Перевёл небольшой обзор основных новшеств в ES2015 (тот который ES6). В обзоре не хватает ES2015 Modules, а это пожалуй самое главное в этом релизе, но можно подробно почитать на сайте Frontender Magazine.
Arrow Functions – стрелочные функции
Синтаксис стрелочных функций короче чем у традиционных. Кроме того, this этих функций содержит контекст “ближайшей” области видимости.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
let foo = ["Hello", "World"]; // Передача одного аргумента не требует круглых или фигурных скобок. // В таких случая и нет необходимости явно указывать return let bar = foo.map(x => x.length); // ES5 var bar = foo.map(function(x) { return x.length; }); // Функции посложнее уже необходимо обернуть в фигурные скобки. // А отсутствие параметров или если их больше одного, в круглые. let foobar = () => { console.log("Hello"); console.log("World"); }; // ES5 var foobar = function() { console.log("Hello"); console.log("World"); }; // Если результатом работы функции является объект, а вы используете укороченный способ написания, // его необходимо дополнительно обернуть в круглые скобки. let quux = () => ({ "myProp" : 123 }); //ES5 var quux = function() { return { "myProp" : 123 }; }; |
Классы
Класс в данном случае – это просто удобный способ описания традиционного прототипного наследования. Синтаксический сахар так сказать.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
class Animal { constructor(type, sound) { this.type = type; this.sound = sound; } makeNoise() { return ('The ' + this.type + ' goes ' + this.sound); } } var simone = new Animal("cat", "meow"); simone.makeNoise(); // Вернёт "The cat goes meow" /** * ES5 version */ function ES5Animal(type, sound) { this.type = type; this.sound = sound; } ES5Animal.prototype.makeNoise = function() { return 'The ' + this.type + ' goes ' + this.sound; } var dogbert = new ES5Animal("dog", "bark"); dogbert.makeNoise(); // Вернёт "The dog goes bark" |
Константы
Константа – способ зафиксировать значение переменной.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function foo(){ const i = 1; var bar = i; // 1 var i = 2; // ошибка } function fooTwo(){ const object = { nestedProperty: 1 }; object = 2; // error object.nestedProperty = 2; // нет ошибок } |
Значения параметров по-умолчанию
Значение по-умолчанию для аргумента функции.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function foo(msg="I am default"){ return msg; } foo(); // I am default /** * ES5 version */ function ES5Foo(msg){ msg = msg || "I am default"; return msg; } foo(); // I am default |
Разложение
Извлечение переменных из массивов или объектов.
1 2 3 4 5 6 |
var foo = [1, 2, 3]; var [one, two, three] = foo; // one => 1, two => 2, three => 3 var {a, b} = {a:1, b:2}; // a => 1, b => 2 |
Генераторы
Генераторы – способ поставить выполнение функции на паузу, и продолжить в дальнейшем. Контекст функции между вызовами сохраняется.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function* count(){ var start = 0; while(true) { yield start; ++start; } } var iterator = count(); iterator.next(); //{value: 0, done: false} iterator.next(); //{value: 1, done: false} iterator.next(); //{value: 2, done: false} iterator.return(); |
let
let прикрепляет переменную к области видимости ближайшего блока {}. Firefox уже долгое время поддерживает эту возможность и теперь она есть в стандартном ES6. Важно: Если let указана вне какого-то блока {}, то она “цепляется” к глобальной области видимости.
1 2 3 4 5 6 |
function foo(){ for(let i = 0; i< 10; i++){ // переменная i доступна } // i is not visible } |
Map
Map – объект вида ключ/значение. И объект и примитив могут быть ключом\значением для Map. Стоит отметить внешнее сходство с традиционными объектами, но Map не имеет ограничений на тип ключа. Кроме того есть возможность получить длину Map. Подробное описание.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var x = {}; var y = 9; var z = "foo"; var m = new Map(); m.set(x, 34); m.set(y, "bar"); m.set(z, {data: "test"}); m.get(x); // 34 m.get(y); // "bar" m.get(z); // {data: "test"} m.size; // 3 |
Set
Set – это коллекция уникальных значений и может быть проитерирована в порядке вставки элементов.
1 2 3 4 5 6 7 8 9 10 11 |
var foo = new Set(); foo.add(1); foo.add(2); foo.add("three"); foo.has(1); // true foo.size; // 3 foo.delete(2); // удалит 2 из коллекции foo |
WeakMap
WeakMap – объект вида ключ/значение, в качестве ключа может быть только объект. Значение могут быть любого типа. В WeakMap ссылка на объект не является причиной для не удаления этого объекта из памяти. Другими словами если на объект ссылается только WeakMap, то сборщик мусора его удалит.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var x = {}; var y = function(){}; var z = "foo"; var w = new WeakMap(); w.set(x, "bar"); w.set(y, 123); w.set(z, "xyz"); // error - key needs to be an object w.get(x); // bar w.get(y); // 123 w.has(x); // true |
WeakSet
WeakSet – коллекция уникальных объектов. В отличии от Set, WeakSet может хранить только объекты. Ссылки на объекты как и в WeakMap не являются “слабыми”, и не помешают сборщику мусора удалить их, если ссылки на этот объект остались только в WeakMap или WeakSet.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var x = {}; var y = function(){}; var ws = new WeakSet(); ws.add(x); ws.add(y); ws.has(x); // true ws.delete(x); ws.clear(); // purge whole weakset |
Промисы
Promises – созданы для удобной работы с отложенными или асинхронными вычислениями.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
var foo = new Promise(function (resolve, reject) { //Check if the current timestamp is an even number and resolve if (Date.now() % 2 === 0) { //Pass a status code of 200 to the success callback function resolve(200); } else { //Pass a status code of 404 to the failure callback function reject(404); } }); // Промис завершит свою работу (перейдёт в состояние fulfilled) и вернёт объект у которого есть метод then. foo.then(function (status) { console.log("Successfully resolved: " + status); }); // Если промис завершит свою работу с ошибкой (перейдёт в состояние rejected) и вернёт объект у которого есть метод catch. foo.catch(function (status) { console.log("An error occurred: " + status); }); |
Прокси
Прокси – специальный объект для которого вы можете переопределить стандартные сеттеры и геттеры. Подробнее.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
let target = { guest: "Welcome, Guest" }; let proxy = new Proxy(target, { get (obj, prop, val) { return val in obj ? obj[val] : 'Howdy, ${val}' }, set (obj, prop, val){ if(prop === 'password'){ if(val.length<8){ throw new TypeError('The length of password should be greater than 8'); } else { obj[prop] = val; } } else { obj[prop] = val; } } }); proxy.guest; // "Welcome, Guest" proxy.userX; // "Howdy, UserX" proxy.password = 'abc'; //Error The length of password should be greater than 8. proxy.age = 22; //age=22 |