国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

通俗易懂理解ES6 - ES6的變量類型及Iterator

Keven / 2570人閱讀

摘要:迭代器在原有的數(shù)據(jù)結(jié)構(gòu)類型上新增了兩種類型,我們?cè)谑褂玫臅r(shí)候還可以通過(guò)自由組合的形式使用這些結(jié)構(gòu)類型達(dá)到自己想要的數(shù)據(jù)結(jié)構(gòu),這就需要一種統(tǒng)一的接口機(jī)制供我們調(diào)用處理不同的數(shù)據(jù)結(jié)構(gòu)。

引言

萬(wàn)丈高樓平地起,欲練此功,必先打好基本功: )

在了解 ES6 新增的變量類型前,我們必須先知道 JavaScript 在ES6之前,有如下六種基本數(shù)據(jù)類型:Null、Undefined、Number、String、Boolean和Object。而 ES6 中,新增了第七種數(shù)據(jù)類型:Symbol。
上述七種數(shù)據(jù)類型作如下類型劃分:

基本類型: Undefined、Null、Boolean、String、Number,這五種類型的變量都是直接把實(shí)際值存儲(chǔ)在棧內(nèi)存當(dāng)中,操作或訪問(wèn)的時(shí)候都是直接對(duì)實(shí)際值進(jìn)行的.

引用類型: Object。Object 類型的變量是把指向堆內(nèi)存的地址值存儲(chǔ)在棧內(nèi)存當(dāng)中的一類數(shù)據(jù)。(關(guān)于堆棧的知識(shí)將會(huì)在后面的文章中作介紹。)

有關(guān)基本類型和引用類型的說(shuō)明,網(wǎng)上已經(jīng)有很多文章有說(shuō)明介紹,為免篇幅過(guò)長(zhǎng),這里就不再重復(fù)敘述了。

Symbol類型:

這里我們著重說(shuō)一下 Symbol 類型:


Symbol 是一個(gè)函數(shù),調(diào)用該函數(shù),返回的唯一值就是 Symbol 類型值;

不允許在 Symbol 前使用 new,symbol 類型的值可通過(guò)直接調(diào)用 Symbol 函數(shù)創(chuàng)建
let symbol = Symbol();
symbol;         //Symbol()
typeof symbol;  //symbol
let symbol1 = new Symbol();     //Uncaught TypeError: Symbol is not a constructor
Symbol 函數(shù)調(diào)用時(shí),可接受一個(gè)參數(shù),該參數(shù)會(huì)通過(guò) toString 方法變?yōu)樽址鳛?symbol 值的說(shuō)明,傳入的參數(shù)不可以為 symbol 類型的值
let testStr = "this is a string",
    testObj = {obj: "this is a object"},
    testArr = ["this","is","a","array"],
    testFn = () => {
        console.log("this is a function");
    },
    testSym = Symbol("this is a symbol"),
    symbolStr = Symbol(testStr),            //Symbol(this is a string)
    symbolObj = Symbol(testObj),            //Symbol([object Object])
    symnolArr = Symbol(testArr),            //Symbol([object Object])
    symbolFn = Symbol(testFn),              //Symbol(() => {console.log("this is a function");})
    symbolSym = Symbol(testSym);            //Uncaught TypeError: Cannot convert a Symbol value to a string
Symbol 函數(shù)調(diào)用后生成的值是唯一的
let symbol1 = Symbol("test"),
    symbol2 = Symbol("test");
symbol1 == symbol2;         //false
symbol1 === symbol2;        //false
Symbol 值不能與其他類型值進(jìn)行運(yùn)算、隱式轉(zhuǎn)換,否則會(huì)報(bào)錯(cuò);但能通過(guò) toString 方法顯式轉(zhuǎn)為字符串。
let symbol = Symbol("this is symbol"),
    str = "this is string",
    num = 2,
    symStr = symbol.toString();
    
let newStr = symbol + str;          //Uncaught TypeError: Cannot convert a Symbol value to a string
let newNum = Symbol + num;          //Uncaught TypeError: Cannot convert a Symbol value to a number
symStr;                             // Symbol(this is symbol)
Symbol 值的唯一性,用于 Object 的屬性中,可以確保不會(huì)出現(xiàn)同名屬性
let symbol = Symbol("this is symbol"),
    symbol1 = Symbol("this is symbol");
let obj = {
    [symbol]: "this is a",
    [symbol1]: "this is b"
};
obj;            //{Symbol(this is symbol): "this is a", Symbol(this is symbol): "this is b"}

let str = "test",
    str1 = "test",
    obj = {};
obj[str] = "測(cè)試非symbol類型命名的屬性";
obj;            //{test: "測(cè)試非symbol類型命名的屬性"}
obj[str1] = "再次測(cè)試非symbol類型命名的屬性";
obj;            //{test: "再次測(cè)試非symbol類型命名的屬性"}
Symbol 命名的屬性可通過(guò) Object.getOwnPropertySymbols 獲取
let symbol = Symbol("this is symbol"),
    symbol1 = Symbol("this is symbol");
let symbolObj = {
    [symbol]: "this is a",
    [symbol1]: "this is b",
}
Object.getOwnPropertySymbols(symbolObj);    //[Symbol(this is symbol), Symbol("this is symbol")]
Symbol 值命名的屬性不會(huì)出現(xiàn)在 Object.keys、for...in...中,通過(guò)Object.getOwnPropertyNames()、JSON.stringify() 也無(wú)法得到返回值。但該屬性是公開(kāi)屬性,不是私有屬性。
let symbol = Symbol("this is symbol"),
    symbol1 = Symbol("this is symbol");
let obj = {
    [symbol]: "this is a",
    [symbol1]: "this is b",
    d: "test"
};
for(key in obj){
    console.log(key);               // d
}
Object.keys(obj);                   // ["d"]
Object.getOwnPropertyNames(obj);    // ["d"]
JSON.stringify(obj);                //{d:"test"}

//仍可訪問(wèn)到Symbol值定義的屬性鍵和屬性值
let symKeys = Object.getOwnPropertySymbols(obj);  
symKeys;                    //[Symbol(this is symbol), Symbol(this is symbol)]
symKeys[0];                 //Symbol(this is symbol)
obj[symKeys[0]];            //this is a
可通過(guò) Symbol.for("xxx") 獲得以"xxx"作為入?yún)⒍傻?Symbol 值,若不存在以"xxx"作為入?yún)⑸傻?Symbol 值,則會(huì)自動(dòng)創(chuàng)建一個(gè)以"xxx"為入?yún)⒌?Symbol 值。
let symbol = Symbol("this is symbol"),
    symbol1 = Symbol.for("this is symbol"),
    symbol2 = Symbol.for("this is symbol");
symbol === symbol1      //false
symbol === symbol2      //false
symbol1 === symbol2     //true
12. 通過(guò) Symbol.keyFor 方法可返回一個(gè)已“登記”的 Symbol 類型值的修飾詞。

通過(guò) Symbol 創(chuàng)建的值有如下兩種情況:
被登記的與未被登記的。


什么是被登記的?在

let s1 = Symbol.for("foo");
console.log(Symbol.keyFor(s1)); // "foo"

var s2 = Symbol("foo");
console.log(Symbol.keyFor(s2) ); // undefined

這里還有一些 MDN 關(guān)于 Symbol 的屬性介紹,因?yàn)楦杏X(jué)在日常開(kāi)發(fā)中使用的概率比較低,因此也不贅述一些自己的理解了,有興趣的朋友可以去看看https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol

關(guān)于 Symbol 的總結(jié): 對(duì)于 Symbol 的使用,實(shí)用性最高的我覺(jué)得是 symbol 值用于屬性命名的情況,在一些開(kāi)發(fā)情況下,對(duì)一個(gè) Object 對(duì)象進(jìn)行遍歷的時(shí)候,希望某一些屬性不被 for in 或 Object.keys 遍歷出來(lái),避免做 if 或 switch 情況處理,這時(shí)候使用 Symbol 定義屬性名是個(gè)不錯(cuò)的選擇。

在原有 ES5 的屬性命名和賦值過(guò)程中,多人協(xié)作開(kāi)發(fā)可能會(huì)導(dǎo)致一些屬性名重命名而導(dǎo)致值覆蓋,對(duì)“半私有屬性”屬性使用 Symbol 命名屬性名會(huì)是個(gè)很好的選擇。


Iterator - 迭代器

ES6 在原有的數(shù)據(jù)結(jié)構(gòu)類型( Array、Object )上新增了兩種類型( Map、Set ),我們?cè)谑褂玫臅r(shí)候還可以通過(guò)自由組合的形式使用這些結(jié)構(gòu)類型達(dá)到自己想要的數(shù)據(jù)結(jié)構(gòu),這就需要一種統(tǒng)一的接口機(jī)制供我們調(diào)用處理不同的數(shù)據(jù)結(jié)構(gòu) —— Iterator。

ES6中,只要被遍歷“對(duì)象”存在 可迭代協(xié)議 , 即System.iterator 屬性,該對(duì)象都是被認(rèn)為是“可遍歷的”。

在 ES6 中,有三類數(shù)據(jù)結(jié)構(gòu)原生具備 Iterator 接口:__數(shù)組、某些類似數(shù)組的對(duì)象(如 字符串、類似數(shù)組形式的對(duì)象)、Set 和 Map 結(jié)構(gòu)數(shù)據(jù)__。

迭代器協(xié)議 定義了一種標(biāo)準(zhǔn)的方式來(lái)產(chǎn)生一個(gè)有限或無(wú)限序列的值,每次遍歷都會(huì)首先調(diào)用被遍歷數(shù)據(jù)集合對(duì)象中的 [Symbol.iterator]() 方法,該方法返回一個(gè) Symbol對(duì)象的iterator屬性 ,該屬性擁有執(zhí)行迭代對(duì)象的 next 方法,并返回一個(gè)對(duì)象,如下是一段模擬 next 方法的代碼

function Iterator(arr){
    let nextIndex = 0;
    return {
        next: function(){
            return nextIndex < arr.length ? {value: arr[nextIndex++], done: false} : {value: undefined, done: true};
        },
        [Symbol.iterator]: function() { return this }
    }
}
let example = Iterator(["a", "b"]);

example.next()      // {value: "a", done: false}
example.next()      // {value: "b", done: false}
example.next()      // {value: undefined, done: true}       //遍歷結(jié)束

返回的對(duì)象中必須包含如下兩個(gè)屬性

{
    done,       //迭代是否已經(jīng)執(zhí)行完畢  迭代完畢時(shí)返回true,否則返回false,返回false時(shí)會(huì)繼續(xù)執(zhí)行迭代
    value       //當(dāng)前成員的值     迭代完畢時(shí)返回undefined,否則返回當(dāng)前成員的值
}
在某些情景下,JS會(huì)默認(rèn)調(diào)用 Symbol.iterator (Iterator接口)

擴(kuò)展運(yùn)算符

擴(kuò)展運(yùn)算符(…)會(huì)默認(rèn)調(diào)用 iterator 接口。

解構(gòu)賦值

對(duì)數(shù)組和Set結(jié)構(gòu)進(jìn)行解構(gòu)賦值時(shí),會(huì)默認(rèn)調(diào)用 Symbol.iterator 方法。

yield*

yield*后面跟的是一個(gè)可遍歷的結(jié)構(gòu),它會(huì)調(diào)用該結(jié)構(gòu)的 iterator 接口。

for...of

執(zhí)行 for...of循環(huán)時(shí),會(huì)調(diào)用 iterator 接口對(duì)數(shù)據(jù)進(jìn)行處理。

Array.from()

Array.form() 時(shí),會(huì)遍歷數(shù)據(jù),調(diào)用 iterator 接口返回相應(yīng)數(shù)據(jù)

其它情況還有
Map()Set()WeakMap()WeakSet() (比如new Map([["a",1],["b",2]]))Promise.all()Promise.race()

順帶一提:

在ES6中,具有 System.iterator 屬性的對(duì)象均可通過(guò) for...of 進(jìn)行遍歷

let arr = ["1","2","3"];
arr.pro = "test";
for (let i in arr) {
  console.log(arr[i]);          //1  2  3  test
}
for(let i of arr) {
    console.log(arr[i]);        //1  2  3
}

for...of 的相比于 forEachfor...in ,其好處在于: forEach 循環(huán)無(wú)法通過(guò) breakcontinuereturn 跳出循環(huán),而 for...of 可以; for...in 循環(huán)設(shè)計(jì)的目的是用于遍歷包含鍵值對(duì)的對(duì)象,對(duì)數(shù)組并不是那么友好,而 for...of 遍歷輸出的值會(huì)在輸出數(shù)據(jù)后默認(rèn)遍歷結(jié)束。

關(guān)于 Iterator 的總結(jié): Iterator作為一種統(tǒng)一的接口機(jī)制供我們調(diào)用處理不同的數(shù)據(jù)結(jié)構(gòu),讓可以用相同的方式來(lái)遍歷集合,而不用去考慮集合的內(nèi)部實(shí)現(xiàn),若數(shù)據(jù)的形式發(fā)生改變,只要數(shù)據(jù)內(nèi)部還存在 System.iterator 屬性,那遍歷的代碼就可以不用做修改直接使用。 同時(shí),其服務(wù)于 for...of 循環(huán), for...of 又有效地避免了以往對(duì)數(shù)據(jù)集僅能通過(guò) forEachfor..in 遍歷時(shí)遇到的一部分問(wèn)題。

以上。

文章觀點(diǎn)內(nèi)容如有錯(cuò)誤歡迎指出交流,相互進(jìn)步

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/104180.html

相關(guān)文章

  • 通俗易懂理解ES6 - 變量聲明命令其塊級(jí)作用域

    摘要:變量聲明結(jié)論存在變量提升,可重復(fù)多次聲明同名變量。和的出現(xiàn),很好地把中定義變量的給埋了,解決了定義同名變量導(dǎo)致變量間相互污染的問(wèn)題,保證了同一塊級(jí)作用域下,變量名的唯一性。中規(guī)定,函數(shù)本身的作用域在其所在的塊級(jí)作用域當(dāng)中。 引言 萬(wàn)丈高樓平地起,欲練此功,必先打好基本功: )。 ES6已經(jīng)融入到了我們的日常開(kāi)發(fā)當(dāng)中,甚至一些ES7的特性也已經(jīng)在普遍使用,但由于瀏覽器的支持問(wèn)題,ES6的...

    Olivia 評(píng)論0 收藏0
  • ES6—擴(kuò)展運(yùn)算符和rest運(yùn)算符(6)

    摘要:擴(kuò)展運(yùn)算符簡(jiǎn)介擴(kuò)展運(yùn)算符是三個(gè)點(diǎn),可以將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列。在實(shí)際項(xiàng)目中靈活應(yīng)用擴(kuò)展運(yùn)算符運(yùn)算符,能寫(xiě)出更精簡(jiǎn)易讀性高的代碼。 1、擴(kuò)展運(yùn)算符簡(jiǎn)介 擴(kuò)展運(yùn)算符( spread )是三個(gè)點(diǎn)(...),可以將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列。 說(shuō)的通俗易懂點(diǎn),有點(diǎn)像化骨綿掌,把一個(gè)大元素給打散成一個(gè)個(gè)單獨(dú)的小元素。 showImg(https://segmentfault.c...

    Amio 評(píng)論0 收藏0
  • es6 promise面試

    摘要:執(zhí)行函數(shù)會(huì)返回一個(gè)遍歷器對(duì)象,每一次函數(shù)里面的都相當(dāng)一次遍歷器對(duì)象的方法,并且可以通過(guò)方法傳入自定義的來(lái)改變函數(shù)的行為。函數(shù)可以通過(guò)配合函數(shù)更輕松更優(yōu)雅的實(shí)現(xiàn)異步編程和控制流管理。它和構(gòu)造函數(shù)的不同點(diǎn)類的內(nèi)部定義的所有方法,都是不可枚舉的。 let const的命令 在ES6之前,聲明變量只能用var,var方式聲明變量其實(shí)是很不合理的,準(zhǔn)確的說(shuō),是因?yàn)镋S5里面沒(méi)有塊級(jí)作用域是很不合...

    timger 評(píng)論0 收藏0
  • ES6(ECMAScript 6)新特性

    摘要:目前的標(biāo)準(zhǔn)化工作正在進(jìn)行中,預(yù)計(jì)會(huì)在年月份放出正式敲定的版本。反的方法可以接收一個(gè)參數(shù)并且返回值取決與它的構(gòu)造函數(shù)。之后就可以用這個(gè)返回值做為對(duì)象的鍵了。 本文基于lukehoban/es6features ,同時(shí)參考了大量博客資料,具體見(jiàn)文末引用。 ES6(ECMAScript 6)是即將到來(lái)的新版本JavaScript語(yǔ)言的標(biāo)準(zhǔn),代號(hào)harmony(和諧之意,顯然沒(méi)有跟上我國(guó)的步伐...

    impig33 評(píng)論0 收藏0
  • JavaScript 是如何工作:模塊構(gòu)建以對(duì)應(yīng)打包工具

    摘要:掛機(jī)科了次使用這個(gè)結(jié)構(gòu),匿名函數(shù)就有了自己的執(zhí)行環(huán)境或閉包,然后我們立即執(zhí)行。注意,匿名函數(shù)的圓括號(hào)是必需的,因?yàn)橐躁P(guān)鍵字開(kāi)頭的語(yǔ)句通常被認(rèn)為是函數(shù)聲明請(qǐng)記住,中不能使用未命名的函數(shù)聲明。 這是專門(mén)探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 20 篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過(guò)了前面的章節(jié),可以在這里找到它們: ...

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

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

0條評(píng)論

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