es6基礎系列三:解構賦值

解構就是ES6容許按照必定模式,從數組和對象中提取值,對變量進行賦值(只能用於數組,對象或迭代器)。若是解構不成功,則等於undefined,但不能賦值爲undefined和null,由於undefined和null不屬於數組或對象數組

1 數組的解構賦值

數組的解構賦值就是,按照數組元素的次序,取出它位置所對應的值,具體以下函數

var [a, b, c] = [1, 2, 3]; // a=1;b=2;c=3 至關於var a=1, b=2, c=3;
// 也能夠用於let,const聲明變量
let [x, y] = [4, 5] // x=4, y=5
// 位置對應
var [, , c] = [1, 2, 3]; // c=3
var [a, b, c] = [, 2,]; // a=undefined; b=2; c=undefined
// 嵌套數組 位置對應
var [a, [[b], c]] = [1, [[2], 3]]; // a=1; b=2; c=3
// ...表示剩下的全部值組成數組
var [a, ...b] = [1, 2, 3, 4];// a=1; b=[2,3,4];
var [a, ...b, c] = [1, 2, 3, 4]; //報錯 Uncaught SyntaxError: Rest element must be last element in array
var [a, ...b] = [1]; // a=1; b=[];

解構只能用於數組,對象或迭代器,重要的事再重複一遍
固然,解構賦值也容許指定默認值code

var [a=1] = []; // a=1
var [a, b=2] = [1]; // a=1, b=2
var [a, b=2] = [1, undefined]; // a=1; b=2
var [a, b=2] = [1, null]; // a=1; b=null;

思考一下,下面輸出的結果,let聲明時爲何報錯對象

var [x=y,y=1]=[]; // x=undefined; y=1
let [x=y,y=1]=[]; // 報錯 Uncaught ReferenceError: y is not defined

2 對象的解構賦值

上面提到了,數組的解構賦值是按照元素的位置來取值的,而對象的解構賦值是按照屬性名來取值的
具體請看下面的例子token

// 屬性名和變量名一致
var {a, b} = {a:"aa", b:"bb"}; // a="aa"; b="bb"
var {a, b} = {b:"bb"}; // a=undefined; b="bb" 變量名a由於找不到屬性名a的值
// 屬性名與變量名不一致
var {a:c, b:d} = {a: "aa", b:"bb", c:"cc", d:"dd"}; //c="aa"; d="bb" 屬性名爲a,變量名爲c
//對象嵌套數組
var o = {
    p: ["hello", {y: "world"}]
};
// 也支持let和const
let {p:[x, {y}]} = o;// x="hello"; y="world"; 注意:p爲屬性名而不是變量名
// 對象嵌套對象
var o = {
    p: {
        q: {
            x: "hello",
            y: "world"
        }
    }
};
var {p:{q:{x, y}}} = o; // x="hello"; y="world"; 注意p,q爲屬性名而不是變量名

爲已經聲明的變量進行解構賦值,必須把整個表達式用小括號包裹,不然會報錯,報錯緣由就是由於JavaScript語法通知解析引擎將任何以{開始的語句解析爲一個塊語句(例如,{console}是一個合法塊語句)ip

var x;
{x} = {x:1}; // 報錯 Uncaught SyntaxError: Unexpected token =
({x} = {x:1}); // x=1

let obj = {};
let arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true }); // obj={prop: 123}; arr=[true]; 注意區別屬性名和變量名,foo,bar是屬性名 obj.prop,arr[0]是變量名

3 解構賦值的用途

變換變量的值element

var a = 1;
var b = 2;
[a, b] = [b, a]; // a=2; b=1;

函數取值io

function func1(){
    return [1, 2, 3];
}
var [a, b, c] = func1(); // a=1;b=2;c=3;
function func2(){
    return {
        a: "a",
        b: "b"
    }
}
var {a, b} = func2(); // a="a";b="b"

函數參數的定義及設置默認值console

function func3({x, y, z}){
    console.log(x+' '+y+' '+z);
}
func3({x:"x",y:"y",z:"z"});//x y z
function func4({x=1, y=2, z=3}){
    console.log(x+' '+y+' '+z);
}
func4({});// 1 2 3

遍歷Map結構ast

var map = new Map();
map.set('x','xx');
map.set('y','yy');
//獲取鍵名和鍵值
for(let [key, value] of map){
    console.log('key='+key+' value='+value);
    //key=x value=xx
    //key=y value=yy
}

//獲取鍵名
for(let[key] of map){
    console.log("key="+key);
    // key=x  
    // key=y
}

// 獲取鍵值
for(let[, value] of map){
    console.log("value="+value);
    // value=xx
    // value=yy
}

4 思考題

爲何func5和func6的結果不同,請注意爲變量賦值和爲函數的參數指定默認值

function func5({x=0, y=0}={}){
    console.log([x,y]);
}
func5({x:3, y:8}); // [3, 8]
func5({x:3}); // [3, 0]
func5({}); // [0, 0]
func5(); // [0, 0]

function func6({ x, y } = { x: 0, y: 0 }){
    console.log([x, y]);
}
func6({x:3, y:8}); // [3, 8];
func6({x:3}); // [3, undefined]
func6({}); // [undefined, undefined]
func6(); // [0, 0]
相關文章
相關標籤/搜索