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

資訊專(zhuān)欄INFORMATION COLUMN

ES6學(xué)習(xí)(二)之解構(gòu)賦值及其原理

chunquedong / 1104人閱讀

摘要:基本原理解構(gòu)是提供的語(yǔ)法糖,其實(shí)內(nèi)在是針對(duì)可迭代對(duì)象的接口,通過(guò)遍歷器按順序獲取對(duì)應(yīng)的值進(jìn)行賦值。屬性值返回一個(gè)對(duì)象的無(wú)參函數(shù),被返回對(duì)象符合迭代器協(xié)議。迭代器協(xié)議定義了標(biāo)準(zhǔn)的方式來(lái)產(chǎn)生一個(gè)有限或無(wú)限序列值。

更多系列文章請(qǐng)看
1、基本語(yǔ)法 1.1、數(shù)組
// 基礎(chǔ)類(lèi)型解構(gòu)
let [a, b, c] = [1, 2, 3]
console.log(a, b, c) // 1, 2, 3

// 對(duì)象數(shù)組解構(gòu)
let [a, b, c] = [{name: "1"}, {name: "2"}, {name: "3"}]
console.log(a, b, c) // {name: "1"}, {name: "2"}, {name: "3"}

// ...解構(gòu)
let [head, ...tail] = [1, 2, 3, 4]
console.log(head, tail) // 1, [2, 3, 4]

// 嵌套解構(gòu)
let [a, [b], d] = [1, [2, 3], 4]
console.log(a, b, d) // 1, 2, 4

// 解構(gòu)不成功為undefined
let [a, b, c] = [1]
console.log(a, b, c) // 1, undefined, undefined

// 解構(gòu)默認(rèn)賦值
let [x = 1] = [undefined];// x=1;
let [x = 1] = [null];// x=null; // 數(shù)組成員嚴(yán)格等于undefined,默認(rèn)值才會(huì)生效
let [x = 1, y = x] = [];     // x=1; y=1
let [x = 1, y = x] = [2];    // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = [];     // ReferenceError: y is not defined 因?yàn)閤用y做默認(rèn)值時(shí),y還沒(méi)有聲明
1.2 對(duì)象
// 對(duì)象屬性解構(gòu)
let { f1, f2 } = { f1: "test1", f2: "test2" }
console.log(f1, f2) // test1, test2

// 可以不按照順序,這是數(shù)組解構(gòu)和對(duì)象解構(gòu)的區(qū)別之一
let { f2, f1 } = { f1: "test1", f2: "test2" }
console.log(f1, f2) // test1, test2

// 解構(gòu)對(duì)象重命名
let { f1: rename, f2 } = { f1: "test1", f2: "test2" }
console.log(rename, f2) // test1, test2

// 嵌套解構(gòu)
let { f1: {f11}} = { f1: { f11: "test11", f12: "test12" } }
console.log(f11) // test11

// 默認(rèn)值
let { f1 = "test1", f2: rename = "test2" } = { f1: "current1", f2: "current2"}
console.log(f1, rename) // current1, current2
1.3 字符串/數(shù)值/布爾值
// String
let [ a, b, c, ...rest ] = "test123"
console.log(a, b, c, rest) // t, e, s, [ "t", "1", "2", "3" ]
let {length : len} = "hello"; // en // 5

// number
let {toString: s} = 123;
s === Number.prototype.toString // true

// boolean
let {toString: s} = true;
s === Boolean.prototype.toString // true

// Map
let [a, b] = new Map().set("f1", "test1").set("f2", "test2")
console.log(a, b) // [ "f1", "test1" ], [ "f2", "test2" ]

// Set
let [a, b] = new Set([1, 2, 3])
console.log(a, b) // 1, 2
2、使用場(chǎng)景 2.1、 淺拷貝
let colors = [ "red", "green", "blue" ];
let [ ...clonedColors ] = colors;
console.log(clonedColors);  // "[red,green,blue]"
注意這里是淺拷貝
2.2、 交換變量
let x = 1;
let y = 2;
[x, y] = [y, x];
2.3、遍歷Map結(jié)構(gòu)
var map = new Map();
map.set("first", "hello");
map.set("second", "world");

for (let [key, value] of map) {
    console.log(key + " is " + value);
}
2.4、函數(shù)參數(shù)
function add(a,b,{c,d}){
    // ...
}
add(1,2,{});
add(1,2)//Uncaught TypeError: Cannot destructure property `c` of "undefined" or "null"
解構(gòu)賦值的規(guī)則是,若等號(hào)右邊的值不是對(duì)象或者數(shù)組,就會(huì)先將其轉(zhuǎn)化成對(duì)象。由于undefined和null無(wú)法轉(zhuǎn)化成對(duì)象,所以對(duì)其進(jìn)行解構(gòu)賦值時(shí)會(huì)報(bào)錯(cuò)。

它實(shí)際上是這樣運(yùn)行的:

function add(a, b, options) {
    let { c,d } = options;
    // ...
}

由于add(1,2)沒(méi)有傳options導(dǎo)致異常,如果我們options是選填的那么可以像下面這樣

function add(a,b,{c,d}={}){
    // ...
}

當(dāng)然大部分情況我們可以給默認(rèn)值

function move ({x:0,y:0}={}){}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
function move ({x,y}={x:0,y:0}){}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]

上面代碼是為函數(shù)move的參數(shù)指定默認(rèn)值,而不是為變量x和y指定默認(rèn)值,所以會(huì)得到與前一種寫(xiě)法不同的結(jié)果。
undefined就會(huì)觸發(fā)函數(shù)參數(shù)的默認(rèn)值。

[1, undefined, 3].map((x = "yes") => x);
3、基本原理

解構(gòu)是ES6提供的語(yǔ)法糖,其實(shí)內(nèi)在是針對(duì)可迭代對(duì)象的Iterator接口,通過(guò)遍歷器按順序獲取對(duì)應(yīng)的值進(jìn)行賦值。這里需要提前懂得ES6的兩個(gè)概念:

Iterator

可迭代對(duì)象

3.1、Iterator概念

Iterator是一種接口,為各種不一樣的數(shù)據(jù)解構(gòu)提供統(tǒng)一的訪問(wèn)機(jī)制。任何數(shù)據(jù)解構(gòu)只要有Iterator接口,就能通過(guò)遍歷操作,依次按順序處理數(shù)據(jù)結(jié)構(gòu)內(nèi)所有成員。ES6中的for of的語(yǔ)法相當(dāng)于遍歷器,會(huì)在遍歷數(shù)據(jù)結(jié)構(gòu)時(shí),自動(dòng)尋找Iterator接口。
Iterator作用:

為各種數(shù)據(jù)解構(gòu)提供統(tǒng)一的訪問(wèn)接口

使得數(shù)據(jù)解構(gòu)能按次序排列處理

可以使用ES6最新命令 for of進(jìn)行遍歷

function makeIterator(array) {
    var nextIndex = 0
    return {
      next: function() {
        return nextIndex < array.length ?
            {value: array[nextIndex++]} :
            {done: true}
        }
    };
  }

var it = makeIterator([0, 1, 2])
console.log(it.next().value) // 0
console.log(it.next().value) // 1
console.log(it.next().value) // 2
3.2、可迭代對(duì)象

可迭代對(duì)象是Iterator接口的實(shí)現(xiàn)。這是ECMAScript 2015的補(bǔ)充,它不是內(nèi)置或語(yǔ)法,而僅僅是協(xié)議。任何遵循該協(xié)議點(diǎn)對(duì)象都能成為可迭代對(duì)象??傻鷮?duì)象得有兩個(gè)協(xié)議:可迭代協(xié)議迭代器協(xié)議

可迭代協(xié)議:對(duì)象必須實(shí)現(xiàn)@@iterator方法。即對(duì)象或其原型鏈上必須有一個(gè)名叫Symbol.iterator的屬性。該屬性的值為無(wú)參函數(shù),函數(shù)返回迭代器協(xié)議。

屬性
Symbol.iterator 返回一個(gè)對(duì)象的無(wú)參函數(shù),被返回對(duì)象符合迭代器協(xié)議。

迭代器協(xié)議:定義了標(biāo)準(zhǔn)的方式來(lái)產(chǎn)生一個(gè)有限或無(wú)限序列值。其要求必須實(shí)現(xiàn)一個(gè)next()方法,該方法返回對(duì)象有done(boolean)value屬性。

屬性
next 返回一個(gè)對(duì)象的無(wú)參函數(shù),被返回對(duì)象擁有兩個(gè)屬性:donevalue
done :如果迭代器已經(jīng)經(jīng)過(guò)了被迭代序列時(shí)為 true。這時(shí) value 可能描述了該迭代器的返回值。如果迭代器可以產(chǎn)生序列中的下一個(gè)值,則為 false。這等效于連同 done 屬性也不指定。
value :迭代器返回的任何 JavaScript 值。done 為 true 時(shí)可省略。

通過(guò)以上可知,自定義數(shù)據(jù)結(jié)構(gòu),只要擁有Iterator接口,并將其部署到自己的Symbol.iterator屬性上,就可以成為可迭代對(duì)象,能被for of循環(huán)遍歷。

3.3、解構(gòu)語(yǔ)法糖

String、Array、Map、Set等原生數(shù)據(jù)結(jié)構(gòu)都是可迭代對(duì)象,可以通過(guò)for of循環(huán)遍歷它。故可以通過(guò)ES6解構(gòu)語(yǔ)法糖依次獲取對(duì)應(yīng)的值。

// String
let str = "test"
let iterFun = str[Symbol.iterator]
let iterator = str[Symbol.iterator]()
let first = iterator.next() // 等效于 let [first] = "test"
console.log(iterFun, iterator, first)
// 打印
// [Function: [Symbol.iterator]], {}, { value: "t", done: false }

// Array
let arr = ["a", "b", "c"];
let iter = arr[Symbol.iterator]();

// 以下等效于 let [first, second, third, four] = ["a", "b", "c"]
let first = iter.next() // { value: "a", done: false }
let second = iter.next() // { value: "b", done: false }
let third = iter.next() // { value: "c", done: false }
let four = iter.next() // { value: undefined, done: true }
4、性能

當(dāng)我們有解構(gòu)賦值的形式來(lái)做函數(shù)參數(shù)時(shí),執(zhí)行的時(shí)候會(huì)增加很多中間變量,內(nèi)存也會(huì)比之前高。但是業(yè)務(wù)代碼還是更加關(guān)注可讀性和可維護(hù)性。如果你寫(xiě)的是庫(kù)代碼,可以嘗試這種優(yōu)化,把參數(shù)展開(kāi)后直接傳遞,到底能帶來(lái)多少性能收益還得看最終的基準(zhǔn)測(cè)試。

參考

ES6 的解構(gòu)賦值前每次都創(chuàng)建一個(gè)對(duì)象嗎?會(huì)加重 GC 的負(fù)擔(dān)嗎?

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

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

相關(guān)文章

  • ES6學(xué)習(xí)手稿基本類(lèi)型擴(kuò)展

    摘要:它是一個(gè)通用標(biāo)準(zhǔn),奠定了的基本語(yǔ)法。年月發(fā)布了的第一個(gè)版本,正式名稱就是標(biāo)準(zhǔn)簡(jiǎn)稱。結(jié)語(yǔ)的基本擴(kuò)展還有一些沒(méi)有在這里詳細(xì)介紹。 前言 ES6標(biāo)準(zhǔn)以及頒布兩年了,但是,好像還沒(méi)有完全走進(jìn)我們的日常開(kāi)發(fā)。這篇文章從ES6的基本類(lèi)型擴(kuò)展入手,逐步展開(kāi)對(duì)ES6的介紹。 ECMAScript和JavaScript JavaScript是由Netscape創(chuàng)造的,該公司1996年11月將JavaSc...

    tommego 評(píng)論0 收藏0
  • ES6學(xué)習(xí)筆記

    摘要:所以,如果一個(gè)數(shù)組成員不嚴(yán)格等于,默認(rèn)值是不會(huì)生效的因?yàn)椴粐?yán)格等于對(duì)象解構(gòu)對(duì)象的解構(gòu)與數(shù)組有一個(gè)重要的不同。數(shù)組的元素是按次序排列的,變量的取值由它的位置決定而對(duì)象的屬性沒(méi)有次序,變量必須與屬性同名,才能取到正確的值。 http://es6.ruanyifeng.com/?se... 一、作用域 let //i作用域在全局,每次循環(huán)i都被重新賦值了而覆蓋了之前的值 var a = []...

    Gu_Yan 評(píng)論0 收藏0
  • 箭頭函數(shù)你想知道的都在這里

    摘要:沒(méi)有箭頭函數(shù)沒(méi)有自己的對(duì)象,這不一定是件壞事,因?yàn)榧^函數(shù)可以訪問(wèn)外圍函數(shù)的對(duì)象那如果我們就是要訪問(wèn)箭頭函數(shù)的參數(shù)呢你可以通過(guò)命名參數(shù)或者參數(shù)的形式訪問(wèn)參數(shù)不能通過(guò)關(guān)鍵字調(diào)用函數(shù)有兩個(gè)內(nèi)部方法和。 1、基本語(yǔ)法回顧 我們先來(lái)回顧下箭頭函數(shù)的基本語(yǔ)法。ES6 增加了箭頭函數(shù): var f = v => v; // 等同于 var f = function (v) { return ...

    xiaoqibTn 評(píng)論0 收藏0
  • ES6學(xué)習(xí)筆記()--------------------------------------變量

    摘要:如果變量名與屬性名不一致,必須寫(xiě)成下面這樣。這是因?yàn)榇藭r(shí),字符串被轉(zhuǎn)換成了一個(gè)類(lèi)似數(shù)組的對(duì)象。數(shù)字和布爾的解構(gòu)賦值,解構(gòu)賦值時(shí),如果等號(hào)右邊是數(shù)值和布爾值,則會(huì)先轉(zhuǎn)為對(duì)象。參數(shù)也可以是無(wú)序的解構(gòu)賦值對(duì)提取對(duì)象中的數(shù)據(jù),可以快速提取 ES6 允許按照一定模式,從數(shù)組和對(duì)象中提取值,對(duì)變量進(jìn)行賦值,這被稱為解構(gòu)ES6之前我們申明多個(gè)變量需要按照下面的方法: let a=1; let b=2...

    王笑朝 評(píng)論0 收藏0
  • ES6學(xué)習(xí)筆記()--------------------------------------變量

    摘要:如果變量名與屬性名不一致,必須寫(xiě)成下面這樣。這是因?yàn)榇藭r(shí),字符串被轉(zhuǎn)換成了一個(gè)類(lèi)似數(shù)組的對(duì)象。數(shù)字和布爾的解構(gòu)賦值,解構(gòu)賦值時(shí),如果等號(hào)右邊是數(shù)值和布爾值,則會(huì)先轉(zhuǎn)為對(duì)象。參數(shù)也可以是無(wú)序的解構(gòu)賦值對(duì)提取對(duì)象中的數(shù)據(jù),可以快速提取 ES6 允許按照一定模式,從數(shù)組和對(duì)象中提取值,對(duì)變量進(jìn)行賦值,這被稱為解構(gòu)ES6之前我們申明多個(gè)變量需要按照下面的方法: let a=1; let b=2...

    geekidentity 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

chunquedong

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<