成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入理解 ES6 的解構(gòu)賦值

only_do / 3261人閱讀

摘要:在可遍歷的量中使用數(shù)組模型數(shù)組解構(gòu)使用一個迭代器來獲取數(shù)據(jù)源中的元素。所以,數(shù)組解構(gòu)能夠在上工作的迭代器總是按照元素插入的順序?qū)⒃胤祷?,所以上述的解?gòu)返回的結(jié)果總是相同的。

解構(gòu)賦值(destructuring assignment)語法是一個Javascript表達式,這種語法能夠更方便的提取出 Object 或者 Array 中的數(shù)據(jù)。這種語法可以在接受提取的數(shù)據(jù)的地方使用,比如一個表達式的左邊。有明確的語法模式來告訴我們?nèi)绾问褂眠@種語法提取需要的數(shù)據(jù)值。

Object 的解構(gòu)

解構(gòu) Object:

const obj = { first: "Jane", last: "Doe" };
const {first: f, last: l} = obj;
// f = "Jane"; l = "Doe"

// {prop} is short for {prop: prop}
const {first, last} = obj;
// first = "Jane"; last = "Doe"

解構(gòu)能幫助更好地處理方法返回的對象:

const obj = { foo: 123 };

const {writable, configurable} = Object.getOwnPropertyDescriptor(obj, "foo");

console.log(writable, configurable); // true true
Array 的解構(gòu)

解構(gòu)數(shù)組,對所有可遍歷的值有效。

let foo = ["one", "two", "three"];

let [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"

const iterable = ["a", "b"];
const [x, y] = iterable;
// x = "a"; y = "b"

[x, y] = iterable;

// window.x = "a"; window.y = "b";

同樣的,解構(gòu)數(shù)組也能幫助我們更好地處理函數(shù)返回值:

const [all, year, month, day] =
    /^(ffffdd)-(dd)-(dd)$/
    .exec("2999-12-31");

而且,你也可以忽略你不感興趣的返回值:

function f() {
  return [1, 2, 3];
}

let [a, , b] = f();
console.log(a); // 1
console.log(b); // 3

你也可以忽略全部返回值,不過似乎沒啥用:

[,,] = f();

當解構(gòu)一個數(shù)組時,可以使用剩余模式(拓展語句,Spread operator),將數(shù)組剩余部分賦值給一個變量。

let [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
在什么地方可以使用解構(gòu)

解構(gòu)可以在下面這些情景中使用,只展現(xiàn)了數(shù)組模式的演示,對象模式也是如此。

// 變量聲明:
const [x] = ["a"];
let [x] = ["a"];
var [x] = ["a"];

// 賦值: 下面這種情況將會在全局變量上添加一個 x 屬性,值為‘a(chǎn)‘
[x] = ["a"]; 

// 參數(shù)的定義:
function userId({id}) {
  return id;
}

function whois({displayName: displayName, fullName: {firstName: name}}){
  console.log(displayName + " is " + name);
}

var user = { 
  id: 42, 
  displayName: "jdoe",
  fullName: { 
      firstName: "John",
      lastName: "Doe"
  }
};

console.log("userId: " + userId(user)); // "userId: 42"
whois(user); // "jdoe is John"

function f([x]) { ··· }
f(["a"]);

也可以在 for-of 循環(huán)中使用:

const arr = ["a", "b"];
for (const [index, element] of arr.entries()) {
    console.log(index, element);
}
// Output:
// 0 a
// 1 b
解構(gòu)賦值的模型 patterns

在解構(gòu)中,有下面兩部分參與:

Destructuring source: 解構(gòu)的源,將要被解構(gòu)的數(shù)據(jù),比如解構(gòu)賦值表達式的右邊部分。

Destructuring target: 解構(gòu)的目標,比如解構(gòu)復制表達式的左邊部分。

解構(gòu)的目標可以是下面三個的任意一個:

賦值對象,Assigment Patterns。例如 x

賦值對象通常來說是一個變量。但是在解構(gòu)賦值中,你有更多的選擇,稍后會講到。

對象模型,Object Patterns。比如:{ first: ?pattern?, last: ?pattern? }

數(shù)組模型,Object Patterns。比如:[ ?pattern?, ?pattern? ]

可以任意嵌套模型,而且是可以非常任性的嵌套。

const obj = { a: [{ foo: 123, bar: "abc" }, {}], b: true };
const { a: [{foo: f}] } = obj; // f = 123
解構(gòu)的 patterns 如何訪問到值的內(nèi)部結(jié)構(gòu)?

在一個表達式pattern = someValue中,pattern是如何訪問someValue的呢?

Object patterns 將 value 轉(zhuǎn)換成 Object

在訪問屬性之前,object pattern 將解構(gòu)的源數(shù)據(jù)(destructuing source)轉(zhuǎn)換成對象。

const {length : len} = "abc"; // len = 3
const {toString: s} = 123; // s = Number.prototype.toString
使用“對象解構(gòu)”的缺點

在這個過程中,強制轉(zhuǎn)換成對象的過程不是通過Object()方法,而是通過內(nèi)置的操作方法toObject()。這兩個操作處理undefinednull的方式不太一樣。

Object()方法將原始類型值轉(zhuǎn)換成包裝類型對象(wrapper object),原來的值原封不動。

> typeof Object("abc")
"object"

> var obj = {};
> Object(obj) === obj
true

也會將undefinednull 轉(zhuǎn)換成一個空的對象。

> Object(undefined)
{}
> Object(null)
{}

對比之下,當遇到undefinednull的時候,toObject()方法則會拋出一個錯誤。所以下面的解構(gòu)是失敗的:

const { prop: x } = undefined; // TypeError
const { prop: y } = null; // TypeError

因此,你可以使用空對象模型{}來檢查一個值是否被強制轉(zhuǎn)換成了一個對象。正如前面提到的規(guī)則,undefinednull將會拋出錯誤

({} = [true, false]); // OK, Arrays are coercible to objects
({} = "abc"); // OK, strings are coercible to objects

({} = undefined); // TypeError
({} = null); // TypeError

表達式兩邊的括號是必須的,因為在 JavaScript 中,聲明不能以花括號開始。

在可遍歷的量中使用數(shù)組模型

數(shù)組解構(gòu)使用一個迭代器來獲取數(shù)據(jù)源中的元素。因此,你可以對任何可以遍歷的值使用數(shù)組解構(gòu)。

字符串是可遍歷的:

const [x, ...y] = "abc"; // x="a"; y=["b", "c"]

我們無法通過索引訪問 Set中的元素,但是可以通過迭代器。所以,數(shù)組解構(gòu)能夠在 Sets上工作:

const [x,y] = new Set(["a", "b"]); // x="a"; y="b’;

Set的迭代器總是按照元素插入的順序?qū)⒃胤祷?,所以上述的解?gòu)返回的結(jié)果總是相同的。

使用“數(shù)組解構(gòu)”的缺點

如果一個值有一個 key 為Symbol.iterator的方法,這個方法返回的是一個對象,那么這個值是可以遍歷的。如果被解構(gòu)的值不能遍歷的,那么“數(shù)組解構(gòu)”會拋出一個TypeError錯誤。

let x;
[x] = [true, false]; // OK, Arrays are iterable
[x] = "abc"; // OK, strings are iterable
[x] = { * [Symbol.iterator]() { yield 1 } }; // OK, iterable

[x] = {}; // TypeError, empty objects are not iterable
[x] = undefined; // TypeError, not iterable
[x] = null; // TypeError, not iterable

可以用一個空的數(shù)組模型[]來檢查值是不是可遍歷的:

[] = {}; // TypeError, empty objects are not iterable
[] = undefined; // TypeError, not iterable
[] = null; // TypeError, not iterable
默認值

默認值是可選的,在數(shù)據(jù)源中找不到對應(yīng)的值時,如果設(shè)置了默認值,則匹配這個默認值作為匹配結(jié)果,否則返回 undefined。

const [x=3, y] = []; // x = 3; y = undefined。
const {foo: x=3, bar: y} = {}; // x = 3; y = undefined
undefined 也會觸發(fā)默認值

當解構(gòu)模式有匹配結(jié)果,且匹配結(jié)果是 undefined 時,也會使用默認值作為返回結(jié)果:

const [x=1] = [undefined]; // x = 1
const {prop: y=2} = {prop: undefined}; // y = 2
默認值是根據(jù)需要計算出來的

也就是說下面的解構(gòu):

const {prop: y=someFunc()} = someValue;

相當于:

let y;
if (someValue.prop === undefined) {
    y = someFunc();
} else {
    y = someValue.prop;
}

使用console.log()可以觀察到:

> function log(x) { console.log(x); return "YES" }
> const [a=log("hello")] = [];
> a
"YES"
> const [b=log("hello")] = [123];
> b
123

在第二個解構(gòu)中,默認值沒有觸發(fā),并且log()沒有被調(diào)用。

默認值可以引用模式中的其他變量

默認值可以引用模式中的任何變量,包括相同模式中的其他變量:

const [x=3, y=x] = [];     // x=3; y=3
const [x=3, y=x] = [7];    // x=7; y=7
const [x=3, y=x] = [7, 2]; // x=7; y=2

但是,變量的順序很關(guān)鍵,從左到右,先聲明的變量不能引用后聲明的變量,也就是左邊的不能引用右邊的。

const [x=y, y=3] = []; // ReferenceError
patterns 的默認值

到目前為止,我們所看到的都是模式中變量的默認值,我們也可以為模式設(shè)置默認值。

const [{prop: x} = {}] = [];

如果整個模式?jīng)]有匹配結(jié)果,則使用{}作為數(shù)據(jù)源來匹配。

const { prop: x } = {}; // x = undefined

上面的例子中,x 為 undefined 可能還是不夠直觀。看下面這個例子:

const [{prop: x} = {props: "abc"}] = []; // x=abc
對象解構(gòu)的更多特性 屬性,屬性值的簡寫

如果屬性值是一個變量,和屬性的 key相同,就可以忽略這個 key:

const { x, y } = { x: 11, y: 8 }; // x = 11; y = 8

// 等價于
const { x: x, y: y } = { x: 11, y: 8 };
計算后的屬性的鍵

如果把表達式放入方括號中,可以用這個表達式聲明屬性的鍵:

const FOO = "foo";
const { [FOO]: f} = {fooL 123}; // f = 123

這也使得可以使用 symbols 來做屬性的鍵:

// Create and destructure a property whose key is a symbol
const KEY = Symbol();
const obj = { [KEY]: "abc" };
const { [KEY]: x } = obj; // x = "abc"

// Extract Array.prototype[Symbol.iterator]
const { [Symbol.iterator]: func } = [];
console.log(typeof func); // function
數(shù)組解構(gòu)的更多特性 省略

在解構(gòu)的過程中可以跳過一些元素:

const [,,x,y] = [1,2,3,4]; // x= 3 y = 4;
剩余運算符 Rest operator (...)

剩余運算符可以將一個可遍歷對象中剩余的元素提取到一個數(shù)組中。如果這個運算符在數(shù)組模式中使用,運算符必須放在最后:

const [x, ...y] = [1,2,3,4]; // x=1; y=[2,3,4];

要注意的時,拓展運算符(spread operator)與剩余操作符有著相同的語法-三個點。但是它們之間有區(qū)別:前者將數(shù)組變成多個元素;后者則用來解構(gòu)和提取數(shù)據(jù),多個元素壓縮成一個元素。

如果運算符找不到任何元素,將會匹配一個空的數(shù)組,永遠不會返回undefined 或者 null。例如:

const [x, y, ...z] = ["a"]; // x="a"; y=undefined; z

操作符不一定非要是一個變量,也可以使用模式:

const [x, ...[y, z]] = ["a", "b", "c"]; // x = "a"; y = "b"; z = "c"
解構(gòu)的陷阱

在使用解構(gòu)的時候,有兩點要考慮清楚:

不能使用大括號作為聲明語句的開頭;

在解構(gòu)的過程中,可以申明變量或者分配給變量,但是不能同時這么做;

解構(gòu)的幾個例子

在 for-of 中使用解構(gòu):

const map = new Map().set(false, "no").set(true, "yes");
for (const [key, value] of map) {
  console.log(key + " is " + value);
}

使用解構(gòu)交換兩個變量的值:

[a, b] = [b, a];

或者:

[a, b, c] = [c, a, b];

還可以分割數(shù)據(jù):

const [first, ...rest] = ["a", "b", "c"]; // first = "a"; rest = ["b", "c"]

處理方法返回的數(shù)組更加方便:

const [all, year, month, day] = /^(ffffdd)-(dd)-(dd)$/.exec("2999-12-31");

const cells = "Jane	Doe	CTO"
const [firstName, lastName, title] = cells.split("	");
console.log(firstName, lastName, title);

要注意的一點是:exec等一些方法可能會返回 null,導致程序拋出錯誤TypeError,此時需要添加一個默認值:

const [, year, month, day] = /^(ffffdd)-(dd)-(dd)$/.exec(someStr) || [];

參考資料:

Exploringjs Destructuring

MDN Destructing assignment

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88093.html

相關(guān)文章

  • 深入理解ES6》筆記——解構(gòu):使數(shù)據(jù)訪問更便捷(5)

    摘要:解構(gòu),一種黑魔法解構(gòu)是從對象中提取出更小元素的過程。賦值是對解構(gòu)出來的元素進行重新賦值??偨Y(jié)本章講解了對象解構(gòu)賦值和數(shù)組解構(gòu)賦值,以及對象和數(shù)組混合情況下的解構(gòu)賦值操作,最后一個知識點是解構(gòu)函數(shù)的參數(shù)。 解構(gòu),一種黑魔法 解構(gòu)是從對象中提取出更小元素的過程。賦值是對解構(gòu)出來的元素進行重新賦值。 下面的代碼你可能無法在瀏覽器上實時測試,推薦在babel官網(wǎng)在線測試代碼:在線測試ES6代碼...

    Drinkey 評論0 收藏0
  • 深入理解ES6之《解構(gòu)

    摘要:對象解構(gòu)如果使用解析聲明變量,則必須提供初始化程序也就是等號右側(cè)的值以下語句有語法錯誤解構(gòu)賦值表達式也就是右側(cè)的表達式如果為或會導致程序拋出錯誤,因為任何嘗試讀取或的屬性的行為都會觸發(fā)運行時錯誤上面代碼是聲明變量同時賦值相應(yīng)的屬性值那如果已 對象解構(gòu) 如果使用var、let、const解析聲明變量,則必須提供初始化程序(也就是等號右側(cè)的值)以下語句有語法錯誤 var { type, n...

    DTeam 評論0 收藏0
  • 深入理解ES6之《解構(gòu)

    摘要:對象解構(gòu)如果使用解析聲明變量,則必須提供初始化程序也就是等號右側(cè)的值以下語句有語法錯誤解構(gòu)賦值表達式也就是右側(cè)的表達式如果為或會導致程序拋出錯誤,因為任何嘗試讀取或的屬性的行為都會觸發(fā)運行時錯誤上面代碼是聲明變量同時賦值相應(yīng)的屬性值那如果已 對象解構(gòu) 如果使用var、let、const解析聲明變量,則必須提供初始化程序(也就是等號右側(cè)的值)以下語句有語法錯誤 var { type, n...

    wuyumin 評論0 收藏0
  • 深入理解ES6筆記(五)解構(gòu):使訪問數(shù)據(jù)更便捷

    摘要:當冒號右側(cè)存在花括號時,表示目標被嵌套在對象的更深一層中。在對象的嵌套解構(gòu)中同樣能為本地變量使用不同的名稱提取數(shù)組解構(gòu)結(jié)構(gòu)賦值基本忽略一些選項重新賦值默認值數(shù)組解構(gòu)賦值同樣允許在數(shù)組任意位置指定默認值。 主要知識點:對象解構(gòu)、數(shù)組解構(gòu)、混合解構(gòu)以及參數(shù)解構(gòu)showImg(https://segmentfault.com/img/bVbfWgH?w=1020&h=585); 《深入理解...

    _DangJin 評論0 收藏0

發(fā)表評論

0條評論

only_do

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<