ES6簡單瞭解

ES6初步學習


let和const

let

用來聲明變量,可是所聲明的變量只在let命令所在的代碼塊內有效javascript

let不像var那樣會發生變量提高,因此必定要先聲明後使用。java

console.log(foo); //undefined
console.log(bar); //報錯ReferenceError
var foo = 2;
let bar = 3;

塊級做用域

ES6明確容許在塊級做用域中聲明函數。可是儘可能避免在塊級做用域內聲明函數,若是須要也要寫成函數表達式,而不是函數聲明語句。數組

在ES6中,塊級做用域之中,函數聲明的語句的行爲相似let,在塊級做用域以外不能被引用。瀏覽器

  • let實際上爲javascript新增了塊級做用域數據結構

  • 外層做用域沒法讀取內層做用域的變量閉包

  • 內層做用域能夠定義外層做用域的同名變量異步

  • 塊級做用域實際上使得普遍運用的當即執行函數變得再也不必要了。函數

function f1() {
    let n =5;
    if(rue) {let n = 10;}
    console.log(n); //5,注意只能在f1這個做用域使用
}

javascript沒有塊級做用域,可是用let聲明的變量能夠綁定到所在的任意做用域中,換句話說let爲其聲明的變量隱式的劫持了所在的塊做用域{...}學習

var foo = true;
if(foo) {
    let bar = foo * 2;
    bar = something(bar);
    console.log(bar); //bar只在foo做用域中有效
}
console.log(bar); //ReferenceError

不太明顯的「死區」

有興趣的能夠自行搜索瞭解一下TDZ(暫存死區),記得當時仍是看到阮大神的微博知道的~~指針

function bar(x = y; y = 2) {
    return [x, y];
}

bar(); //報錯,此時至關於y未聲明的狀況下

let不容許在相同做用域內重複聲明同一個變量,不能在函數內部從新聲明參數。const也是這樣。

function(arg) {let arg; //報錯}

const

const一樣能夠建立塊做用域變量,一樣只在聲明所在的塊級做用域中有效。但其值是固定的,不可更改,只讀。

一旦聲明變量,就必須當即初始化,不能留到之後賦值。

//只聲明不賦值就會報錯
const foo; //SyntaxError:

const聲明的變量也是不提高,一樣存在暫時性死區,只能在聲明的位置後面使用。

if(true) {
    console.log(MAX); //ReferenceError
    const MAX = 5;
}

對於複合類型的變量,變量名不指向數據,而是指向數據所在的地址。const只保證變量名指向的地址不變,不保證該地址的數據保持不變。不能把foo指向另外一個地址。

const foo = {};
foo.prop = 123;
foo.prop; //123
foo = {}; //TypeError:"foo" is read-only

頂層對象的屬性

瀏覽器環境指的是window對象 Node中指的是global對象

ES6中,var命令和function命令聲明的全局變量依舊是頂層對象的屬性,可是let和const以及class聲明的全局變量不屬於頂層對象的屬性。

var a = 1; 
window.a; //1

let b = 1;
window.b; //undefined

異常

嚴格模式下LHS查詢失敗時,並不會建立並返回一個全局變量,引擎會拋出同RHS查詢失敗時相似的ReferenceError異常

若是RHS查詢到一個變量,嘗試對這個變量的值進行不合理的操做時,好比對一個非函數類型的值進行函數調用,或者引用null或undefined類型的值中的屬性,引擎會拋出另一中的異常TypeError

ReferenceError同做用域的判別失敗有關,TypeError則表示做用域判別成功了,可是對結果的操做是非法的或者不合理的。

查找的目的是對變量進行賦值,那麼就會使用LHS查詢,若是目的是獲取變量的值,那麼就會使用RHS查詢。

var a = 2這樣的會被分解兩個步驟:(1)var a 會在做用域中聲明新變量,代碼執行前進行(2)a = 2 會查詢(LHS)變量a並對其進行賦值。

閉包

  • 循環和閉包

每次迭代都生成一個新的做用域,使得延遲函數的回調能夠將新的做用域封閉在每一個迭代內部。

for(var i = 0; i <= 5; i++) {
    (functiong(j) {
        setTimeout(function timer() {
            console.log(a);
        }, 1000);
    })(i);
}

var的循環,每一次循環都是新的i值覆蓋舊的i值,只有一個i,因此只輸出最後一個。

let的循環 每次循環都是一個新的變量i,多個i,因此會每一個都輸出,每次迭代都進行從新綁定,與閉包有關

Generator函數

異步
最大的特色就是能夠交出函數的執行權(即暫停執行)
函數名以前加星號.yield表示執行到此處,執行權將交給其餘協程。

function* gen(x) {
    var y = yield x + 2;
    return y;
}

var g = gen(1);
g.next() //{value:3,done:false}
//value是yield語句後面表達式的值,表示當前階段的值,done表示函數是否執行完畢,是否還有下一個階段。
g.next() //{value:undefined,done:true}

調用generator函數會返回一個內部指針g,執行它不會返回結果返回的是指針對象。調用指針的g的next方法,會移動內部指針,指向第一個遇到的yield語句即x+2處。

Set數據結構

相似於數組可是成員的值都是惟一的,沒有重複的值。

var s = new Set([1,2,3,4,4]);
[...s] //[1,2,3,4]

Set實例的方法
操做方法和遍歷方法

操做數據

(1) 操做方法

  • add:添加某個值,放回set結構自己

  • delete:刪除某個值返回一個布爾值,表示刪除是否成功

  • has(value):返回一個布爾值,表示該值是否爲set的成員

  • clear:清除全部成員,沒有返回值

s.add(2).add(3).add(2);
s.size //2
s.has(1) //false
s.has(2) //true
s.has(3) //true
s.delete(2);
s.has(2) //false

(2) Array.from方法能夠將set數據結構轉爲數組

var items = new Set([1,2,3,4,5]);
var array = Array.from(items);

(3) 擴展運算符...也能夠將某些數據結構轉換一個數組

function foo() {
    var args = [...arguments];
}

[...document.querySelectorAll("div")]

(4)數組去重的另外一種方法

function dedupe(array) {
    return Array.from(new Set(array));
}
dedupe([1,1,2,3]) //[1,2,3]

遍歷操做

  • keys:返回鍵名的遍歷器

  • values:返回鍵值的遍歷器

  • entries:返回鍵值對的遍歷器

  • forEach:使用回掉函數遍歷每一個成員

附錄(易錯點):

  • 隱式的強制轉換

3 + true; //4
NaN !== NaN; //true
Null == undefined; //true
  • 浮點數

0.1 + 0.2; //0.300000004
(8).toString(2); //"1000"
parseInt("1001", 2); //9
  • 數據類型

typeof null; //"object"

typeof "hello"; //"string"

var s = new String("hello");
typeof s; //"object"

var s1 = new String("hello");
var s2 = new String("hello");
s1 === s2; //false
s1 == s2; //false

NaN !==NaN
相關文章
相關標籤/搜索