javascript ES6 新特性之 解構

豐寸發表於2019-05-09

 解構的作用是可以快速取得陣列或物件當中的元素或屬性,而無需使用arr[x]或者obj[key]等傳統方式進行賦值

var arr = [1, 2, 3];

//傳統方式
var a = arr[0], b = arr[1], c = arr[2];
console.log(a, b, c); // 1 2 3

//解構方式
var [a, b, c] = arr;
console.log(a, b, c); // 1 2 3

從上面的例子我們可以看出,要想獲取一個陣列中的值,我們可以利用傳統的索引的方式,也可以宣告一個陣列變數來獲取,第二種方式看起來更優雅。

如果上面的方法看起來我們的傳統方法還過得去的話看下面的例子:

var arr = [1, [2, [3]]];

// 傳統方法
var a = arr[0], b = arr[1][0], c = arr[1][1][0];
console.log(a, b, c);// 1 2 3

// 解構方法
var [a, [b, [c]]] = arr;
console.log(a, b, c);// 1 2 3

多層陣列巢狀的話我們就可以看出解構的強大之處了。再看下面的例子:

var arr = [1, 2, 3];

// 傳統方式
function bar(a, b, c) {
    console.log(a, b, c);
}
bar(arr[0], arr[1], arr[2]); // 1 2 3

// 解構方式
function baz([a, b, c]) {
    console.log(a, b, c);
}
baz(arr); // 1 2 3

我們將一個陣列傳值應用到實際的應用中,可以是程式碼看起來更加簡潔優雅,在多層陣列中更能體現出來,如下:

var arr = [[1, 2], [3, 4], [5, 6]];

// 傳統方法
for (var a of arr) {
    // 第一種
    console.log(a[0], a[1]); // 1 2 3 4 5 6
    // 第二種
    for (var b of a) {
        console.log(b) // 1 2 3 4 5 6
    }
}

// 解構方法
for (var [a, b] of arr) {
    console.log(a, b); // 1 2 3 4 5 6
}

我們要分別獲取 arr 陣列中的值,如果不去下標索引的話傳統方式需要兩層迴圈才能獲取,如果用解構的話只需要迴圈一次,從而加快了執行速度。如果陣列巢狀層數更多的話效果更明顯。

 

物件賦值解構:

var obj = {
    name: 'zhangsan',
    sex: 0,
    age: 26,
    son: {
        sonname: 'lisi',
        sonsex: 1,
        sonage: 2
    }
};

var {name, sex, age, son} = obj;
console.log(name, sex, age); //zhangsan 0 26
console.log(son); // { sonname: 'lisi', sonsex: 1, sonage: 2 }

var {name, sex, age, son:{sonname,sonsex,sonage}} = obj;
console.log(name,sex,age,sonname,sonsex,sonage); // zhangsan 0 26 lisi 1 2

但是如果物件的子物件中又重名的就需要在解構時重新命名,如下:

var obj = {
    name: 'zhangsan',
    sex: 0,
    age: 26,
    son: {
        name: 'lisi',
        sex: 1,
        age: 2
    }
};

var {name, sex, age, son} = obj;
console.log(name, sex, age); //zhangsan 0 26
console.log(son); // { name: 'lisi', sex: 1, age: 2 }

var {name, sex, age, son: {name, sex, age}} = obj;
console.log(name, sex, age, name, sex, age); // lisi 1 2 lisi 1 2

var {name, sex, age, son: {name: sonname, sex: sonsex, age: sonage}} = obj;
console.log(name, sex, age, sonname, sonsex, sonage); // zhangsan 0 26 lisi 1 2

如果物件的子物件中有和父物件重名的變數名稱,則會將父物件的變數值覆蓋,重新命名子物件的變數則不會,重新命名規則為 (原變數名:新變數名)。

同樣的我們也可以將物件解構應用到函式傳參中,如下:

var obj = {
    name: 'zhangsan',
    sex: 0,
    age: 26,
    son: {
        name: 'lisi',
        sex: 1,
        age: 2
    }
};

// 傳統方法
function foo(name,sex,age,son) {
    console.log(name,sex,age,son)
}
foo(obj.name,obj.sex,obj.age,obj.son); // zhangsan 0 26 { name: 'lisi', sex: 1, age: 2 }

// 解構方法
function foo({name,sex,age,son}) {
    console.log(name,sex,age,son)
}
foo(obj); // zhangsan 0 26 { name: 'lisi', sex: 1, age: 2 }

// 解構方法 子物件也進行解構,但是子物件中含有和父物件相同的變數名,不重新命名會報錯
function foo({name, sex, age, son: {name, sex, age}}) {
    console.log(name, sex, age, name, sex, age);  // SyntaxError: Duplicate parameter name not allowed in this context
}
foo(obj);  // SyntaxError: Duplicate parameter name not allowed in this context

// 解構方法 子物件也進行解構,但是子物件中含有和父物件相同的變數名,將子物件重新命名
function foo({name, sex, age, son: {name: sonname, sex: sonsex, age: sonage}}) {
    console.log(name, sex, age, sonname, sonsex, sonage);
}

foo(obj); // zhangsan 0 26 lisi 1 2

在上述方法中如果子物件也進行解構,子物件中有和父物件相同的變數名,則需要將子物件中和父物件相同的變數名進行重新命名,當然也可以重新命名父物件。只要沒有相同的變數名即可。

解構也可以將陣列與物件組合起來使用,如下迴圈結構:

var arr = [{name: 'aaa', age: 26}, {name: 'bbb', age: 27}, {name: 'ccc', age: 28}];

for (var {age, name} of arr) {
    console.log(name, age);
}
//aaa 26
//bbb 27
//ccc 28

解構的特殊應用場景:

//變數互換
var x = 1, y = 2;
var [x, y] = [y, x];
console.log(x, y); // 2 1

//字串解構
var str = 'hello';
var [a, b, c, d, e] = str;
console.log(a, b, c, d, e); // h e l l o

 

相關文章