JavaScript 新舊替換二:賦值和取值

引子

在取值或賦值的時候,常常會聲明一個臨時中間變量,新的語法能夠省去這步。下面主要是關於 Object 和 Array 的賦值和取值新的方式。javascript

這是繼 JavaScript 新舊替換一:變量聲明的第二篇。java

ES5 方式

Object

Object 類型通常能夠這樣賦值:git

var boy = { name: "Jack",age: 18 };
// 或者這樣
var girl = {};
girl.name = "Rose";
girl.age = 18;

Object 類型通常能夠這樣取值:es6

var boy = { name: "Jack",age: 18 };
var name = boy.name;
var age = boy['age'];

Array

Array 類型通常能夠這樣賦值:github

var colors = new Array("red", "blue", "green");
// 或者這樣
var fruit = ['apple','banana','peach'];
// 或者這樣
var flower = [];
flower[0] = 'rose';
flower[1] = 'carnation';
flower[2] = 'tulip';

Array 類型通常能夠這樣取值:數組

var colors = new Array("red", "blue", "green");
var color1 = colors[0];

ES2015+ 方式

在 ES2015 中引入了一個新的語法特性,名爲解構(destructuring)。它能夠從對象或數組中提取值,而後對變量進行賦值。簡化了取值和賦值的代碼。看下面的例子。app

ES5 方式:ui

function getPersonInfo () {
  return { name: 'Jack',age: 18 };
}
var message = getPersonInfo();
var personName = message.name,personAge = message.age;
console.info(personName,personAge); // Jack 18

使用解構:設計

function getPersonInfo () {
  return { name: 'Jack',age: 18 };
}
let { name:name,age:age } = getPersonInfo();
console.info(name,age); // Jack 18

Object

在上面的例子中,若是使用的變量名跟對象中的屬性名同樣,能夠寫的更加簡潔:code

let { name,age } = getPersonInfo();
console.info(name,age); // Jack 18

對比簡化以前的形式,是略去了 name: 仍是略去了 :name?其實是略去 name: 部分。若是想要賦給非同名變量,能夠這樣作:

let { name:personName,age:personAge } = getPersonInfo();
console.info(personName,personAge); // Jack 18

關於這種形式,須要關注這個細節。至於緣由,先來思考一下通常對象字面值:

var x = 10,y = 20;
var o = { a:x,b:y };
console.info(o.a,o.b); // 10 20

對於 { a:x,b:y },咱們知道 a 是對象屬性,x 是要賦給 a 的值。這種語法模式跟賦值符 = 的模式同樣:target = source,咱們能夠很直觀的理解這一點。在使用解構的時候:

let { name:personName,age:personAge } = getPersonInfo();

name:personNamename 表示屬性的源值,personName 是要賦值的目標變量。能夠發現,對象字面值是 target <-- source,而對象解構賦值是 source --> target。注意到這個反轉,對解構語法的理解頗有幫助。

還能夠像下面這樣對比的觀察:

let m = 10,n = 20;
let o = { a:m,b:n };
let     { a:M,b:N } = o;

前面說解構是略去了 a: 這部分,把上面代碼中兩行的 a:b: 都去掉,看起來就好像是把 m 賦值給了 M,把 n 賦值給了 N

Array

function getColors() {
  return ["red", "blue", "green"];
}
let [color1,color2,color3] = getColors();
console.info(color1,color2,color3); // red blue green

數組解構跟對象解構不太同樣,數組的元素是按次序排列,變量的取值由位置決定,而對象的屬性是沒有次序,變量必須跟屬性同名,才能取到對應值。

數組解構的這種寫法屬於模式匹配:只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。

數組解構的狀況有:

徹底解構

等號左邊的模式,跟等號右邊的數組徹底匹配。

let [x,y,z] = [1,2,3];
console.info(x,y,z); // 1 2 3

let [a,,c] = [1,2,3];
console.info(a,c); // 1 3

部分解構

等號左邊的模式,跟等號右邊的數組部分匹配。

let [x,y] = [1,2,3];
console.info(x,y); // 1 2

let [a, [b], c] = [1, [2, 3], 4];
console.info(a,b,c); // 1 2 4

解構失敗

let [x] = [];
console.info(x); // undefined

let [a,b] = [1];
console.info(a,b); // 1 undefined

解構失敗,變量的值會爲 undefined

默認值

解構能夠制定默認值。使用默認值的條件是:

  • 對象的屬性值 === undefined。
  • 數組成員 === undefined。

對象解構默認值:

let {x:y=1} = {};
console.info(y); // 1

let {a:b=1} = {a:2};
console.info(b); // 2

數組解構默認值:

let [x=1] = [undfined];
console.info(x); // 1

let [a=1] = [null];
console.info(a); // null

不僅是聲明

在上面的例子中,在 let 聲明中應用瞭解構賦值,但解構是一個通用的賦值操做,不僅是聲明。

let m,n;
[m] = [1];
( {n} = {n:2} );
console.info(m); // 1
console.info(n); // 2

上面的例子中,變量都已經聲明,這樣解構就只是用於賦值。

對於對象解構,若是省略了 var/let/const 聲明符,就必須用 () 括起來。若是不這麼作,解析的時候就會被看成一個塊語句而不是一個對象。

參考資料

相關文章
相關標籤/搜索