ES2017 или ES8 - это последняя спецификация ECMAScript, выпущенная в июне прошлого года. В ES2016 / ES7 очень мало серьезных изменений по сравнению с ES2015 / ES6 (обещания, функции стрелок и другие элементы современного языка). Но в ES2017 добавлено несколько интересных функций. Вы можете прочитать полную спецификацию ES2017 здесь. Но я не думаю, что вам захочется читать 885-страничную спецификацию, поэтому давайте углубимся в основные изменения в ES2017, а также рассмотрим предложения ES2018.
Основные изменения:
1. Асинхронные функции
2. Общая память и атомики
Незначительные изменения:
3. Object.values () и Object.entries ()
4. Object.getOwnPropertyDescriptors ()
5. Заполнение строк
6. Конечные запятые в списках параметров функций и вызовах
По моему мнению, самая захватывающая особенность ES2017 - это асинхронные функции (async / await), поскольку они позволяют писать более чистый код с меньшим количеством строк при работе с обещаниями. Он обеспечивает простой и элегантный способ обработки асинхронных операций.
1. Асинхронные функции
Асинхронные функции (или async / await) - это оболочки поверх обещаний. Мотивом этого является упрощение обработки асинхронного кода. Теперь вы можете определять асинхронные функции, которые могут иметь или не иметь какие-либо блокирующие операции (обещанные асинхронные), используя ключевое слово await.
function getVolume(length, breadth, height) { return new Promise(resolve => { setTimeout(() => { resolve(length * breadth * height); }, 3000); }); } async function printVolume(length, breadth, height) { console.log(1); const text = await getVolume(length, breadth, height); console.log(`Volume: ${text}`); console.log(2); } console.log(printVolume(5, 4, 3));
Это напечатает следующие значения
1 Volume: 60 // will be printed after 3-second delay 2
Теперь, если мы выполним следующее вместо
console.log (printVolume (5, 4, 3)); в приведенном выше коде мы получим другой результат:
console.log(3); console.log(printVolume(5, 4, 3)); console.log(4);
Это напечатает следующие значения
3 1 4 Volume: 60 // will be printed after 3-second delay 2
Это потому, что вызов функции не блокирует выполнение основного потока.
Небольшое глубокое погружение - давайте посмотрим, как работает async путем компиляции функции async с использованием babel - вы можете игнорировать следующие несколько строк, если вас устраивает простой синтаксис, но я думаю, что важно понимать, как это работает, поскольку это даст вам лучший контекст при использовании их.
var printVolume = (function() { var _ref = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee( length, breadth, height ) { var text; return regeneratorRuntime.wrap( function _callee$(_context) { while (1) { switch ((_context.prev = _context.next)) { case 0: console.log(1); _context.next = 3; return getVolume(length, breadth, height); case 3: text = _context.sent; console.log("Volume: " + text); console.log(2); case 6: case "end": return _context.stop(); } } }, _callee, this ); }) ); return function printVolume(_x, _x2, _x3) { return _ref.apply(this, arguments); }; })(); function _asyncToGenerator(fn) { return function() { var gen = fn.apply(this, arguments); return new Promise(function(resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then( function(value) { step("next", value); }, function(err) { step("throw", err); } ); } } return step("next"); }); }; }
Под капотами асинхронные функции транслируются в генератор функций, который возвращает обещания. Итак, по сути, асинхронная функция - это функция-конструктор, которая возвращает этот генератор функций и вызывает его, чтобы получить обещание, которое мы можем обработать, когда оно будет разрешено.
2. Общая память и атомики
ES2017 представил конструктор SharedArrayBuffer и глобальный объект Atomics с их вспомогательными функциями.
Javascript работает в одном потоке, но вы можете выполнять задачи асинхронно. Движок JS запускает эти задачи в отдельных потоках, а затем передает их результат обратно в основной поток с помощью обратных вызовов, или вы можете использовать веб-рабочих, которые являются тяжелыми процессами со своей собственной глобальной средой, и по умолчанию ничего не разделяется, а затем SIMD (одна инструкция, несколько данных) была введен для низкоуровневого параллелизма данных.
SharedArrayBuffer и Atomics представлены для достижения высокоуровневого параллелизма. Объект SharedArrayBuffer совместно используется несколькими рабочими процессами и основным потоком, поэтому вы можете быстро и легко обмениваться данными, а координация между общими данными проста.
// main.js const worker = new Worker(‘worker.js’); const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 100); // 100 primes shared memory worker.postMessage({sharedBuffer}); // worker.js self.addEventListener(‘message’, function (event) { const {sharedBuffer} = event.data; const ia = new Int32Array(sharedBuffer); });
Теперь вы можете использовать один и тот же разделяемый объект в любом количестве рабочих, которые хотите, и вы можете управлять буфером разделяемой памяти следующим образом.
// main.js const worker = new Worker(‘worker.js’); const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 100000); // 100000 primes const ia = new Int32Array(sab); // ia.length == 100000 const primes = new PrimeGenerator(); for ( let i=0 ; i < ia.length ; i++ ) ia[i] = primes.next(); worker.postMessage(ia); // worker.js let ia; self.addEventListener(‘message’, function (event) { ia = event.data; // ia.length == 100000 console.log(ia[30]); // prints 100, the 31st prime ia[30] = 200; // update the data }
Он обновит общий буфер, но трудно сказать, сколько времени потребуется, чтобы запись появилась от одного рабочего к другому (это зависит от системы).
Таким образом, для достижения синхронизации используются атомарные операции. Новый глобальный объект Atomics предоставляет несколько атомарных операций в виде статических методов. Атомика используется для синхронизации (метод загрузки и сохранения), ожидания (метод ожидания и пробуждения) и других арифметических атомарных операций (добавление, подметоды). Операции Atomics (загрузка, сохранение и другие) обеспечивают безопасное чтение и запись.
Подробнее на https://github.com/tc39/ecmascript_sharedmem/blob/master/TUTORIAL.md
3. Object.values () и Object.entries ()
В JS вы можете получить доступ к свойствам объекта с помощью Property Accessors (obj [prop '], obj.prop), поэтому вам необходимо иметь предварительный знание ключа. Вы можете использовать Object.keys (obj), чтобы получить все ключи obj в виде массива, но его беспокойные операции при выполнении сложных операций. В ES2017 появились два новых метода - Object.values () и Object.entries ().
Object.values (obj) - возвращает массив значений.
Object.entries (obj) - возвращает массив пар [ключ, значение].
Object.keys (obj) - возвращает массив ключи.
const user = { name: "Ridham", id: 12, post: "SE" }; console.log(Object.values(user)); // ["Ridham", 12, "SE"] console.log(Object.entries(user)); // [["name", "Ridham"], ["id", 12], ["post", "SE"]] console.log(Object.keys(user)); // ["name", "id", "post"]
4. Object.getOwnPropertyDescriptors ()
Метод getOwnPropertyDescriptors возвращает все собственные дескрипторы свойств (перечисляемые или нет) указанного объекта. Он не включает свойства, унаследованные от прототипа объекта.
Он в основном используется для создания неглубокого клона или копирования свойств в другой объект. перед этим используется Object.assign (), но он не копирует свойства с атрибутами, отличными от значений по умолчанию.
Вы можете использовать Object.defineProperties () с getOwnPropertyDescriptor () для копирования свойств
const source = { set log(data) { console.log(data); } }; // clone object const clone = Object.create( Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj) ); // copy properties const target = {}; Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); console.log(Object.getOwnPropertyDescriptor(target, 'log'));
5. Заполнение строк
ES2017 представил методы padEnd () и padStart () для применения отступов к строке. Перед этим мы должны написать код полифиллов, чтобы добиться этого.
console.log(‘1.00’.padStart(15)) console.log(‘40,000.00’.padStart(15)) console.log(‘199,500.00’.padStart(15)) 1.00 40,000.00 199,500.00 console.log(‘1.00’.padEnd(15, ‘*’)) console.log(‘40,000.00’.padEnd(15, ‘*’)) console.log(‘199,500.00’.padEnd(15, ‘*’)) 1.00*********** 40,000.00****** 199,500.00*****
6. Конечные запятые в списках параметров функций и вызовах
из ES2017 конечная запятая в параметре функций (es2017 (1, 3,);) не вызывает SyntaxError. Аналогично завершению запятых в литералах объектов ({x: 1,}) и литералах массива [1, 3,]
Предложения ES2018
Готовые предложения
Снятие ограничения литералов шаблона:
- В настоящее время вы не можете использовать escape-символы Unicode (\ u, \ 0100, \ xFF) в литералах шаблона. Это вызывает SyntaxError. Итак, предложение состоит в том, чтобы снять ограничение на escape-последовательности.
Флаг s (dotAll) для регулярных выражений:
- в шаблонах регулярных выражений точка. соответствует одному символу, независимо от того, что это за символ.
В ECMAScript есть два исключения:
. не соответствует астральным персонажам. Это исправляет установка флага u (Unicode).
. не соответствует символам конца строки.
/foo.bar/.test(‘foo\nbar’); // → false
Поэтому предлагается добавить новый флаг s для регулярных выражений ECMAScript, которые создают. соответствует любому символу, включая терминаторы строки.
На ранней стадии (3,2 и 1) все еще есть много интересных предложений, таких как пересмотр toString (стадия - 3), Асинхронная итерация (стадия 3), Rest / Spread Properties (стадия 3), Promise.prototype.finally (стадия 3), BigInt (stage-3), поля публичных экземпляров класса и поля частных экземпляров (stage-3), String.prototype. {TrimStart, trimEnd} (stage-2), Atomics.waitAsync (stage-2) и многие другие .
Ознакомиться со всеми предложениями можно здесь.
Если вам понравилась эта статья, дайте мне много аплодисментов - для писателя это мир. Следуйте за мной, если вы хотите прочитать больше статей о JS, технологиях и стартапах.