Никто не может отрицать, насколько JavaScript стал одним из самых популярных языков программирования, используемых разработчиками по всему миру не только для Интернета, но также для настольных и мобильных приложений благодаря его гибкости, производительности и огромному сообществу, которое за ним стоит.
В этой статье мы постараемся сделать краткий обзор некоторых новых функций ES2018 / ES2019, которые уже одобрены TC39 (для тех, кто не знает, что такое TC39 , технический комитет, который отвечает за развитие JavaScript к ES2018, принимает предложения, и если они будут приняты, они будут добавлены в следующую редакцию).
ES2018
1- Асинхронная итерация:
ES6 представил нам удивительный новый шестой примитивный тип данных, который позволяет нам выполнять итерацию через объекты анонимно, в то время как мы можем перебирать объект через символы.
Давайте посмотрим быстрее:
const iterator = { [Symbol.iterator]: () => { const data = ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i' , 'p', 't'] return { next: () => { if (data.length) { return { value: data.shift(), done: false }; } else { return { done: true }; } } } } } for(const letters of iterator) { console.log(letters); }
Но что, если у нас есть поток данных, который нам нужно обрабатывать асинхронно ?!
И здесь появляется новая функция асинхронной итерации в ES2018, а не фрагмент кода выше, который реализует логику итерации по данным с использованием синхронной итерации с символами.
Некоторые из вас, скорее всего, спрашивают, почему бы просто не вернуть обещание, которое возвращает массив со всем набором данных?
Я мог бы сказать, что у нас есть большой набор данных, который займет немного времени для загрузки каждого элемента, тогда нам нужна поддержка асинхронных последовательностей данных, которые отличаются от потоков ... кому интересно погрузиться в это глубже поговорим вот короткая ссылка:
Есть несколько правил для асинхронного вызова нашего объекта:
1- Нам нужно использовать Symbol.asyncIterator
вместо Symbol.iterator
2- next()
должен вернуть обещание.
3- Чтобы перебрать такой объект, мы должны использовать for...await...of
.
Итак, давайте попробуем:
const data = ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i' , 'p', 't']; // let's suppose we'll get this array asynchronously const iterator = { [Symbol.asyncIterator]: () => { return { next: () => { if (data.length) { return Promise.resolve({ value: data.shift(), done: false }); } else { return Promise.resolve({ done: true }); } } } } }; (async function() { for await (const item of iterator) { console.log(item); } })();
2- Операторы отдыха / спреда:
В ES2015 операторы rest / spread широко использовались разработчиками вместо использования других методов, таких как concat () и slice (), которые позволяют гораздо проще объединять и копировать массивы.
Но ES2018 поставляется с очень удобными инструментами для объектных литералов и деструктурирования объектов.
1- Распространение:
const obj = { a: 1, b: 2 }; const obj1 = { ...obj, c: 3 }; console.log(obj1); // { a: 1, b: 2, c: 3 }
Если мы попробуем это на ES2015, то это выдаст нам ошибку, но с новым ...
в ES2018 для литерала объекта мы можем получить данные из obj и назначьте их obj1.
Обратите внимание, что имена имеют значение при копировании объекта в другой, поэтому, если есть свойства с таким же именем, будет использоваться последнее из них:
const obj = { a: 1, b: 2, c: 3 }; const obj1 = { ...obj, c: 4 }; console.log(obj1); // { a: 1, b: 2, c: 4 }
Также обратите внимание, что порядок имеет значение при копировании объектов:
const obj = { a: 1, b: 2, }; const obj1 = { c: 3, ...obj }; console.log(obj1); // {c: 3, a: 1, b: 2}
2- Отдых:
Деструктуризация массивов - отличный шаблон для извлечения данных из массивов в ES2015, поэтому TC39 сделал это возможным и внутри объектов в ES2018:
const obj = { a: 1, b: 2, c: 3 }; const { a, ...rest } = obj; console.log(a); // 1 console.log(rest); // { b: 2, c: 3 }
Приведенный выше код позволяет скопировать перечислимые свойства в новый объект и скопировать конкретное требуемое свойство, но есть некоторые ограничения, когда rest
свойства всегда должны находиться в конце объекта:
const obj = { a: 1, b: 2, c: 3 }; const { ...rest, a } = obj; console.log(rest); // "SyntaxError: Rest element must be last element
Также нам нужно помнить, что мы можем использовать только один раз оператор отдыха на уровне:
const obj = { a: { b: 1, c: 2, d: 3, }, e: 4, f: 5 }; const { ...rest, ...rest1} = obj; // "SyntaxError: Rest element must be last element const {a: {b, ...rest}, ...rest1} = obj; console.log(b); // 1 console.log(rest); // { c: 2, d: 3} console.log(rest1); // { e: 4, f: 5}
Флаг 3 - точка (.) для регулярного выражения:
Пришло очень полезное обновление для расширения возможностей RegExp. Поскольку раньше мы знали, что \n
не соответствует символу конца строки точка (.) И астральным (не BMP) символам, таким как эмодзи в шаблоне RegExp:
console.log(/^.$/.test('\n')); // false console.log(/^.$/.test('😀')); // false
В то время как ECMAScript распознает терминаторы строки:
- ЛИНИЯ ПОДАЧИ U + 000A (LF) (
\n
) - ВОЗВРАТ ПЕРЕВОЗКИ U + 000D (CR) (
\r
) - СЕПАРАТОР ЛИНИИ U + 2028
- U + 2029 РАЗДЕЛИТЕЛЬ ПАРАГРАФОВ
Таким образом, у разработчиков не могло быть выбора сопоставить точку (.) Только несколькими способами:
console.log(/^[\s\S]$/.test('\n')); // true console.log(/^[\w\W]$/.test('\n')); // true console.log(/^[^]$/.test('\n')); // true
Затем разработчики ECMAScript придумали решение, следующее за другими языками программирования, такими как Perl и PHP, добавив \s
для соответствия символу конца строки:
console.log(/newDotAll./s.test('newDotAll\n')); // true console.log(/^.$/s.test('\n')); // true console.log(/^.$/s.test('\r')); // true console.log(/^.$/s.test('\u{2028}')); // true
4- Promise.prototype.finally ():
Представьте, что вы встретили девушку и попросили ее пойти с вами на свидание, так что у вас будет два результата: либо вы научитесь с ней разговаривать, и она скажет да и ваш запрос будет выполнен, или вам все равно нужно попрактиковаться в том, как вы будете выполнять эту работу, и она отклонит ваш запрос, но во всех случаях этот шаг наконец закончатся получением нового опыта: либо получится, либо не получится.
Вот как работает Promise и так работает новый метод finally:
let date = new Promise((resolve, reject) => { let response = Boolean(Math.round(Math.random())); if(response) { resolve('she will go out with me'); } else { reject('she said no'); } }); date.then((success) => { console.log(success); }).catch((failure) => { console.log(failure); }).finally(()=> { console.log('I took my chance!'); });
В этом примере у нас был случайный ответ, и результат нашего обещания будет зависеть от него, либо он будет истинным, либо ложным, но блок finally будет действовать как очиститель для нашего ожидающего ответа статус и закрыть обещание.
Здравствуйте, ES2019
1-квартира / квартираКарта:
В ES2019 массивы получили еще две дополнительные функции, которые упростили для нас выполнение операций с массивами независимо от их глубины.
Плоский метод в основном берет массив массивов, а затем объединяет их в один массив, давайте посмотрим:
const arr = [1,2,3,4,5, [6,7, [8,9,10]], [11, 12, 13] ];
Раньше мы применяли нормальную функцию примерно так:
const customFlat = (arr) => { return arr.reduce((acc, cur) => { return acc.concat(Array.isArray(cur) ? customFlat(cur) : cur); }, []); }; console.log(customFlat([1,2,3,4,5, [6,7, [8,9,10]], [11, 12, 13] ])); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
На помощь приходит такая квартира!
const arr = [1,2,3,4,5, [6,7, [8,9,10]], [11, 12, 13] ]; const flatArrLev1 = arr.flat(); // [1, 2, 3, 4, 5, 6, 7, [8, 9, 10], 11, 12, 13]
Итак, здесь мы видим, что flat () берет первый вложенный уровень массива, а затем берет его на верхний уровень и принимает один аргумент, который является глубиной, которая указывает, на сколько уровней нужно сгладить. Обратите внимание, что по умолчанию глубина равна 1.
const flatArrLev2 = arr.flat(2); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Итак, мы замечаем, что [6,7] и [11, 12, 13] находились на уровне 1, поэтому они автоматически переходят на верхний уровень, затем во второй операции flatArrLev2 мы сделали это на более глубоком уровне на [8, 9, 10], так что у нас есть новый свежий массив без вложенных значений.
PS: если мы не знаем, насколько глубоки наши вложенные массивы, мы можем использовать Infinity следующим образом:
const flatInfinity = arr.flat(Infinity);
FlatMap - еще одна интересная функция, которая применяет две комбинированные операции к массиву, сначала вызывая map () для каждого элемента массива, а затем flat (), чтобы преобразовать результат в новый массив:
const arr1 = [ [1, 2], [3, 4], [5, 6] ]; console.log(arr1.flatMap(x => x[0]+x[1]));
1- Сопоставьте эти вложенные массивы и выполните вычисления по ним: [1,2]…
Двойное выравнивание
3- Результат: [3, 7, 11]
2- Object.fromEntries ():
За последние годы в Object добавлено множество методов, один полезный был добавлен в ES2019.
Object.fromEntries - это совершенно новый метод, который делает инверсию Object.entries и принимает итерируемый Сопоставьте или подобный карте массив и преобразует список пар "ключ-значение" в новый объект:
Так что давай попробуем;)
Object.fromEntries(new Map([["a", "b"], ["c", "d"]])); // Object { a: "b", c: "d" } Object.fromEntries([["a", "b"], ["c", "d"]]); // Object { a: "b", c: "d" }
PS: он полностью поддерживается не всеми браузерами, поэтому вам необходимо проверить свой движок перед его использованием.
3- trimStart / trimEnd:
Строки также претерпели некоторые изменения в отношении обрезки, но некоторые из вас могут сказать, что у нас уже есть trimLeft () и trimRight (), я бы сказал, что эти функции меняют только имена и сохраняет тот же эффект, потому что он более близок к человеческому языку, и мы все еще можем использовать старые trimLeft () и trimRight () в качестве псевдонимов.
let name = " Hamza Amdouni ";
console.log(name
.trimStart()); // "Hamza
Amdouni
" console.log(name
.trimEnd()); // "Hamza
Amdouni
"console.log(name.trimStart() === name.trimLeft()); // true
4- Symbol.prototype.description:
Описание символа было немного утомительным, в то время как у нас был только один способ - преобразовать его в строку:
const symbol = Symbol('new Symbol'); console.log(String(symbol) === 'Symbol(new Symbol)'); // true
Благодаря Майклу Фикарре с его новым предложением он дал нам простой способ доступа к дескриптору символа:
const symbol = Symbol('new Symbol'); console.log(symbol.description === 'new Symbol'); // true
Заключение
В конце концов, я просто хотел поделиться тем, что я узнал из ES2018 / ES2019, и любые предложения, комментарии принимаются, пока я с нетерпением жду ваших аплодисментов;)