Обзор 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, написанная Акселем Раушмайером.
- Список дополнительных ресурсов здесь, чтобы вы могли начать работу еще быстрее.