妙用ES6解構和擴展運算符讓你的代碼更優雅

Javascript ES6/ES2015塵埃落定,其中許多特性實際上是爲了簡化代碼。解構運算符,擴展運算符,和rest運算符就是其中很好的特性,它們能夠經過減小賦值語句的使用,或者減小經過下標訪問數組或對象的方式,使代碼更加簡潔優雅,可讀性更佳。如今各瀏覽器及node.js都加快了部署ES6的步伐。ES6的學習正當其時。html

解構

解構的做用是能夠快速取得數組或對象當中的元素或屬性,而無需使用arr[x]或者obj[key]等傳統方式進行賦值node

數組解構賦值:數組

var arr = ['this is a string', 2, 3];

//傳統方式
var a = arr[0],
    b = arr[1],
    c = arr[2];

//解構賦值,是否是簡潔不少?
var [a, b, c] = arr;

console.log(a);//this is a string
console.log(b);//2
console.log(c);//3

嵌套數組解構:瀏覽器

var arr = [[1, 2, [3, 4]], 5, 6];
var [[d, e, [f, g]], h, i] = arr;
console.log(d);//1
console.log(f);//3
console.log(i);//6

函數傳參解構:app

var arr = ['this is a string', 2, 3];

function fn1([a, b, c]) {
    console.log(a);
    console.log(b);
    console.log(c);
}

fn1(arr);
//this is a string
//2
//3

for循環解構:函數

var arr = [[11, 12], [21, 22], [31, 32]];
for (let [a, b] of arr) {
    console.log(a);
    console.log(b);
}
//11
//12
//21
//22
//31
//32

對象賦值解構:學習

var obj = {
    name: 'chris',
    sex: 'male',
    age: 26,
    son: {
        sonname: '大熊',
        sonsex: 'male',
        sonage: 1
    }
};

var {name, sex, age, son} = obj;
console.log(name + ' ' + sex + ' ' + age); //chris male 26
console.log(son); // { sonname: '大熊', sonsex: 'male', sonage: 1 }

對象傳參解構:this

var obj = {
    name: 'chris',
    sex: 'male',
    age: 26,
    son: {
        sonname: '大熊',
        sonsex: 'male',
        sonage: 1
    }
};

function fn2({sex, age, name}) {
    console.log(name + ' ' + sex + ' ' + age);
}

fn2(obj);
//chris male 26

變量名與對象屬性名不一致解構:spa

var obj = {
    name: 'chris',
    sex: 'male',
    age: 26
};
var {name: nickname, age: howold} = obj;
console.log(nickname + ' ' + howold); //chris 26

嵌套對象解構:rest

var obj = {
    name: 'chris',
    sex: 'male',
    age: 26,
    son: {
        sonname: '大熊',
        sonsex: 'male',
        sonage: 1
    }
};
var {name, sex, age, son: {sonname, sonsex, sonage}} = obj;
console.log(sonname + ' ' + sonsex + ' ' + sonage);
//大熊 male 1

//Babel暫不支持這種嵌套解構
obj = {
    name: 'chris',
    sex: 'male',
    age: [1, 2, 3]
}

{name, sex, age: [a, b, c]} = obj;
console.log(c);

嵌套對象屬性重名,解構時須要更改變量名:

var obj = {
    name: 'chris',
    sex: 'male',
    age: 26,
    son: {
        name: '大熊',
        sex: 'male',
        age: 1
    }
};
//賦值解構
var {name: fathername, son: {name, sex, age}} = obj;
console.log(fathername); //chris
console.log(name); //大熊

//傳參解構
function fn3({sex, age, name, son: {name: sonname}}) {
    console.log(name + ' ' + sex + ' ' + age + ' ' + sonname);
}

fn3(obj);
//chris male 26 大熊

循環解構對象:

var arr = [{name: 'chris', age: 26}, {name: 'jack',    age: 27}, {name: 'peter',age: 28}];

for (let {age, name} of arr) {
    console.log(name + ' ' + age);
}
//chris 26
//jack 27
//peter 28

解構的特殊應用場景:

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

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

 

擴展運算符

擴展運算符用三個點號表示,功能是把數組或類數組對象展開成一系列用逗號隔開的值

var foo = function(a, b, c) {
    console.log(a);
    console.log(b);
    console.log(c);
}

var arr = [1, 2, 3];

//傳統寫法
foo(arr[0], arr[1], arr[2]);
//使用擴展運算符 foo(...arr); //1 //2 //3

特殊應用場景:

//數組深拷貝
var arr2 = arr;
var arr3 = [...arr];
console.log(arr===arr2); //true, 說明arr和arr2指向同一個數組
console.log(arr===arr3); //false, 說明arr3和arr指向不一樣數組

//把一個數組插入另外一個數組字面量
var arr4 = [...arr, 4, 5, 6];
console.log(arr4);//[1, 2, 3, 4, 5, 6]

//字符串轉數組
var str = 'love';
var arr5 = [...str];
console.log(arr5);//[ 'l', 'o', 'v', 'e' ]

 

rest運算符

rest運算符也是三個點號,不過其功能與擴展運算符剛好相反,把逗號隔開的值序列組合成一個數組

//主要用於不定參數,因此ES6開始能夠再也不使用arguments對象
var bar = function(...args) {
    for (let el of args) {
        console.log(el);
    }
}

bar(1, 2, 3, 4);
//1
//2
//3
//4

bar = function(a, ...args) {
    console.log(a);
    console.log(args);
}

bar(1, 2, 3, 4);
//1
//[ 2, 3, 4 ]

rest運算符配合解構使用:

var [a, ...rest] = [1, 2, 3, 4];
console.log(a);//1
console.log(rest);//[2, 3, 4]

 

小結:

等號表達式是典型的賦值形式,函數傳參和for循環的變量都是特殊形式的賦值。解構的原理是賦值的兩邊具備相同的結構,就能夠正確取出數組或對象裏面的元素或屬性值,省略了使用下標逐個賦值的麻煩。

對於三個點號,三點放在形參或者等號左邊爲rest運算符; 放在實參或者等號右邊爲spread運算符,或者說,放在被賦值一方爲rest運算符,放在賦值一方爲擴展運算符。

 

一點經驗:

  • 在等號賦值或for循環中,若是須要從數組或對象中取值,儘可能使用解構。
  • 在本身定義函數的時候,若是調用者傳來的是數組或對象,形參儘可能使用解構方式,優先使用對象解構,其次是數組解構。代碼可讀性會很好。
  • 在調用第三方函數的時候,若是該函數接受多個參數,而且你要傳入的實參爲數組,則使用擴展運算符。能夠避免使用下標形式傳入參數。也能夠避免不少人習慣的使用apply方法傳入數組。
  • rest運算符使用場景應該稍少一些,主要是處理不定數量參數,能夠避免arguments對象的使用。

歡迎你們補充或者糾正。

目前node.js (4.1.1)已經支持擴展運算符了,不過運行的時候要加上 --harmony_spreadcalls 參數。還不支持解構賦值,想嚐鮮的話可使用Babel。但願V8/node.js早日支持所有ES6特性,畢竟,ES7很快要來了,哈哈

 

轉載請註明出處:http://www.cnblogs.com/chrischjh/p/4848934.html

相關文章
相關標籤/搜索