小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

ES6 手冊(cè)

 贊那回憶09 2016-08-04

tip

文章是翻譯,主要是很多 ES6 的用法技巧以及最佳實(shí)踐~
原文 https://github.com/DrkSephy/es6-cheatsheet


es6

ES6 手冊(cè)

這篇手冊(cè)包含了 ES2015(ES6) 的使用小技巧、最佳實(shí)踐以及可以給你每天的工作參考的代碼片段。

內(nèi)容列表

var 和 let/const 的比較

除了 var ,我們現(xiàn)在還可以使用兩個(gè)新的標(biāo)示符來定義一個(gè)變量 —— letconst。和 var 不一樣的是,letconst 不存在變量提升。

使用 var 的栗子:

var snack = 'Meow Mix';

function getFood(food) {
if (food) {
var snack = 'Friskies';
return snack;
}
return snack;
}

getFood(false); // undefined

當(dāng)我們用 let 代替 var 的時(shí)候,觀察會(huì)發(fā)生什么:

let snack = 'Meow Mix';

function getFood(food) {
if (food) {
let snack = 'Friskies';
return snack;
}
return snack;
}

getFood(false); // 'Meow Mix'

當(dāng)我們重構(gòu)使用 var 的老代碼的時(shí)候應(yīng)該注意上面的變化。盲目地使用 let 替換 var 可能會(huì)出現(xiàn)出乎意料的情況。

注意letconst 是塊級(jí)作用域,因此在變量未被定義之前使用它會(huì)產(chǎn)生一個(gè) ReferenceError。

console.log(x); // ReferenceError: x is not defined

let x = 'hi';

最佳實(shí)踐: 在遺留代碼中放棄使用 var 聲明意味著需要很小心地重構(gòu);在新的項(xiàng)目代碼中,使用 let 聲明一個(gè)可以改變的變量,用 const 聲明一個(gè)不能被重新賦值的變量。

用塊級(jí)作用域代替 IIFES

函數(shù)立即執(zhí)行表達(dá)式 的通常用途是創(chuàng)造一個(gè)內(nèi)部的作用域,在 ES6 中,我們能夠創(chuàng)造一個(gè)塊級(jí)作用域而不僅限于函數(shù)作用域:

IIFES:

(function () {
var food = 'Meow Mix';
}());

console.log(food); // Reference Error

使用 ES6 的塊級(jí)作用域:

{
let food = 'Meow Mix';
}

console.log(food); // Reference Error

箭頭函數(shù)

我們經(jīng)常需要給回調(diào)函數(shù)維護(hù)一個(gè)詞法作用域的上下文 this。
看看這個(gè)栗子:

function Person(name) {
this.name = name;
}

Person.prototype.prefixName = function (arr) {
return arr.map(function (character) {
return this.name + character; // Cannot read property 'name' of undefined
});
};

一個(gè)常用的解決辦法是把 this 存在一個(gè)變量中:

function Person(name) {
this.name = name;
}

Person.prototype.prefixName = function (arr) {
var that = this; // Store the context of this
return arr.map(function (character) {
return that.name + character;
});
};

我們也可以傳遞一個(gè)合適的 this 上下文:

function Person(name) {
this.name = name;
}

Person.prototype.prefixName = function (arr) {
return arr.map(function (character) {
return this.name + character;
}, this);
}

我們還可以綁定上下文:

function Person(name) {
this.name = name;
}

Person.prototype.prefixName = function (arr) {
return arr.map(function (character) {
return this.name + character;
}.bind(this));
};

使用 箭頭函數(shù)this 將不會(huì)受到影響,并且我們可以重寫上面的函數(shù):


function Person(name) {
this.name = name;
}

Person.prototype.prefixName = function (arr) {
return arr.map(character => this.name + character);
};

最佳實(shí)踐:當(dāng)你需要維護(hù)一個(gè) this 上下文的時(shí)候使用 箭頭函數(shù)。

在我們寫一個(gè)函數(shù)的時(shí)候,箭頭函數(shù)更加簡(jiǎn)潔并且可以很簡(jiǎn)單地返回一個(gè)值:

var squares = arr.map(function (x) { return x * x }); // Function Expression

const arr = [1, 2, 3, 4, 5];
const squares = arr.map(x => x * x); // Arrow Function for terser implementation

最佳實(shí)踐:盡可能使用箭頭函數(shù)代替原來的寫法。

字符串

在 ES6 中,標(biāo)準(zhǔn)庫升級(jí)了很多,在這些變化中有許多新的對(duì)于字符串的函數(shù),比如 .includes().repeat()。

.includes( )

var string = 'food';
var substring = 'foo';

console.log(string.indexOf(substring) > -1);

之前我們使用 indexOf() 函數(shù)的返回值是否 >-1 來判斷字符串是否包含某些字符串,現(xiàn)在我們更簡(jiǎn)單地使用 .includes() 來返回一個(gè)布爾值來判斷:

const string = 'food';
const substring = 'foo';

console.log(string.includes(substring)); // true

.repeat( )

function repeat(string, count) {
var strings = [];
while(strings.length <>count) {
strings.push(string);
}
return strings.join('');
}

在 ES6 中,可以更簡(jiǎn)便地實(shí)現(xiàn):

// String.repeat(numberOfRepetitions)
'meow'.repeat(3); // 'meowmeowmeow'

模版字符串

使用 模版字符串 我們就可以不用對(duì)某些特殊自負(fù)進(jìn)行轉(zhuǎn)義處理了:

var text = 'This string contains \'double quotes\' which are escaped.';

let text = `This string contains 'double quotes' which don't need to be escaped anymore.`;

模版字符串 還支持插入,可以把變量值和字符串連接起來.

var name = 'Tiger';
var age = 13;

console.log('My cat is named ' + name + ' and is ' + age + ' years old.');

更簡(jiǎn)單:

const name = 'Tiger';
const age = 13;

console.log(`My cat is named ${name} and is ${age} years old.`);

在 ES5 中,需要換行時(shí),需要這樣:

var text = (
'cat\n' +
'dog\n' +
'nickelodeon'
);

或者這樣:

var text = [
'cat',
'dog',
'nickelodeon'
].join('\n');

模版字符串 可以支持換行并且不需要額外的處理:

let text = ( `cat
dog
nickelodeon`
);

模版字符串 還支持表達(dá)式:

let today = new Date();
let text = `The time and date is ${today.toLocaleString()}`;

解構(gòu)

結(jié)構(gòu)可以讓我們用一個(gè)更簡(jiǎn)便的語法從一個(gè)數(shù)組或者對(duì)象(即使是深層的)中分離出來值,并存儲(chǔ)他們。

結(jié)構(gòu)數(shù)組

var arr = [1, 2, 3, 4];
var a = arr[0];
var b = arr[1];
var c = arr[2];
var d = arr[3];
let [a, b, c, d] = [1, 2, 3, 4];

console.log(a); // 1
console.log(b); // 2

結(jié)構(gòu)對(duì)象

var luke = { occupation: 'jedi', father: 'anakin' };
var occupation = luke.occupation; // 'jedi'
var father = luke.father; // 'anakin'
let luke = { occupation: 'jedi', father: 'anakin' };
let {occupation, father} = luke;

console.log(occupation); // 'jedi'
console.log(father); // 'anakin'

模塊

在 ES6 之前,我們使用 Browserify 這樣的庫來創(chuàng)建客戶端的模塊化,在 node.js 中使用 require
在 ES6 中,我們可以直接使用所有類型的模塊化(AMD 和 CommonJS)。

使用 CommonJS 的出口

module.exports = 1;
module.exports = { foo: 'bar' };
module.exports = ['foo', 'bar'];
module.exports = function bar () {};

使用 ES6 的出口

在 ES6 中我們可以暴漏多個(gè)值,使用 Exports

export let name = 'David';
export let age = 25;??

或者暴露一個(gè)對(duì)象列表:

function sumTwo(a, b) {
return a + b;
}

function sumThree(a, b, c) {
return a + b + c;
}

export { sumTwo, sumThree };

我們還可以暴露函數(shù)、對(duì)象和其他的值,通過簡(jiǎn)單地使用 export 這個(gè)關(guān)鍵字:

export function sumTwo(a, b) {
return a + b;
}

export function sumThree(a, b, c) {
return a + b + c;
}

最后,我們還可以綁定一個(gè)默認(rèn)的輸出:

function sumTwo(a, b) {
return a + b;
}

function sumThree(a, b, c) {
return a + b + c;
}

let api = {
sumTwo,
sumThree
};

export default api;

/* Which is the same as
* export { api as default };
*/

最佳實(shí)踐:總是在模塊的最后面使用 export default 方法,這可以讓暴露的東西更加清晰并且可以節(jié)省時(shí)間去找出暴漏出來值的名字。尤其如此,在 CommonJS 中通常的實(shí)踐就是暴露一個(gè)簡(jiǎn)單的值或者對(duì)象。堅(jiān)持這種模式,可以讓我們的代碼更加可讀,并且在 ES6 和 CommonJS 模塊之間更好地兼容。

ES6 中的導(dǎo)入

在 ES6 中同樣提供了多樣的導(dǎo)入方式,我們可以這么導(dǎo)入一個(gè)整個(gè)文件:

import 'underscore';

需要著重注意的一點(diǎn)是簡(jiǎn)單的導(dǎo)入整個(gè)文件會(huì)在那個(gè)文件的頂部執(zhí)行所有的代碼

和 Python 中類似,我們可以命名導(dǎo)入的值:

import { sumTwo, sumThree } from 'math/addition';

我們還可以重命名導(dǎo)入:

import {
sumTwo as addTwoNumbers,
sumThree as sumThreeNumbers
} from 'math/addition';

另外,我們可以導(dǎo)入所有的東西(整體加載):

import * as util from 'math/addition';

最后,我們可以從一個(gè)模塊中導(dǎo)入一個(gè)值的列表:

import * as additionUtil from 'math/addition';
const { sumTwo, sumThree } = additionUtil;

可以像這樣導(dǎo)入默認(rèn)綁定的輸出:

import api from 'math/addition';
// Same as: import { default as api } from 'math/addition';

雖然最好保持出口的簡(jiǎn)單,但如果需要的話我們有時(shí)可以混合默認(rèn)的進(jìn)口和混合進(jìn)口。當(dāng)我們這樣出口的時(shí)候:

// foos.js
export { foo as default, foo1, foo2 };

我們可以這樣導(dǎo)入它們:

import foo, { foo1, foo2 } from 'foos';

當(dāng)我們用 commonjs 的語法導(dǎo)入一個(gè)模塊的出口時(shí)(比如 React),我們可以這樣做:

import React from 'react';
const { Component, PropTypes } = React;

還有更精簡(jiǎn)的寫法:

import React, { Component, PropTypes } from 'react';

注意:導(dǎo)出的值是動(dòng)態(tài)引用的,而不是拷貝。因此,在一個(gè)模塊中改變一個(gè)變量的綁定將影響輸出模塊中的值。應(yīng)該避免改變這些導(dǎo)出值的公共接口。(原文這里我覺得有誤)

參數(shù)

在 ES5 中,在函數(shù)中我們需要各種操作去處理 默認(rèn)參數(shù)、不定參數(shù)重命名參數(shù) 等需求,在 ES6 中我們可以使用更簡(jiǎn)潔的語法完成這些需求:

默認(rèn)參數(shù)

function addTwoNumbers(x, y) {
x = x || 0;
y = y || 0;
return x + y;
}

ES6 中,函數(shù)的參數(shù)可以支持設(shè)置默認(rèn)值:

function addTwoNumbers(x=0, y=0) {
return x + y;
}

addTwoNumbers(2, 4); // 6
addTwoNumbers(2); // 2
addTwoNumbers(); // 0

rest 參數(shù)

在 ES5 中,我們需要這么處理不定參數(shù):

function logArguments() {
for (var i=0; i <>arguments.length; i++) {
console.log(arguments[i]);
}
}

使用 rest ,我們就可以處理不確定數(shù)目的參數(shù):

function logArguments(...args) {
for (let arg of args) {
console.log(arg);
}
}

命名參數(shù)

在 ES5 中是使用配置對(duì)象的模式來處理命名參數(shù),jQuery 中的使用:

function initializeCanvas(options) {
var height = options.height || 600;
var width = options.width || 400;
var lineStroke = options.lineStroke || 'black';
}

我們可以利用解構(gòu)的一個(gè)函數(shù)的形參實(shí)現(xiàn)相同的功能:

function initializeCanvas(
{ height=600, width=400, lineStroke='black'})
{

// Use variables height, width, lineStroke here
}

如果我們想使整個(gè)值可選擇,我們可以結(jié)構(gòu)將一個(gè)空的對(duì)象:

function initializeCanvas(
{ height=600, width=400, lineStroke='black'} = {})
{

// ...
}

展開操作

在 ES5 中,我們可以 apply Math.max 方法來獲得一個(gè)數(shù)組中的最大值:

Math.max.apply(null, [-1, 100, 9001, -32]); // 9001

在 ES6 中,我們可以通過展開操作把一個(gè)數(shù)組的值作為參數(shù)傳遞給一個(gè)函數(shù):

Math.max(...[-1, 100, 9001, -32]); // 9001

我們可以更簡(jiǎn)潔地使用這個(gè)語法來合并數(shù)組:

let cities = ['San Francisco', 'Los Angeles'];
let places = ['Miami', ...cities, 'Chicago']; // ['Miami', 'San Francisco', 'Los Angeles', 'Chicago']

類 Classes

在 ES6 之前,我們通過構(gòu)造函數(shù)來創(chuàng)造一個(gè)類,并且通過原型來擴(kuò)展屬性:

function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}

Person.prototype.incrementAge = function () {
return this.age += 1;
};

然后可以這樣繼承類:

function Personal(name, age, gender, occupation, hobby) {
Person.call(this, name, age, gender);
this.occupation = occupation;
this.hobby = hobby;
}

Personal.prototype = Object.create(Person.prototype);
Personal.prototype.constructor = Personal;
Personal.prototype.incrementAge = function () {
Person.prototype.incrementAge.call(this);
this.age += 20;
console.log(this.age);
};

在 ES6 中,提供了更多的語法糖,可以直接創(chuàng)造一個(gè)類:

class Person {
constructor(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}

incrementAge() {
this.age += 1;
}
}

使用 extends 關(guān)鍵字來繼承一個(gè)類:

class Personal extends Person {
constructor(name, age, gender, occupation, hobby) {
super(name, age, gender);
this.occupation = occupation;
this.hobby = hobby;
}

incrementAge() {
super.incrementAge();
this.age += 20;
console.log(this.age);
}
}

最佳實(shí)踐:雖然使用 ES6 的語法創(chuàng)造類的時(shí)候,js引擎是如何實(shí)現(xiàn)類以及如何操作原型是令人費(fèi)解的,但是未來對(duì)初學(xué)者來說這是一個(gè)好的開始,同時(shí)也可以讓我們寫更簡(jiǎn)潔的代碼。

Symbols

Symbols 在 ES6 之前就已經(jīng)存在,但是我們現(xiàn)在可以直接使用一個(gè)開發(fā)的接口了。Symbols 是不可改變并且是第一無二的,可以在任意哈希中作一個(gè)key。

Symbol()

調(diào)用 Symbol() 或者 Symbol(description) 可以創(chuàng)造一個(gè)第一無二的符號(hào),但是在全局是看不到的。Symbol() 的一個(gè)使用情況是給一個(gè)類或者命名空間打上補(bǔ)丁,但是可以確定的是你不會(huì)去更新它。比如,你想給 React.Component 類添加一個(gè) refreshComponent 方法,但是可以確定的是你不會(huì)在之后更新這個(gè)方法:

const refreshComponent = Symbol();

React.Component.prototype[refreshComponent] = () => {
// do something
}

Symbol.for(key)

Symbol.for(key) 同樣會(huì)創(chuàng)造一個(gè)獨(dú)一無二并且不可改變的 Symbol,但是它可以全局看到,兩個(gè)相同的調(diào)用 Symbol.for(key) 會(huì)返回同一個(gè) Symbol 類:

Symbol('foo') === Symbol('foo') // false
Symbol.for('foo') === Symbol('foo') // false
Symbol.for('foo') === Symbol.for('foo') // true

對(duì)于 Symbols 的普遍用法(尤其是Symbol.for(key))是為了協(xié)同性。它可以通過在一個(gè)第三方插件中已知的接口中對(duì)象中的參數(shù)中尋找用 Symbol 成員來實(shí)現(xiàn),比如:

function reader(obj) {
const specialRead = Symbol.for('specialRead');
if (obj[specialRead]) {
const reader = obj[specialRead]();
// do something with reader
} else {
throw new TypeError('object cannot be read');
}
}

在另一個(gè)庫中:

const specialRead = Symbol.for('specialRead');

class SomeReadableType {
[specialRead]() {
const reader = createSomeReaderFrom(this);
return reader;
}
}

Maps

Maps 在 JavaScript 中是一個(gè)非常必須的數(shù)據(jù)結(jié)構(gòu),在 ES6 之前,我們通過對(duì)象來實(shí)現(xiàn)哈希表:

var map = new Object();
map[key1] = 'value1';
map[key2] = 'value2';

但是它并不能防止我們偶然地用一些特殊的屬性名重寫函數(shù):

> getOwnProperty({ hasOwnProperty: 'Hah, overwritten'}, 'Pwned');
> TypeError: Property 'hasOwnProperty' is not a function

實(shí)際上 Maps 允許我們對(duì)值進(jìn)行 setgetsearch 操作:

let map = new Map();
> map.set('name', 'david');
> map.get('name'); // david
> map.has('name'); // true

Maps 更令人驚奇的部分就是它不僅限于使用字符串作為 key,還可以用其他任何類型的數(shù)據(jù)作為 key:

let map = new Map([
['name', 'david'],
[true, 'false'],
[1, 'one'],
[{}, 'object'],
[function () {}, 'function']
]);

for (let key of map.keys()) {
console.log(typeof key);
// > string, boolean, number, object, function
}

注意:但我們使用 map.get() 方法去測(cè)試相等時(shí),如果在 Maps 中使用 函數(shù) 或者 對(duì)象 等非原始類型值的時(shí)候測(cè)試將不起作用,所以我們應(yīng)該使用 Strings, Booleans 和 Numbers 這樣的原始類型的值。

我們還可以使用 .entries() 來遍歷迭代:

for (let [key, value] of map.entries()) {
console.log(key, value);
}

WeakMaps

在 ES6 之前,為了存儲(chǔ)私有變量,我們有各種各樣的方法去實(shí)現(xiàn),其中一種方法就是用命名約定:

class Person {
constructor(age) {
this._age = age;
}

_incrementAge() {
this._age += 1;
}
}

但是命名約定在代碼中仍然會(huì)令人混淆并且并不會(huì)真正的保持私有變量不被訪問?,F(xiàn)在,我們可以使用 WeakMaps 來存儲(chǔ)變量:

let _age = new WeakMap();
class Person {
constructor(age) {
_age.set(this, age);
}

incrementAge() {
let age = _age.get(this) + 1;
_age.set(this, age);
if (age > 50) {
console.log('Midlife crisis');
}
}
}

在 WeakMaps 存儲(chǔ)變量很酷的一件事是它的 key 他不需要屬性名稱,可以使用 Reflect.ownKeys() 來查看這一點(diǎn):

> const person = new Person(50);
> person.incrementAge(); // 'Midlife crisis'
> Reflect.ownKeys(person); // []

一個(gè)更實(shí)際的實(shí)踐就是可以 WeakMaps 儲(chǔ)存 DOM 元素,而不會(huì)污染元素本身:

let map = new WeakMap();
let el = document.getElementById('someElement');

// Store a weak reference to the element with a key
map.set(el, 'reference');

// Access the value of the element
let value = map.get(el); // 'reference'

// Remove the reference
el.parentNode.removeChild(el);
el = null;

// map is empty, since the element is destroyed

如上所示,當(dāng)一個(gè)對(duì)象被垃圾回收機(jī)制銷毀的時(shí)候, WeakMap 將會(huì)自動(dòng)地一處關(guān)于這個(gè)對(duì)象地鍵值對(duì)。

注意:為了進(jìn)一步說明這個(gè)例子的實(shí)用性,可以考慮 jQuery 是如何實(shí)現(xiàn)緩存一個(gè)對(duì)象相關(guān)于對(duì)引用地 DOM 元素對(duì)象。使用 jQuery ,當(dāng)一個(gè)特定地元素一旦在 document 中移除的時(shí)候,jQuery 會(huì)自動(dòng)地釋放內(nèi)存。總體來說,jQuery 在任何 dom 庫中都是很有用的。

Promises

Promises 可以讓我們遠(yuǎn)離平行的代碼(回調(diào)地獄):

func1(function (value1) {
func2(value1, function (value2) {
func3(value2, function (value3) {
func4(value3, function (value4) {
func5(value4, function (value5) {
// Do something with value 5
});

});

});

});

});

轉(zhuǎn)變成垂直代碼:

func1(value1)
.then(func2)
.then(func3)
.then(func4)
.then(func5, value5 => {
// Do something with value 5
});

在 ES6 之前,我們使用 bluebird 或者 q,現(xiàn)在我們可以使用原生的 Promise 了。

new Promise((resolve, reject) =>
reject(new Error('Failed to fulfill Promise')))
.catch(reason => console.log(reason));

我們有兩個(gè)處理器,resolve(當(dāng)Promise是 fulfilled 時(shí)的回調(diào))和 reject(當(dāng)Promise是 rejected 時(shí)的回調(diào)):。

Promises的好處:對(duì)錯(cuò)誤的處理使用一些列回調(diào)會(huì)使代碼很混亂,使用 Promise ,我看可以清晰的讓錯(cuò)誤冒泡并且在合適的時(shí)候處理它,甚至,在 Promise 確定了 resolved/rejected 之后,他的值是不可改變的--它從來不會(huì)變化。

這是使用 Promise 的一個(gè)實(shí)際的栗子:

var request = require('request');

return new Promise((resolve, reject) => {
request.get(url, (error, response, body) => {
if (body) {
resolve(JSON.parse(body));
} else {
resolve({});
}
});

});

我們還可以使用 Promise.all()并行 處理多個(gè)異步函數(shù):

let urls = [
'/api/commits',
'/api/issues/opened',
'/api/issues/assigned',
'/api/issues/completed',
'/api/issues/comments',
'/api/pullrequests'
];

let promises = urls.map((url) => {
return new Promise((resolve, reject) => {
$.ajax({ url: url })
.done((data) => {
resolve(data);
});
});
});

Promise.all(promises)
.then((results) => {
// Do something with results of all our promises
});

Generators 生成器

就像 Promises 可以幫我們避免回調(diào)地獄,Generators 可以幫助我們讓代碼風(fēng)格更整潔--用同步的代碼風(fēng)格來寫異步代碼,它本質(zhì)上是一個(gè)可以暫停計(jì)算并且可以隨后返回表達(dá)式的值的函數(shù)。

一個(gè)簡(jiǎn)單的栗子使用 generators:

function* sillyGenerator() {
yield 1;
yield 2;
yield 3;
yield 4;
}

var generator = sillyGenerator();
> console.log(generator.next()); // { value: 1, done: false }
> console.log(generator.next()); // { value: 2, done: false }
> console.log(generator.next()); // { value: 3, done: false }
> console.log(generator.next()); // { value: 4, done: false }

next 可以回去到下一個(gè) yield 返回的值,當(dāng)然上面的代碼是非常不自然的,我們可以利用 Generators 來用同步的方式來寫異步操作:

// Hiding asynchronousity with Generators

function request(url) {
getJSON(url, function(response) {
generator.next(response);
});
}

這里的 generator 函數(shù)將會(huì)返回需要的數(shù)據(jù):

function* getData() {
var entry1 = yield request('http://some_api/item1');
var data1 = JSON.parse(entry1);
var entry2 = yield request('http://some_api/item2');
var data2 = JSON.parse(entry2);
}

通過 yield,我們可以保證 entry1data1 中我們需要解析并儲(chǔ)存的數(shù)據(jù)。

雖然我們可以利用 Generators 來用同步的方式來寫異步操作,但是確認(rèn)錯(cuò)誤的傳播變得不再清晰,我們可以在 Generators 中加上 Promise:

function request(url) {
return new Promise((resolve, reject) => {
getJSON(url, resolve);
});
}

然后我們寫一個(gè)函數(shù)逐步調(diào)用 next 并且利用 request 方法產(chǎn)生一個(gè) Promise:

function iterateGenerator(gen) {
var generator = gen();
(function iterate(val) {
var ret = generator.next();
if(!ret.done) {
ret.value.then(iterate);
}
})();
}

在 Generators 中加上 Promise 之后我們可以更清晰的使用 Promise 中的 .catchreject來捕捉錯(cuò)誤,讓我們使用新的 Generator,和之前的還是蠻相似的:

iterateGenerator(function* getData() {
var entry1 = yield request('http://some_api/item1');
var data1 = JSON.parse(entry1);
var entry2 = yield request('http://some_api/item2');
var data2 = JSON.parse(entry2);
});

Async Await

當(dāng) ES6 真正到來的時(shí)候,async await 可以用更少的處理實(shí)現(xiàn) Promise 和 Generators 所實(shí)現(xiàn)的異步處理:

var request = require('request');

function getJSON(url) {
return new Promise(function(resolve, reject) {
request(url, function(error, response, body) {
resolve(body);
});
});
}

async function main() {
var data = await getJSON();
console.log(data); // NOT undefined!
}

main();

在 js 引擎中,它所實(shí)現(xiàn)的和 Generators 其實(shí)是一樣的,我更推薦在 Generators + Promises 之上使用 async await,更多的資源和使用 ES7 和 用 babel 轉(zhuǎn)化可以看這里。

Getter/Setter 函數(shù)

ES6 已經(jīng)開始實(shí)現(xiàn)了 gettersetter 函數(shù),比如蝦面這個(gè)栗子:

class Employee {

constructor(name) {
this._name = name;
}

get name() {
if(this._name) {
return 'Mr. ' + this._name.toUpperCase();
} else {
return undefined;
}
}

set name(newName) {
if (newName == this._name) {
console.log('I already have this name.');
} else if (newName) {
this._name = newName;
} else {
return false;
}
}
}

var emp = new Employee('James Bond');

// uses the get method in the background
if (emp.name) {
console.log(emp.name); // Mr. JAMES BOND
}

// uses the setter in the background
emp.name = 'Bond 007';
console.log(emp.name); // Mr. BOND 007

最新版本的瀏覽器也在對(duì)象中實(shí)現(xiàn)了 gettersetter 函數(shù),我們可以使用它們來實(shí)現(xiàn) 計(jì)算屬性,在設(shè)置和獲取一個(gè)屬性之前加上監(jiān)聽器和處理。

var person = {
firstName: 'James',
lastName: 'Bond',
get fullName() {
console.log('Getting FullName');
return this.firstName + ' ' + this.lastName;
},
set fullName (name) {
console.log('Setting FullName');
var words = name.toString().split(' ');
this.firstName = words[0] || '';
this.lastName = words[1] || '';
}
}

person.fullName; // James Bond
person.fullName = 'Bond 007';
person.fullName; // Bond 007

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多