ES6小記

ZeroNoob發表於2018-03-22

ES6

ES6 就是ECMAScript 6是新版本JavaScript語言的標準。

1. let 和 const

ES6 新增了 let 和 const 來宣告變數和常量,它們的用法類似var, 但只在程式碼塊中有效。

1.1 let 的基本使用

    {
        var a = 'hello';
        let b = 'world';
    }
    
    a // hello
    b // Uncaught ReferenceError: a is not defined
複製程式碼

上述程式碼表明,let只在他所在的程式碼塊中有效。

1.2 不能重複定義

let不允許在相同作用域內,重複宣告同一個變數。

    let a = 'hello';
    let a = 'world'; // Uncaught SyntaxError: Identifier 'a' has already been declared
    
    function s1(arg){
        let arg;  // Uncaught SyntaxError: Identifier 'arg' has already been declared
    }
複製程式碼

1.3 不存在變數提升

var 命令會存在變數提升的問題,在定義之前使用,值為 undefined。
let 命令改變了這個行為,必須要在宣告後使用,否則報錯。

    console.log(a); // Uncaught ReferenceError: a is not defined
    let a = 'hello world'; 
    
    console.log(b); // 值為 undefined
    var b = 'hello kitty' 
複製程式碼

1.4 臨時鎖區(Temporal Distonrtion Zone)

保證了let 命令不會受到外部影響。

    var a = 123;
    function s1(){
        a = 'hello world';  // Uncaught ReferenceError: a is not defined
        let a = 'hello kitty';
    }
複製程式碼

1.5 const 基本使用

const宣告一個只讀的常量。一旦宣告,常量的值就不能改變。

    const a = 'hello world!';
    console.log(a) // hello world!
    
    a = 'hello kitty'; // Uncaught SyntaxError: Identifier 'a' has already been declared
複製程式碼

const實際上並不是保證變數的值不能變,而是變數指向的那個記憶體地址不得改動。

    const arr = [];
    arr[0] = 'hello';
    arr[1] = 'world';
    console.log(arr); // ["hello", "world"]
    
    arr = []; // Uncaught SyntaxError: Identifier 'arr' has already been declared
    
    const json = {};
    json.name = 'LiMing';
    console.log(json.name)  // LiMing
    
    json = {} Uncaught SyntaxError: Identifier 'json' has already been declared
複製程式碼

常量 arr, json 儲存的是一個地址,只是保證了地址不可變,但陣列和物件本身是可變的,所以依然可以為其新增新屬性。

2 解構

2.1 陣列解構賦值

    var name = 'LiMing';
    var age = 12;
    // ES5 變數賦值
    
    let [name, age] = ['LiMing', 12];
    // 解構賦值
複製程式碼

以前為變數賦值,只能直接指定值。ES6中可以按照一定模式,從陣列和物件中提取值,對變數進行賦值,這被稱為解構。

    let a = ['LiMing', 12];
    let [name, age] = a;
    console.log(name, age) // LiMing 12
    
    let [,,b] = ['hello', 'world', 'hello kitty'];
    console.log(b) // hello kitty
    
    let [one, , two] = [1, 2, 3];
    console.log(one, two) // 1 3
    
    let [s1, ...s2] = [1, 2, 3, 4, 5];
    console.log(s1, s2)  // 1  [2, 3, 4, 5]
    
    let b = [];
    console.log(b) // undefined
    
    let [a1, a2 ,a3] = [1];
    console.log(a1, a2)  // 1 undefined
複製程式碼

如果解構不成功,變數的值就等於undefined。
如果右邊的資料不是陣列將會報錯。

    let [a] = true; // TypeError: true is not iterable
    
    let [a] = NaN; // TypeError: NaN is not iterable
    
    let [a] = 1; // TypeError: 1 is not iterable
    
    let [a] = null; // TypeError: null is not iterable
    
    let [a] = undefined; // TypeError: undefined is not iterable
    
    let [a] = {}; // TypeError: {} is not iterable
複製程式碼

2.2 預設值

解構允許指定預設值

    let [a = 'hello'] = [];
    console.log(a) // hello 
複製程式碼

ES6內部嚴格使用 === 來判斷是否有值,所以只有當一個陣列成員嚴格等於undefined,預設值才會生效。

    let [a = 'hello world'] = [undefined];
    console.log(a) // hello world
    
    let [a = 'hello world'] = [null];
    let [b = 'hello kitty'] = [''];
    console.log(a, b)  // null '' 
複製程式碼

2.3 物件解構

解構當然也可以用於物件

    let {name, age} = {name: 'LiMing', age: 12}
    console.log(name, age)  // LiMing 12
複製程式碼

物件解構與陣列解構不同。 陣列是有順序的,變數值有位置決定,而物件是無序的,所以變數名必須為物件的屬性名

    let json = {name: 'zero'}
    let {name} = json
    let {a} = json
    console.log(name, a) // zero undefined
複製程式碼

如果變數名與屬性名不一致,則需要:

    let {a: name} = {name: 'zero'}
    console.log(a)  // zero
複製程式碼

2.4 函式引數解構

函式的引數當然也可以解構

    function s1([a, b]){
        return a + b
    }
    console.log(s1([1, 5])) // 6
    
    
    function add({a = 0, b = 0} = {}) {
      return a + b;
    }
    add({a: 3, b: 8}); // 11
    add({a: 3}); // 3
    add({}); // 0
    add(); // 0
複製程式碼