Обзор ECMAScript 6 простыми словами

Вот Обзор ECMAScript 6 простым языком.
И позвольте мне упомянуть, что на этот обзор сильно повлияло es6features repo, спасибо Люку Хобану за такую ​​отличную работу. И Аксель Раушмайер за его потрясающую исчерпывающую книгу.

Сначала, когда я сам услышал о ES6, мне было трудно переварить его и изучить его основы. Я прошел этот путь, но вам это необязательно!
Итак, вот краткое введение в ES6 и его новые функции, все объясняется простым языком для таких чайников, как я 😄

Вступление

ECMAScript 6, также известный как ECMAScript 2015, является следующей версией Javascript и стал стандартом в июне 2015 года.
ES6 является значительным обновлением языка по сравнению с ES5 в 2009 году.

Это новый язык?
Нет! Это тот же старый Javascript, который мы знаем, но с более красивым синтаксисом и большим количеством функций.

Означает ли это, что мои текущие коды Javascript скоро не заработают?
Нет! Это сломало бы сеть! Javascript всегда имеет обратную совместимость. то есть к нему будут добавлены новые функции, а существующие функции станут более мощными. Это называется One JavaScript.

Какова его цель?
Как правило, лучше сделать язык! Это позволяет нам кодировать быстрее, безопаснее и эффективнее.

Что будет после ES6?
ECMAScript 7 и так далее… TC39 планирует выпускать новую версию ECMAScript каждый год. то есть с этого момента версии ECMAScript будут относительно небольшими обновлениями. Так что все, что вы узнаете о ES6 сегодня, будет полезно, когда вы захотите начать изучать ES7 и более поздние версии.

Установка

Этот раздел предназначен для тех веб-дизайнеров, которые еще не так хорошо знакомы с инструментами командной строки. Так что, если вы уже знаете, как установить node.js и Babeljs, компилятор ES6, вы можете пропустить этот раздел.

Мне нужно что-то установить?
Да! Поскольку ES6 является новым, большинство его функций пока не поддерживаются в браузерах. Но ждать не надо! Мы можем начать кодирование на ES6 сегодня с помощью node.js и Babeljs, компилятора ES6!
Babeljs преобразует наш синтаксис ES6 в ES5, чтобы текущие браузеры могли читать наш код как если мы написали все это на ES5 с самого начала. Разве это не круто? Да, это так! Итак, давайте просто посмотрим, как все это установить, и приступим к работе.

  1. Сначала загрузите и установите node.js на свой компьютер.
  2. Теперь откройте терминал / командную строку и введите: npm install --global babel.
    Нажмите Enter на клавиатуре, чтобы запустить команду и установить Babeljs в самый первый раз на вашем компьютере.
    Babeljs компилятор ES6.
  3. Выполните: npm install -g browserify.
    Чтобы установить Browserify, если вы хотите использовать синтаксис загрузчика модуля ES6.
    Browserify позволяет писать модульные коды JavaScript в отдельных файлах Javascript, а затем объединять их все и заполните свою html-страницу только одним связанным файлом Javascript.
  4. Запустите: cd path/to/my/project, чтобы перейти из каталога в каталог вашего проекта.
  5. Бег: babel src --out-dir build. Эта команда преобразует любые файлы .js в папке 'src' из синтаксиса ES6 в ES5 и помещает новые преобразованные файлы в папку 'build'.
    Теперь все готово! Вы можете кормить html новыми преобразованными файлами .js, и браузер, как всегда, должен запускать ваши коды

Возможности ECMAScript 6

строка + массив + объектные API

В ES6 мы добавили много новых библиотек, включая основные математические библиотеки, помощники по преобразованию массивов и Object.assign() для копирования.

'hello'.startsWith('hell'); // true
'hello'.endsWith('ello'); // true
'hello'.includes('ell'); // true
'doo '.repeat(3); // 'doo doo doo '
Array.from(document.querySelectorAll("*")); // Returns a real Array
Array.of(1, 2, 3); // Similar to new Array(...), but without special one-arg behavior
[0, 0, 0].fill(7, 1); // [0,7,7]
[1, 2, 3].findIndex(x => x == 2); // 1
['a', 'b', 'c'].entries(); // iterator [0, 'a'], [1,'b'], [2,'c']
['a', 'b', 'c'].keys(); // iterator 0, 1, 2
['a', 'b', 'c'].values(); // iterator 'a', 'b', 'c'
Object.assign(Point, { origin: new Point(0,0) }); // Assigns new parameters for 'Point' object.

Символы

Символ - это новый примитивный тип в ECMAScript 6. Это токены, которые служат уникальными идентификаторами. Вы создаете символы с помощью фабричной функции Symbol(). Они всегда уникальны. Каждый раз, когда мы создаем новый символ, мы фактически создаем новый уникальный идентификатор, который никогда не конфликтует ни с чем другим в нашем проекте. Вот почему это делает их полезными в некоторых случаях. Например, когда мы хотим определить константу!

В ES5 мы использовали две разные уникальные строки для определения констант ... Нам нужно полагаться на строку! Но, как мы знаем, String не является чем-то уникальным! Мы можем случайно изменить их или напечатать в разных местах, и это нарушит наше постоянное поведение. Но теперь мы можем легко использовать Symbol() при определении наших постоянных переменных, и мы уверены, что каждый раз, когда мы вызываем Symbol(), это уникальный идентификатор в нашем проекте, который никогда не конфликтует. Прохладный!

const COLOR_RED    = Symbol();
const COLOR_ORANGE = Symbol();
console.log( 'each Symbol() is always unique: ', Symbol() === Symbol() ); // Yes, it returns false.
// They can also help us create unique dynamic methods for our objects and classes.
const MY_KEY = Symbol();
let obj0 = {};
obj0[MY_KEY] = 123;
console.log('my dynamic object method: ', obj0[MY_KEY]); // 123

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

Литералы шаблонов предоставляют синтаксический сахар для построения строк. Сам литерал разделяется обратными кавычками, интерполированные выражения внутри литерала ограничиваются ${var}. Литералы шаблонов всегда создают строки.

// Multiline strings
const HTML5_SKELETON = `
  <!doctype html>
  <html>
  <head>
    <meta charset="UTF-8">
    <title></title>
  </head>
  <body>
  </body>
  </html>`;
// Interpolate variable bindings
let name = 'Bob', time = 'today';
let greeting = `Hello ${name}, how are you ${time}?`;
// Tagged templates
let str = String.raw`This is a text
with multiple lines.
Escapes are not interpreted,
\n is not a newline.`;

Пусть + Const

ES6 предоставляет два новых способа объявления переменных: let и const, которые в основном заменяют способ объявления переменных var в ES5. let работает аналогично var, но объявляемая переменная является блочной, она существует только в текущем блоке. var имеет функциональную область видимости.

function func(randomize) {
  if (randomize) {
    let x = Math.random(); // NOTE: x exists ONLY in this if statement
    var y = Math.random(); // NOTE: But y exists in the whole function.
  }
  // Block scoping means that we can shadow variables within a function
  // which means the x variable here has nothing to do with the above one that
  // we've defined inside of the if statement.
  let x = 5;
  return y;
}

const работает аналогично let, но объявленная вами переменная должна быть немедленно инициализирована со значением, которое не может быть изменено впоследствии.

const a = 123;

ПРИМЕЧАНИЕ: const ошибка! const означает только то, что сама переменная неизменна. Итак, если переменная является объектом, свойства этого объекта все еще изменяются! Решением этой проблемы является метод Javascript freeze().

const freezObj = Object.freeze({});

Деструктуризация

Деструктуризация позволяет связывать с использованием сопоставления с образцом с поддержкой сопоставления массивов и объектов.
На самом деле деструктуризация - это удобный способ извлечения значений из данных, хранящихся в (возможно, вложенных) объектах и ​​массивах.

// Let's understand destructuring better...
let obj1 = {}; obj1.first = 'Jane'; obj1.last = 'Doe'; // This is how we can construct data
let f1 = obj1.first; let l1 = obj1.last; // And this is how we can extract data out of it. right?
// Now for constructing we could also use object literal:
let obj2 = { first: 'Jane', last: 'Doe' };
// destructuring is also similar to it! it's just the opposite of
// constructing. It lets us to extract data easier.
let { first: f2, last: l2 } = obj2; // Now we have f2 and l2 variables available.
// Destructing works with arrays too
let [x1, y1] = ['a', 'b']; // x1 = 'a'; y1 = 'b'
// Computed property keys
const FOO = 'foo';
let { [FOO]: f4 } = { foo: 123 }; // f4 = 123

Мы также можем использовать шаблон для нашего уничтожения.
ПРИМЕЧАНИЕ. Важно отметить, что при уничтожении нам просто нужно указать переменную, которую мы хотим извлечь из массива или объекта. . Вот и все! например В следующем примере нам просто нужно извлечь «foo» из «obj3» и сохранить его как переменную «f3». Итак, мы просто создаем шаблон для доступа к «foo» в объекте и упоминаем только это, потому что это все, что нам нужно.

let obj3 = { a: [{ foo: 123, bar: 'abc' }, {}], b: true };
let { a: [{foo: f3}] } = obj3; // f3 = 123

У нас также могут быть значения по умолчанию:

let [x3 = 3, y3] = []; // x3 = 3; y3 = undefined
let {foo: x4 = 3, bar: y4} = {}; // x4 = 3; y4 = undefined
// Of course default values can be functions too:
function log() { return 'YES' }
let [aa=log()] = [];
// Default values can refer to other variables in the pattern.
// However order of them matters! The following produces referenceError:
// let [x=y, y=3] = [];
// Why? because y is not defined yet when x says that my default value is y!
let [xx=3, yy=xx] = [];

Его также можно использовать в for-of.
ПРИМЕЧАНИЕ. В ES6 у нас есть новый вид цикла, который называется for-of. До ES5, когда нам нравилось перебирать массив, который мы просто использовали, в массиве ES5 был метод forEach(), который позволяет нам это делать. Теперь у нас есть for-of, который проще в использовании.

// a for-of example and a loop through the array
let arr = ['a', 'b', 'c'];
for ( let item of arr ) {
  //console.log(item);
}
// Via the new Array method entries() and destructuring, we can get both index
// and value of each array element.
for ( let [index, item] of arr.entries() ) {
  //console.log(index + '. ' + item);
}
// We can also do it like this too
for ( {name: n, age: a} of arr ) {
  // do something
}
// Array patterns work with iterables
let [x2,...y2] = 'abc'; // x2='a'; y2=['b', 'c']; 'rest' operator
let [,,x] = ['a', 'b', 'c', 'd']; // x = 'c'; We can also use 'Elision' to skip elements

Хорошо, в каких еще ситуациях деструктуризация полезна?

// To split an Array
let [first1, ...rest1] = ['a', 'b', 'c'];
// Multiple return values
function testing() {
  return {element: undefined, index: -1};
}

По умолчанию + Отдых + Спред

ES6 предоставляет новый и лучший способ определения значений по умолчанию для параметров в наших функциях:

// In ES5, you specify default values for parameters like this:
function foo(x, y) {
  x = x || 0; y = y || 0;
  // do something
}
// ES6 has nicer syntax:
function foo(x=0, y=0) {
  // y is 0 if not passed (or passed as undefined)
}
// In ES6, you can use destructuring in parameter definitions and the code
// becomes simpler:
function selectEntries1({ start=0, end=-1, step=1 } = {}) {
  // do something
}
// Above function is equivalent to this one.
function selectEntries2(options) {
  options = options || {};
  var start = options.start || 0;
  var end = options.end || -1;
  var step = options.step || 1;
  // do something
}

ES6 также позволяет нам иметь параметры отдыха:

function format(pattern, ...params) {
  return params;
}
format('a', 'b', 'c'); // ['b', 'c'] // params will be an array

// In ES6 we have '...' which is the spread operator.
// In ES5, this is how we used to turn an array into parameters: We used apply()
Math.max.apply(null, [-1, 5, 11, 3]);
// Now we can simply do this! As spread operator will extract its items and
// turns them into parameters
Math.max(...[-1, 5, 11, 3]);

Стрелки и лексика this

Стрелки - это сокращение функции, использующее синтаксис =>. Но, в отличие от функций, стрелки имеют то же лексическое значение this, что и окружающий их код.

Тела выражения:

var evens = [0,2,4];
// These two are equivalent:
var odds = evens.map(v => v + 1);
var odds = evens.map(function(v){ return v + 1; });
// These two are equivalent:
var nums = evens.map((v, i) => v + i);
var nums = evens.map(function(v, i){ return v + i; });

Органы постановления:

var fives = [];
nums.forEach(v => {
  // See? for more complex statement we can put everything inside {} just like
  // how we do it with normal functions.
  if (v % 5 === 0) fives.push(v);
});

Лексически это:

var bob = {
  _name: 'Bob',
  _friends: [],
  printFriends() {
    this._friends.forEach(f =>
      // 'this' keyword simply refers to the 'bob' Object in our closure not
      // the closure itself.
      console.log(this._name + ' knows ' + f));
  },
};
class UiComponent {
  constructor() {
    let button = document.getElementById('myButton');
    button.addEventListener('click', () => {
      // By using arrow functions, 'this' keyword simply refers to our
      // own 'UiComponent' class not the closure. This is awesome in ES6.
      // We no more need to use bind() in such cases...
      this.handleClick();
    });
  }
  handleClick() {
    console.log('CLICK');
  }
}

Классы

Классы ES2015 - это простой сахар по сравнению с объектно-ориентированным шаблоном на основе прототипов.

class Person {
  // constructor will be called automatically when the class is initialized.
  constructor(fname, lname) {
    // A class body can only contain methods, but not data properties.
    // So that's why we should set our properties here in the constructor.
    this.fname = fname;
    this.lname = lname;
  }
}

class Employee extends Person {
  constructor(fname, lname, name = 'no name') {
    // In a derived class(extended class), you must call super() before
    // you can use 'this' keyword to define a property. e.g. this.name. Also
    // if we don't use super() we get ReferenceError when we're trying to
    // initialize the sub class.
    super(fname, lname);
    if (name === 'no name') this.name = this.fname + ' ' + this.lname;
  }
  setJob(title) {
    this.job = title;
  }
  static greeting() {
    return 'Hello World!';
  }
  // At the time being, classes only let us create static methods, but not
  // static data properties. But we can create a static getter instead.
  static get JOHN() {
    return new Employee('John', 'Doe');
  }
  // Getters and setters
  get prop() {
    return this.prop;
  }
  set prop(value) {
    this.prop = value;
  }
  // Computed method names
  ['my'+'Method']() {
    // do something
  }
}
var john = new Employee('John', 'Doe');
john.setJob('Designer');
console.log('Class-> Employee class, just initialized: ', Employee.JOHN);
console.log('Class-> Employee class, greeting: ', Employee.greeting());
console.log('Class-> John: ', john);

Расширенные объектные литералы

Объектные литералы расширены, чтобы поддерживать установку прототипа при создании, сокращение для foo: foo назначений, определение методов и выполнение супервызов.

let first = 'Jane';
let last = 'Doe';
let propKey = 'foo';
let obj = {
  // Method definition
  myMethod(x, y) {
    // do something
  },
  // Property value shorthands. The following:
  // let obj = { first, last };
  // is as same as:
  // let obj = { first: first, last: last };
  first,
  last,
  // Computed property keys
  [propKey]: true,
  ['b'+'ar']: 123,
  ['h'+'ello']() {
    // console.log(obj.hello());
    return 'hi';
  },
  // Setters & Getters
  get sth() {
    console.log('Object Literal-> ', 'sth getter');
    return 123;
  },
  set sth(value) {
    console.log('Object Literal-> ', 'sth setter');
    // Return value is ignored
  }
};
// New methods in Object
// The most important new method of Object is assign().
Object.assign(obj, { bar: true }); // it assigns new parameters for our object.
console.log('Object Literal-> ', JSON.stringify(obj)); // {"first":"Jane","last":"Doe","foo":true,"bar":true,"sth":123}

Итераторы + for..of

ECMAScript 6 представляет новый интерфейс для итерации, итерируемый. (Итерируемость на самом деле означает все, что можно повторить) Массивы, строки, карты, наборы, структуры данных DOM (работа в процессе) - все итерируемые.

Проще говоря, итератор - это структура, которая при каждом вызове будет возвращать следующие результаты в последовательности. например entries()метод массива. arr.entries() каждый раз, когда мы его вызываем, он возвращает следующий элемент в массиве.

ПРИМЕЧАНИЕ. Некоторые итерируемые структуры не являются чем-то новым, например, цикл for… Но здесь я просто хочу объяснить, что такое протокол итерации, сделать его более понятным, а также представить новые функции ES6, связанные с ним 😄

Конструкции языка, которые обращаются к данным через протокол итераций:

// Destructuring actually is doing an iterable job(a repeated job, multiple job)
// to extract data out of the array. It should be repeated a job on a specific
// pattern to accomplish this.
let [a,b] = new Set(['a', 'b', 'c']);
// for-of is obviously iterable.
for (let x of ['a', 'b', 'c']) {
  console.log('for-of iteration-> ', x);
}
let arr2 = Array.from(new Set(['a', 'b', 'c'])); // Array.from()
let arr3 = [...new Set(['a', 'b', 'c'])]; // Spread operator (...)
let map0 = new Map([[false, 'no'], [true, 'yes']]); // Constructors of Maps
let set0 = new Set(['a', 'b', 'c']); // Constructors of Sets
// Promise.all(iterableOverPromises).then(); // Promise.all()
// Promise.race(iterableOverPromises).then(); // Promise.race()
// yield* an Iterable
// NOTE: 'yield' is related to Generators when we wanna create a nGenerator
// (Generator is a new feature in ES6)

Давайте использовать итерацию:

let arr4 = ['a', 'b'];
let iter = arr4[Symbol.iterator](); // we create an iterator via the method whose key is Symbol.iterator
// Then we call the iterator’s method next() repeatedly to retrieve the items
// “inside” the Array:
iter.next(); // returns an object: { value: 'a', done: false }
iter.next(); // { value: 'b', done: false }
iter.next(); // { value: undefined, done: true }
// NOTE: The boolean property 'done' indicates when the end of the sequence of
// items has been reached.

Видеть? Это как-то похоже на то, как работает цикл ... Он каждый раз возвращает что-то новое.
ПРИМЕЧАНИЕ. Ключевой характеристикой итерационного протокола является его последовательность: итератор возвращает значения по одному. Это означает, что если итерируемая структура данных является нелинейной (например, дерево), итерация приведет к ее линеаризации.

Теперь давайте используем символы в объекте, который, как нам нравится, действует как итератор:

let iterableObject = {
  // Our object must have a dynamic method which is actually using Symbol
  // primitive. As we know Symbols are always unique and that's one of their
  // use cases, to create a unique dynamic method for our classes.
  [Symbol.iterator]() {
    let data = ['hello', 'world'];
    let index = 0;
    // Now our iterator method must return an object which has next() method.
    return {
      // Here is our iterator logic! In our example here, we check 'index'
      // variable and act accordingly based on its value.
      next() {
        if (index < data.length) {
          return { value: data[index++] };
        } else {
          return { done: true };
        }
      }
    };
  }
};
// Now that's how we can use our iterable object.
for (let x of iterableObject) {
  // x is different each time. The first time in the loop it's 'hello' and the
  // second time it's 'world'.
  console.log('iterableObject-> ', x);
}

ПРИМЕЧАНИЕ. Как мы знаем, мы использовали символ в качестве ключа метода в нашем объекте. Этот уникальный маркер делает объект итерируемым и позволяет нам использовать цикл for-of. Прохладный! Теперь мы создали в нашем коде настраиваемый итерируемый объект (или класс), который позволяет нам упростить итерируемый код в наших проектах.

Если бы указанный выше итерируемый объект был реальным образцом, он мог бы быть действительно полезен в проекте. Мне не нужно было помещать всю мою логику в цикл for-of для выполнения итеративной работы, я мог легко создать значимый итерируемый класс и внутри него поместить свою логику, тогда я мог бы использовать свой класс в for- цикла в разных местах и ​​легко выполнять мою повторяемую работу. Легкий! Это сделает мой код более чистым и сухим.

Модули

Поддержка на уровне языка модулей для определения компонентов. Кодирует шаблоны из популярных загрузчиков модулей JavaScript (AMD, CommonJS). В ECMAScript 6 модули хранятся в файлах. Есть ровно один модуль на файл и один файл на модуль.

// lib/math.js
// We simply export any variable or function in our file.
export function sum(x, y) { return x + y; }
export var pi = 3.141593;
// app.js
// Import anything that we like in an other file.
import * as math from "lib/math";
// Now we can access all the things that we've exported in math.js like this:
alert("2π = " + math.sum(math.pi, math.pi));
// otherApp.js
// We can also import each functionality explicitly instead of importing them
// 'as' one general name.
import {sum, pi} from "lib/math";
alert("2π = " + sum(pi, pi));

Также может быть один экспорт по умолчанию. Модули, которые экспортируют только отдельные значения, очень популярны в сообществе Node.js. У нас может просто быть модуль, который экспортирует только один класс или функцию.

// myFunc.js
// Of course our function can have a name too: export default function foo() {}
export default function() { }
import myFunc from 'myFunc';
myFunc();
// MyClass.js
// Of course our class can have a name too: export default class Bar {}
export default class { }
import MyClass from 'MyClass';
let inst = new MyClass();

Как мы знаем из кода ECMAScript 5, который не использует модули через библиотеки (такие как RequireJS, browserify или webpack), шаблон модуля раскрытия популярен и основан на IIFE. Его преимущество в том, что он четко разделяет публичное и частное.

// How to create properly a module in ES5:
// my_module.js
var my_module = (function () {
  // Module-private variable:
  var countInvocations = 0;
  function myFunc(x) {
    countInvocations++;
  }
  // Exported by module:
  return {
    myFunc: myFunc
  };
}());
// This module pattern produces a global variable and is used as follows
my_module.myFunc(33);

В ECMAScript 6 модули встроены, поэтому барьер для их принятия невелик:

// How to create properly a module in ES6:
// my_module.js
// Module-private variable:
let countInvocations = 0;
// export the module
export function myFunc(x) {
  countInvocations++;
}

Карта + набор + WeakMap + WeakSet

Эффективные структуры данных для общих алгоритмов. Следующие четыре структуры данных являются новыми в ECMAScript 6: Map, WeakMap, Set и WeakSet.

Карта. В ES5 отсутствовала структура данных для сопоставления значений со значениями. Структура данных карты в ECMAScript 6 позволяет использовать произвольные значения в качестве ключей и приветствуется.

// Create an empty Map
let map = new Map();
// We can also fill out the map right at the moment that we're initializing it.
let map = new Map([ [ 1, 'one' ], [ 2, 'two' ] ]);
// The set() method of Map is chain-able. So we can fill out the map like this too.
let map = new Map().set(1, 'one').set(2, 'two');
// Any value can be a key, even an object!
// We can also set an OR operator if what we're going to get was undefined for
// some reasons: map.get(KEY) || 0;
const KEY = {};
map.set(KEY, 123);
map.get(KEY); // 123
map.has(KEY); // true
map.delete(KEY); // true
map.size; // 1
map.clear(); // To empty the map
// keys() returns an iterable over the keys in the Map.We can use it in a
// for-of loop for instance.
map.keys();
// values() returns an iterable over the values in the Map.
map.values();
// entries() returns the entries of the Map as an iterable over [key,value]
// pairs (Arrays).
// NOTE: We can use destructuring in a for-of loop to access both, keys and
// values, just like what we can do with the entries() method of an array.
map.entries();

WeakMap: это карта, которая не предотвращает сборку своих ключей мусора. Это означает, что вы можете связывать данные с объектами, не беспокоясь об утечках памяти. WeakMap - это структура данных, ключи которой должны быть объектами, а значения могут быть произвольными. Он имеет тот же API, что и Map, с одним существенным отличием: вы не можете перебирать содержимое - ни ключи, ни значения, ни записи. Вы также не можете очистить WeakMap.

Set: ECMAScript 5 также не имеет структуры данных Set. Есть два возможных решения:

  1. Используйте ключи объекта для хранения элементов набора строк.
  2. Сохранение (произвольных) установленных элементов в массиве: проверьте, содержит ли он элемент через indexOf(), удалите элементы через filter() и т. Д. Это не очень быстрое решение, но его легко реализовать. Следует иметь в виду, что indexOf() не может найти значение NaN.

ECMAScript 6 имеет структуру данных Set, которая работает для произвольных значений, работает быстро и правильно обрабатывает NaN.

let set = new Set();
// We can also fill out the set right at the moment that we're initializing it.
let set = new Set(['red', 'green', 'blue']);
// The add() method of Set is chain-able. So we can fill out the set like this too.
let set = new Set().add('red').add('green').add('blue');
set.add('red');
set.has('red'); // true
set.delete('red'); // true
set.size; // 1
set.clear(); // To empty the set

WeakSet: это набор, который не предотвращает сборку мусора его элементов.

ПРИМЕЧАНИЕ. Почему у карт и наборов есть свойство «размер», а не «длина» (как у массивов)? Причина этой разницы в том, что длина предназначена для последовательностей, структур данных, которые можно индексировать, например массивов. size предназначен для коллекций, которые в основном неупорядочены - например, Карты и Наборы.

Обещания

Обещания - это библиотека для асинхронного программирования. Мы уже знакомы с шаблоном обещания в Javascript. Но, говоря простым языком, на самом деле это упрощает асинхронное поведение. Мы можем установить новое обещание и внутри него закодировать любое асинхронное поведение. Как вызов ajax, тайм-аут и т. Д.

function getJSON (url) {
  let promise = new Promise(function (resolve, reject) {
    // Ok, now here in the promise, we simply write our asynchronous behavior.
    // e.g. an ajax call.
    // resolve(value); // if our ajax call successes, we call resolve() and pass
    // the necessary argument to it. What is the argument? Well, we ourselves
    // decide what it should be according to our asynchronous job. e.g. for an
    // ajax job, the jquery's ajax() method calls our own successful function
    // when it loads our file successfully. It also pass it an argument which
    // is actually the data that it loaded. So data is our argument here.
    // reject(error); // if it fails, we call reject() and pass the necessary
    // argument to it.
  });
  return promise; // remember to return the promise.
}
// now this is how we use our promise. its then() method will be called when
// our promise is resolved, catch() will be called when it has been rejected.
getJSON('promised.json')
.then(value => {})
.catch(error => {});
// NOTE: There's also an optional second argument for the then() method, which
// is the error actually. This code is equivalent to the above one. We can use
// any one of them that we wish.
getJSON('promised.json')
.then(value => {}, error => {});
// We can also chain our promise. then() method returns a new Promise Q.
getJSON('promised.json')
.then(value1 => 123) // whatever the first then() returns, is the argument of the next then()
.then(value2 => {}); // so 'value2' is equal to 123.
// In chaining, if any one of our promises fail, we can still continue chaining
// by returning a default value in the catch() method of the one that failed.
getJSON('promised.json')
.catch(() => 'default value') // whatever the first then() returns, is the argument of the next then()
.then(value2 => {}); // so 'value2' is equal to 'default value'.
// We can also manually throw an exception and it will be passed on to the next
// error handler.
getJSON('promised.json')
.then(value => {throw new Error();})
.then(err => {});

// with chain-able promises, as we know we can easily do something like this
// and have nested promises:
asyncFunc1()
.then(function (value1) {
  asyncFunc2()
    .then(function (value2) {
      // do something else...
  });
});
// or make it flat, and do it like this:
asyncFunc1()
.then(function (value1) {
  return asyncFunc2();
})
.then(function (value2) {
  // do something else...
});

Что дальше?

Это было всего лишь краткое введение, чтобы познакомить вас с ES6 и его новыми функциями. Теперь ты хочешь узнать больше, верно? Так что приготовьтесь к большому количеству крутых событий! Вот несколько отличных ресурсов, которые помогут вам узнать больше: