
Обзор 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 с самого начала. Разве это не круто? Да, это так! Итак, давайте просто посмотрим, как все это установить, и приступим к работе.
- Сначала загрузите и установите node.js на свой компьютер.
- Теперь откройте терминал / командную строку и введите:
npm install --global babel.
Нажмите Enter на клавиатуре, чтобы запустить команду и установить Babeljs в самый первый раз на вашем компьютере.
Babeljs компилятор ES6. - Выполните:
npm install -g browserify.
Чтобы установить Browserify, если вы хотите использовать синтаксис загрузчика модуля ES6.
Browserify позволяет писать модульные коды JavaScript в отдельных файлах Javascript, а затем объединять их все и заполните свою html-страницу только одним связанным файлом Javascript. - Запустите:
cd path/to/my/project, чтобы перейти из каталога в каталог вашего проекта. - Бег:
babel src --out-dir build. Эта команда преобразует любые файлы .js в папке 'src' из синтаксиса ES6 в ES5 и помещает новые преобразованные файлы в папку 'build'.
Теперь все готово! Вы можете кормить html новыми преобразованными файлами .js, и браузер, как всегда, должен запускать ваши коды
Возможности ECMAScript 6
- Строка + массив + объектные API
- Символы
- Шаблонные литералы
- Let + Const
- Разрушение
- По умолчанию + Отдых + Спред
- Стрелки и лексическое это
- Классы
- Расширенные объектные литералы
- Итераторы + for..of
- Модули
- Карта + набор + WeakMap + WeakSet
- Обещания
строка + массив + объектные 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. Есть два возможных решения:
- Используйте ключи объекта для хранения элементов набора строк.
- Сохранение (произвольных) установленных элементов в массиве: проверьте, содержит ли он элемент через
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 и его новыми функциями. Теперь ты хочешь узнать больше, верно? Так что приготовьтесь к большому количеству крутых событий! Вот несколько отличных ресурсов, которые помогут вам узнать больше:
- Командная строка для веб-дизайна, эта серия руководств не имеет ничего общего с ES6 напрямую! Но это отличное начало для тех веб-дизайнеров, которые еще не знакомы с инструментами командной строки, но должны быть!
- Es6features repo более подробно объяснил особенности ES6.
- Компилятор Javascript Babeljs.
- [Руководство по стилю Javascript] (Руководство по стилю JavaScript Airbnb) учит разумному подходу к JavaScript.
- Exploring ES6 Book - всеобъемлющая книга о ES6, написанная Акселем Раушмайером.
- Список дополнительных ресурсов здесь, чтобы вы могли начать работу еще быстрее.