JavaScript ES6相關的一些知識(/let、const/箭頭函數/Promise/generate)

ES6是個啥

ECMAScript是國際經過的標準化腳本語言
JavaScript由ES,BOM,DOM組成
ES是JavaScript的語言規範,同時JavaScript是ES的實現和擴展
6就是JavaScript語言的下一代標準segmentfault

關於ES6的一些知識

1.let、const

ES5中的做用域有:函數做用域,全局做用域
ES6新增了塊級做用域。由{}包括(if和for語句也屬於塊級做用域)數組

{
    var a = 1;
    let b = 2;
    
}
console.log(a)//1
console.log(b)//undefined

let、const、var的區別
var:能夠跨塊級做用域訪問,不能跨函數做用域訪問
let:只能在塊級做用域訪問,不能跨函數使用
const:定義常量,必須初始化且不能修改,只能在塊級做用域內使用
關於變量提高:var不論聲明在何處都會莫默認提高到函數/全局最頂部,可是let和const不會進行變量提高promise

2.arrow function 箭頭函數

箭頭函數至關於匿名函數,簡化了函數的定義
定義就用=> 一個箭頭瀏覽器

箭頭函數有兩種格式:
第一種:只包含一個表達式多線程

x=>x++

至關於dom

function(x)}{
    return x++;
}

第二種:包含多條語句:異步

//包含判斷等
x=>{
    if(x>0){
        return x++;
    }
    else{
        x--;
    }
}
//多個參數
(x,y,z....)=>x+y+z+...+
//無參數
()=>1

//返回對象
x=>({obj:x})//注意符號,避免和函數體的{}衝突

使用箭頭函數時,函數體內的this對象,就是定義時所在的對象函數

3.Promise

定義:Promise對象用於異步操做,它表示一個還沒有完成且預計在將來完成的異步操做oop

關於同步&異步
JavaScript是基於事件驅動的單線程運行機制
(why: 瀏覽器中至少有三個線程:js引擎線程,gui渲染線程,瀏覽器事件觸發線程
js操做dom,瀏覽器事件觸發都會影響gui渲染效果,所以他們之間存在互斥的關係,使用多線程會帶來很是複雜的同步問題(a線程在某個DOM節點添加內容。b線程刪除了該節點)
同步:
即單線程模式,全部的任務都在主線程上執行,造成一個執行棧*,如函數調用後須要等待函數執行結束後才能進行下一個任務,若是某個任務執行時間過長(如死循環),容易形成線程阻塞,影響下面任務的正常進行
異步:
能夠一塊兒執行多個任務,函數調用後不會馬上就返回執行結果,異步任務會在當前腳本全部的同步任務執行結束後再執行。異步任務不進入主線程,而是進入任務隊列,在某個任務能夠執行時,等待主線程讀取任務隊列,隨後該任務將進入主線程執行
異步任務的實現,最經典的就是setTimeout()/setInterval()
他們的內部運行機制徹底同樣,前者指定的代碼只執行一次,後者爲反覆執行ui

setTimeout(function(){
    console.log("taskA,yibu");
},0)

console.log("taskB,tongbu");
//taskB,tongbu
//taskA,yibu

即便延時事件爲0,但因爲它屬於異步任務,仍須要等待同步任務執行結束後再執行

綜合看,總體的執行順序爲:先執行執行棧中的內容,執行完畢後,讀取任務隊列,尋找對應的異步任務,結束等待狀態,進入執行棧執行,不斷循環(Event Loop)
只要主線程空了,就會去讀取任務隊列

關於回調函數,callback()
回調函數便是會被主線程掛起的代碼
異步任務必須指定回調函數,當主線程開始讀取任務隊列,執行異步任務的時候,執行的就是對應的回調函數


言歸正傳,繼續理解Promise

promise的三種狀態:

  1. pending:初始狀態
  2. fulfilled:操做成功
  3. rejected:操做失敗

Promise能夠由1->2/1->3一旦狀態變化,便會一直保持這個狀態,再也不改變。
當狀態改變Promise.then綁定的函數就會被調用

構建Promise

var promise = new Promise(function(resolve,reject){
    if(/*操做成功*/)
        resolve(data);
    else
        reject(error);
});

異步操做成功調用resolve,將結果做爲參數傳遞出去
異步操做失敗調用reject,將報出的錯誤做爲參數傳遞出去

Promise構建完成後,使用then方法指定resolve狀態和reject狀態的回調函數
promise.then(成功回調函數,失敗的回調函數(非必要))
//這兩個函數都接受promise傳出的值做爲參數

promise.then(function(data){do xxxx for success},function(error){do xxxx for failure});

Promise新建後就執行,then方法指定的回調函數會在當前腳本的全部同步任務執行結束後再執行

例子:

var promise = new Promise(function(resolve, reject) {
  console.log('before resolved');
  resolve();
  console.log('after resolved');
});

promise.then(function() {
  console.log('resolved');
});

console.log('outer');

//before resolved
//after resolved
//outer
//resolved

Promise的優點在於,能夠在then方法中繼續寫Promise對象並返回,而後繼續調用then來進行回調操做。可以簡化層層回調的寫法。
Promise的精髓在於,用維護狀態、傳遞狀態的方式使得回調函數可以及時調用,比傳遞callback要簡單、靈活

Promise的其餘方法

.catch()

用於指定發生錯誤時的回調函數,等同於reject部分
和reject的區別:
promise.then(onFulfilled,onRejected)在onFulfilled發生異常,在onRejected中捕獲不到
promise.then(onFulfilled).catch(onRejected)可以捕獲異常。也能夠用then替換,只是寫法不一樣。本質上沒有區別

.all()

用於將多個Promise實例包裝成一個新的Promise實例

var p = Promise.all([p1, p2, p3]);

p1p2p3都需爲promise實例
當p1p2p3都爲fulfilled時,p纔會變爲fulfilled
只要有一個變爲rejected,p就會變成rejected

.race()

用於將多個Promise實例包裝成一個新的Promise實例
與all()的區別相似於 AND 和 OR
p1p2p3有一個狀態發生改變,p的狀態就發生改變,並返回第一個改變狀態的promsie返回值,傳遞給p

.resolve()

看做new Promise()的快捷方式
實例:

Promise.resolve('Success');

/*******等同於*******/
new Promise(function (resolve) {
    resolve('Success');
});

讓對象馬上進入resolved狀態

4.generate

能夠將generate理解爲一個可以屢次返回的「函數」

function* foo(x){
    yield x++;
    yield x+2;
    yield x+3;
    return x*x;
}

function*定義,而且yield也能夠返回數據


調用generate的方法:
不斷的使用next()

var f = foo(0);
console.log(f.next());// 0 false
console.log(f.next());// 3 false
console.log(f.next());// 4 false
console.log(f.next());// 1 true

使用for of結構

for (var x of foo(0)) {
    console.log(x); // 依次輸出0 3 4 (沒有輸出1緣由不詳)
}

每執行一次後就暫停,返回的值就是yield的返回值,每次返回一個值,直到done爲true,這個generate對象已經所有執行完畢
generate更像一個可以記住執行狀態的函數

實際上generate不算是一個函數,它的返回值不是變量也不是函數,而是一個可迭代的對象
該對象相似一個元素被定義好的數組,保存的是一種規則而不元素自己,不可以隨機訪問,遍歷也只可以遍歷一次,由於規則只保存了上次的狀態

參考文檔1:講解JavaScript的線程運做

參考文檔2:講解Promise

參考文檔3:關於generate

相關文章
相關標籤/搜索