一:Symbol
1.1 基本使用
簡單的説,Symbol就是一個絕對唯一的key值,類似之前obj['key']='value'這種操作的字符串'key',好處是絕對不會重複,避免覆蓋之前的值。
Symbol是一個方法,會返回一個唯一的symbol,可以帶參數,比如:var sy=Symbol('sy-name'),不過這只是為了方便查看,加不加目前沒有區別。
var sy1=Symbol(),sy2=Symbol();
console.log(sy1===sy2);//false
var obj={[sy1]:'這是數據一'};
obj[sy2]='這是數據二';
console.log(obj);//{Symbol(): "這是數據一", Symbol(): "這是數據二"}
1.2 有用的方法
-
Symbol.for():接受一個字符串作為參數,然後在全局搜索有沒有以改字符串作為名稱的Symbol值,如果有就返回,沒有就新建一個返回。 注意:只有該方法建立的Symbol會登記在全局,Symbol()方法建立的不會登記在全局
var sy1 = Symbol.for(),sy2 = Symbol.for();
console.log(sy1 === sy2);//true
var sy3 = Symbol.for('info1'),sy4 = Symbol.for('info1');
console.log(sy3 === sy4);//true
var sy5=Symbol('info2'),sy6 = Symbol.for('info2');
console.log(sy3 === sy6);//false
console.log(sy5 === sy6);//false
* Symbol.keyFor()
該方法是配合上面的方法來使用的,接受一個Symbol作為參數,會在全局搜索該Symbol對象,返回該對象名稱,如果沒有就返回undefined。
二:Generator函數
-----------------------------------------------------------------------------------------------------------------------------------------
### 2.1 基本使用
定義函數名稱時帶一個*的函數就是Generator函數,內部的yield語句是特色,該函數的使用可以用下面的幾條概括一下:
* 調用Generator函數並不會立刻return結果,而是在遇到第一個yield語句前停止下來,返回一個指針(姑且這樣稱呼);
* 以後每次調用yield時候(具體看下面例子,直到遇到yield或return時停止繼續執行),會返回yield數據,有點類似return;
* 返回的數據格式從下面的例子應該就明白了,沒有yield或return語句會發生什麼應該也明白了。
function *firstYieldFun(){
yield '你好';
yield '2007';
return 'name:';
}
var fun=firstYieldFun();
console.log(fun.next());//{value: "你好", done: false}
console.log(fun.next());//{value: "2007", done: false}
console.log(fun.next());//{value: "name:", done: true}
console.log(fun.next());//{value: undefined, done: true}
console.log(fun.next());//{value: undefined, done: true}
簡單的説,Generator函數就是一個分段執行的函數,走走停停,yield用來切割代碼成一段段的,next()方法用來啓動執行下一段這個行為。
forEach方法的參數是一個普通函數,Generator函數不可以作為參數。
### 2.2 重要的説明
* yield特殊使用
除了上面的例子yield單獨成為一個語句,其還可以用於表達式,函數參數和賦值表達式的右邊等。
需要注意的是,yield要明確歸屬,用小括號包裹,小括號不是必須的,是在歸屬關係不明確的時候才是必須的,例如:```console.log('My name is : '+(yield '你好2007'))```;
* next()方法帶參數時
yield本身不會返回值,或者説是undefined,不過next()方法如果帶參數情況就不一樣了,此時就會返回yield帶的參數,如下例子説明:
function* secondYieldFun() {
console.log(yield '你好2007');
}
var fun = secondYieldFun();
console.log(fun.next()); //{value: "你好2007", done: false}
//這是參數
console.log(fun.next('這是參數')); //{value: undefined, done: true}
三:Promise
-----------------------------------------------------------------------------------------------------------------
### 3.1 基本使用
Promise就是一個對象,有點類似註冊事件的感覺,不過又不一樣,你提前註冊好成功和失敗以後應該走的路徑,然後你自己根據實際情況決定是失敗還是成功,其實和回調沒有本質的區別,就是寫起來好像好看了些,下面的例子很明瞭。
var promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
if (false) {
//Pending --> Resolved
resolve('成功了');
} else {
//Pending --> Rejected
reject('失敗了');
}
}, 5000);
});
promise1.then(function(value) {
console.log('成功:' + value);
}, function(error) {
console.log('失敗:' + error);
});
需要説明一下的是,Promise對象保證着三種狀態:pending、Resolved和Rejected,就是進行中、成功和失敗的意思。
### 3.2 Promise.race()和Promise.all()
將多個Promise實例,包裝成一個新的Promise實例。 下面介紹的二個方法的參數如果不是對象的實例,就會先調用Promise.resolve方法變成對象的實例再傳遞進去。
let pro=Promise.race(Promise對象的實例1, Promise對象的實例2 [,Promise對象的實例N])
只要promise對象的實例中有一個率先改變,率先改變的那個的返回狀態就會作為pro的狀態返回,餘下的會繼續執行完畢但不會改變狀態了。
let pro=Promise.all(Promise對象的實例1, Promise對象的實例2 [,Promise對象的實例N])
結果只有二種情況:
* 全部成功時,會等待全部執行結束,返回成功;
* 存在至少一個失敗時,會在遇見第一個失敗時候返回失敗,餘下的會繼續執行完畢但不會改變狀態了。
var pro1 = new Promise((resolve, reject) => setTimeout(() => resolve('第一條'), 3000));
var pro2 = new Promise((resolve, reject) => setTimeout(() => resolve('第二條'), 1000));
var proAll = Promise.all([pro1, pro2]);
proAll.then(val => console.log(val)); // ["第一條", "第二條"]