Javascript – один из самых важных навыков работы с интерфейсом, от ES6 до ES13, могут быть функции, о которых вы не знаете

ES6 (ES2015)

Класс

JavaScript — это язык, использующий цепочку прототипов.
В первые дни такие концепции, как объектно-ориентированные, создавались с помощью цепочки прототипов, что было довольно сложно. Класс, наконец, представлен в ES6.

class Animal {
   constructor(name, color) {
     this.name = name;
     this.color = color;
   }
   // This is a property on the prototype chain
   toString() {
     console.log('name:' + this.name + ', color:' + this.color);

   }
 }

var animal = new Animal('myDog', 'yellow');
animal.toString(); 

console.log(animal.hasOwnProperty('name')); //true
console.log(animal.hasOwnProperty('toString')); // false
console.log(animal.__proto__.hasOwnProperty('toString')); // true

class Cat extends Animal {
 constructor(action) {
   super('cat','white');
   this.action = action;
 }
 toString() {
   console.log(super.toString());
 }
}

var cat = new Cat('catch')
cat.toString();

console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true

модуль

Каждый модуль имеет собственное пространство имен, чтобы избежать конфликтов, используя импорт и экспорт для импорта и экспорта. В основном рассматривайте файлы .js как модули.

Функция стрелки

() =› {…}, сокращение от function. Самое главное, он может убедиться, что это всегда направлено на него самого,

Больше не нужно писать var self = this, var that = this и т. д.!

const add = (a, b) => { return a + b};
const res = add(1, 2); // 3
const minus = (a, b) => a - b;
const res1 = minus(5, 1); // 4

Значения функциональных параметров по умолчанию

Если функция не передает параметры, используется значение по умолчанию, что является более кратким.

function example(height = 5, width = 6) { 
     const newH = height * 2;
     const newW = width * 4;
     return newH + newW;
}

example(); // 34 (5*2 + 6*4)

литерал шаблона

Раньше комбинации длинных строк объединялись с помощью знака +. Это плохо читается, со строками-шаблонами читать намного проще.

const firstName = 'water';
const lastName = 'fish';
// not use template literal
const name = 'Hello, My name is' + firstName + ', ' + lastName;
// use template literal
const nameWithLiteralString = `Hello, My name is ${firstName}, ${lastName}`;

деструктурирование присваивания

const arr = [1, 2, 3, 4, 5];
const [one, two, three] = arr;
console.log(one); // 1
console.log(two); // 2
...

// To skip certain values
const [first,,,,last] = arr;
console.log(first); // 1
console.log(last); // 5

// Objects can also be destructurized and assigned
const student = { 
    name: 'waterfish', 
    age: 28,
};
const {name, age, city} = student;
console.log(name); // "waterfish"
console.log(age); // "28"

оператор расширения

const arr1= ['A', 'B'];
const arr2= ['0', ...arr1, '1', '2'];
conslog.log(arr2); // ["0", "A", "B", "1", "2"]

Он представлен тремя точками (…), массив может быть расширен, если это объект, он будет расширен в соответствии с ключом-значением.

Сокращение свойства объекта

Это значение можно опустить, если имена полей, из которых состоит объект, совпадают с именами переменных в предыдущих абзацах.

const name = 'waterfish', age = 28;

// Before ES6, we must write like this
const customer = {
    name: name,
    age: age,
} // // {name: 'waterfish', age: 28}

// After ES6, we can do it
const newCustomer = {
    name,
    age,
} // // {name: 'waterfish', age: 28}

Обещание

Promise — это решение для асинхронной (асинхронной) записи, которое более элегантно, чем исходное написание обратного вызова. Использование Promise может решить адский обратный вызов.

const waitSecond = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000);
});
waitSecond.then( () => {
    console.log('hello after 1 second.'); 
    // output this line after 1 second
    return waitSecond;
}).then( () => {
    console.log('World after 2 sceond.');
    // output this line after 2second
})

ES8 (ES2017) выпустил более совершенный асинхронный код await, который напрямую делает асинхронную запись похожей на синхронную.

Недостаток в том, что когда идея ложится на сложную бизнес-логику, иногда пропускается await и обнаруживаются ошибки во время выполнения.

let, const заменяет var

let: общая переменная, которую можно переопределить.

const: после объявления его содержимое нельзя изменить. Поскольку массивы и объекты являются указателями, их содержимое можно увеличивать или уменьшать без изменения указателей.

В первые дни область видимости var в JavaScript была глобальной.

То есть переменная объявляется после использования, и она будет автоматически поднята на верхний уровень во время выполнения, и будет назначена позже. Более подвержена загрязнению.

ES7 (ES2016)

Array.prototype.includes()

Он используется для определения того, содержит ли массив заданное значение, и если да, то возвращает true; в противном случае возвращает ложь.

Как и предыдущее использование indexOf, его можно рассматривать как возвращающее логическое значение, что более понятно с семантической точки зрения.

const arr = [1, 2, 3, 4, 5];
arr.include(3); // true

if (arr.include(3)) { ... }
// ... Equivalent to the previous writing of indexOf
arr.indexOf(3); // 2 (return its array position)
// If you want to write it in the if, you must add `> -1`, which is not as clear as the include in ES7 in terms of semantics
if (arr.indexOf(3) > -1) { ... }

оператор возведения в степень

console.log(2**10); // 1024
// equal to
console.log(Math.pow(2, 10)); // 1024

ES8 (ES2017)

асинхронно, ждите

Асинхронная функция — это функция, объявленная с ключевым словом async, в которой разрешено использовать ключевое слово await. Ключевые слова async и await позволяют более лаконично описать асинхронное поведение на основе промисов, избегая необходимости явно настраивать цепочки промисов.

async test() {
    try {
        const result = await otherAsyncFunction();
        console.log(result); // output result
    } catch(e) {
        console.log(e); // Can catch errors if otherAsyncFunction() throws an error
    }
}

Object.values()

Возвращает все значения собственных свойств объекта, исключая унаследованные значения.

const exampleObj = {a: 1, b: 2, c: 3, d:4};
console.log(Object.value(exampleObj)); // [1, 2, 3, 4];

// To do the same thing before, use the following notation. much verbose
const values = Object.keys(exampleObj).map(key => exampleObj[key]);

Object.entries()

Возвращает перечисляемый ключ, значение, переданное в самом объекте.

const Obj = {a: 1, b: 2, c: 3, d:4};
console.log(Object.entries(Obj)); // [["a", 1], ["b", 2], ["c", 3], ["d", 4]];

// Usually used with for
for (const [key, value] of Object.entries(Obj)) {
  console.log(`key: ${key}, value: ${value}`);
}
// key: a, value: 1
// key: b, value: 2
// key: c, value: 3
// key: d, value: 4

padStart() и padEnd()

Вы можете добавить дополнительное содержимое в начало или конец строки и дополнить его до указанной длины.

В прошлом эти функции часто добавлялись через общие вспомогательные инструменты, такие как lodash, и объединялись.

String.padStart(fillingLength, FillingContent);
// If the content to be filled is too much and exceeds the "fill length", 
// it will be filled from the leftmost to the upper limit of the length, 
// and the excess will be truncated

Наиболее часто используемая ситуация должна быть суммой, заполнить указанную длину и добавить 0, если ее недостаточно.

// padStart
'100'.padStart(5, 0); // 00100
// If the content to be padded exceeds the "padding length". Then fill in from the left to the upper limit of the length
'100'.padStart(5, '987'); // 98100

// padEnd
'100'.padEnd(5, 9); // 10099
// If the content to be padded exceeds the "padding length". Then fill in from the right to the upper limit of the length
'100'.padEnd(5, '987'); // 10098

запятая в конце

ECMAScript 2017 поддерживает запятые в конце параметров функции.

function f(p) {}
function f(p,) {}

(p) => {};
(p,) => {};

Object.getOwnPropertyDescriptors()

Получите свои собственные дескрипторы, которые обычно не используются общими бизнес-требованиями разработки.

const exampleObj = {a: 1, b: 2, c: 3, d:4};
Object.getOwnPropertyDescriptors(exampleObj);
// {a: {…}, b: {…}, c: {…}, d: {…}}
// a: {value: 1, writable: true, enumerable: true, configurable: true}
// b: {value: 2, writable: true, enumerable: true, configurable: true}
// c: {value: 3, writable: true, enumerable: true, configurable: true}
// d: {value: 4, writable: true, enumerable: true, configurable: true}
// __proto__: Object

общий буфер массива

SharedArrayBuffer — это буфер фиксированной длины необработанных двоичных данных, аналогичный ArrayBuffer.

Может использоваться для создания данных в общей памяти. В отличие от ArrayBuffer, SharedArrayBuffer нельзя отсоединить.

Объект Atomics

Объект Atomics, предоставляющий набор статических методов для выполнения атомарных операций с SharedArrayBuffer.

Все свойства и функции атомов статичны, как и математика, новой нет.

Если многопоточность считывает и записывает данные в одно и то же место в одно и то же время, атомарная операция гарантирует, что обрабатываемые данные соответствуют ожиданиям: то есть следующая подоперация выполняется после завершения предыдущей подоперации, и работа не прерывается.

Можно сказать, что это функция, улучшенная для разработки многопоточного сервера в Node.Js, и вероятность ее использования во фронтенд-разработке довольно мала. хром уже обеспечивает поддержку.

ES9 (ES2018)

цикл ожидания

В асинхронной функции иногда необходимо использовать асинхронную (несинхронную) функцию внутри синхронного цикла for.

Сам цикл for по-прежнему является синхронным, и весь цикл for будет выполняться до завершения асинхронной функции в цикле, а затем асинхронные функции внутри будут выполняться одна за другой. В ES9 добавлены асинхронные итераторы, позволяющие использовать await с циклы для выполнения асинхронных операций.

async function process(array) {
  for await (const i of array) {
    doSomething(i);
  }
}

обещание.finally()

Будь то успех (.then()) или неудача (.catch()), часть, которая будет выполнена после промиса.

function process() {
  process1()
  .then(process2)
  .then(process3)
  .catch(err => {
    console.log(err);
  })
  .finally(() => {
    console.log(`it must execut no matter success or fail`);
  });
}

Отдых и распространение

const myObject = {
  a: 1,
  b: 2,
  c: 3
};
const { a, ...r } = myObject;
// a = 1
// r = { b: 2, c: 3 }

// Can also be used in function input parameters
function restObjectInParam({ a, ...r }) {
    console.log(a); // 1
    console.log(r); // {b: 2, c: 3}
}

restObjectInParam({
  a: 1,
  b: 2,
  c: 3
});

ES10 (ES2019)

Array.prototype.flat() и Array.prototype.flatMap()

const arr1 = [1, 2, [3, 4]];
arr1.flat(); // [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat(); // [1, 2, 3, 4, [5, 6]]
// Pass in a number in flat, representing the flattening depth
arr2.flat(2); // [1, 2, 3, 4, 5, 6]

let arr = ["water", "", "fish"]

arr.map(s => s.split(""))
// [["w", "a", "t", "e", "r"], [""], ["f", "i", "s", "h"]

arr.flatMap(s => s.split(''));
// ["w", "a","t","e","r", "", "f", "i", "s", "h"]

String.prototype.trimStart() и String.prototype.trimEnd()

Метод trimStart() удаляет пробелы в начале строки, а trimLeft() является псевдонимом для этого метода.

const greeting = ' Hello world! ';
console.log(greeting);
// expected output: " Hello world! ";
console.log(greeting.trimStart());
// expected output: "Hello world! ";

Метод trimEnd() удаляет пробелы в конце строки, а trimRight() является псевдонимом для этого метода.

const greeting = '   Hello world!   ';
console.log(greeting);
// expected output: "   Hello world!   ";
console.log(greeting.trimEnd());
// expected output: "   Hello world!";

Объект.fromEntries()

Преобразование списка пар ключ-значение в объект.

const entries = new Map([
  ['foo', 'bar'],
  ['baz', 42]
]);
const obj = Object.fromEntries(entries);
console.log(obj);
// expected output: Object { foo: "bar", baz: 42 }

String.prototype.matchAll

Метод matchAll() возвращает итератор по всем результатам сопоставления строки с регулярным выражением, включая захваченные группы.

const regexp = /t(e)(st(\d?))/g;
const str = 'test1test2';
const array = [...str.matchAll(regexp)];
console.log(array[0]);
// expected output: Array ["test1", "e", "st1", "1"]
console.log(array[1]);
// expected output: Array ["test2", "e", "st2", "2"]

Большое число

const theBiggestInt = 9007199254740991n;

const alsoHuge = BigInt(9007199254740991);
// ↪ 9007199254740991n

const hugeString = BigInt("9007199254740991");
// ↪ 9007199254740991n

const hugeHex = BigInt("0x1fffffffffffff");
// ↪ 9007199254740991n

const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111");
// ↪ 9007199254740991n

ES11 (ES2020)

Обещание.allSettled()

Метод Promise.allSettled() возвращает обещание, которое выполняется, когда все заданные обещания были выполнены или отклонены, с массивом объектов, каждый из которых описывает результат каждого обещания.

Обычно он используется, когда у вас есть несколько асинхронных задач, которые не зависят от успешного завершения друг друга, или когда вы всегда хотите знать результат каждого промиса.

Напротив, Promises, возвращаемые Promise.all(), могут быть более подходящими, если задачи зависят друг от друга или если вы хотите, чтобы какая-либо из них была немедленно отклонена.

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
Promise.allSettled(promises).
  then((results) => results.forEach((result) => console.log(result.status)));
// expected output:
// "fulfilled"
// "rejected"

Необязательно?

const username = user?.name || 'guest';

Нулевой оператор объединения ??

В JavaScript, когда встречается 0, null или undefuded, он автоматически превращается в false. Но иногда 0 на самом деле является нормальным значением и может допускать только undefined и null.

const username = user.level ?? 'no level'; 
// output 0. if level is not available, it becomes 'no level'.

Динамический импорт

el.onclick = () => {
    import(`/js/logger.js`)
    .then((module) => {
        module.doSomthing();
    })
    .catch((err) => {
        handleError(err);
    })
}

GlobalThis

Глобальное свойство globalThis содержит глобальное значение this, аналогичное глобальному объекту.

function canMakeHTTPRequest() {
  return typeof globalThis.XMLHttpRequest === 'function';
}
console.log(canMakeHTTPRequest());
// expected output (in a browser): true

ES12 (ES2021)

Обещание.любое()

Promise.any() принимает итерацию объектов Promise. Он возвращает один промис, и всякий раз, когда выполняется любое из промисов в итерируемом объекте, возвращается промис со значением выполненного промиса.

Если в реализации итерируемого объекта нет обещаний (если все заданные обещания отклонены), возвращенное обещание отклоняется с помощью AggregateError, нового подкласса Error, который группирует отдельные ошибки.

const p1 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('p1 resolved value')
  }, 1000)
})
const p2 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('p2 resolved value')
  }, 500)
})
const p3 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('p3 resolved value')
  }, 1800)
})
Promise.any([p1, p2, p3]).then(value=>{
  console.log(value)
}) // p2 resolved value

оператор логического присваивания

Во время разработки мы можем использовать логические операторы ||, && и ?? (нулевой оператор объединения), предложенный в ES2020 для решения некоторых проблем.

И ES2021 предложит ||= , &&= , ??= , концепция аналогична += :

let b = 2
b += 1 
// equal to b = b + 1
let a = null
a ||= 'some random text'  // a become to'some random text'
// equal a = a || 'some random text'
let c = 'some random texts'
c &&= null  // c become to null
// equal to c = c && null
let d = null
d ??= false  // d become to false
// equal to d = d ?? false

Слабая ссылка

Объект WeakRef содержит слабую ссылку на объект, известный как его цель или референт. Слабая ссылка на объект — это ссылка, которая не предотвращает удаление объекта сборщиком мусора.

Напротив, нормальные (или сильные) ссылки удерживают объекты в памяти, и когда у объекта больше нет сильных ссылок, сборщик мусора движка JavaScript может уничтожить объект и освободить его память.

Если это произойдет, вы больше не сможете получить объект по слабой ссылке.

ES13 (ES2022)

Что удивительного произойдет….?