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

資訊專欄INFORMATION COLUMN

Set & Map:新生的數(shù)據(jù)集合及其弱引用衍生

AprilJ / 2881人閱讀

摘要:前言新增了兩種基本的原生數(shù)據(jù)集合和加上和現(xiàn)在共有四種,以及由兩者衍生出的弱引用集合和。其本身是生成實(shí)例數(shù)據(jù)集合的構(gòu)造函數(shù),可以接受一個(gè)數(shù)組或具有接口的數(shù)據(jù)結(jié)構(gòu)作為參數(shù)用來(lái)初始化。返回鍵值對(duì)的遍歷器對(duì)象,鍵值對(duì)為鍵名鍵值。

前言

ES6新增了兩種基本的原生數(shù)據(jù)集合:SetMap(加上ArrayObject現(xiàn)在共有四種),以及由兩者衍生出的弱引用集合:WeakSetWeakMap。從某個(gè)不無(wú)狹隘的角度看(不無(wú)狹隘?到底有多狹隘多不狹隘呢?),Set更為類似Array集合的某種提升,而Map則為Object集合的增強(qiáng),雖然兩類在本質(zhì)上就不相同。

1 Set

其本身是生成Set實(shí)例(數(shù)據(jù)集合)的構(gòu)造函數(shù),可以接受一個(gè)數(shù)組(或具有iterable接口的數(shù)據(jù)結(jié)構(gòu))作為參數(shù)用來(lái)初始化。存儲(chǔ)的結(jié)構(gòu)類似數(shù)組,不過(guò)成員的值在集合中都是唯一的,不會(huì)出現(xiàn)重復(fù)值。實(shí)際的存儲(chǔ)順序(也是遍歷順序)與插入順序一致,行為的結(jié)果和數(shù)組相同。

其數(shù)據(jù)結(jié)構(gòu)中沒(méi)有鍵名,但為了和Map統(tǒng)一,也可認(rèn)為鍵名和健值是同一值(會(huì)在遍歷小節(jié)中介紹)。內(nèi)部使用的相等判斷規(guī)則,除了認(rèn)為NaN等于NaN,與全等于一致。利用Set中沒(méi)有重復(fù)值的特性,可以簡(jiǎn)單的實(shí)現(xiàn)數(shù)組去重。最后一點(diǎn),其實(shí)例的字符串標(biāo)簽為[Object Set]——厲害啦,都自立了門(mén)戶。

let set = new Set([1, 2]);
console.log(...set); // 1 2
console.log({}.toString.call(set)); // [Object Set]

let o = {};
[...new Set([1, 2, 2])]; // [1, 2]
[...new Set([1, NaN, NaN])]; // [1, NaN]
[...new Set([1, o, o])]; // [1, o]
[...new Set([1, {}, {}])]; // [1, {}, {}]

F(1, {}, 1); // [1, {}],可解析帶遍歷器的類數(shù)組對(duì)象。
function F() {
  console.log([...new Set(arguments)]);
}

let o = { length: 0 };
[...new Set(o)]; // 報(bào)錯(cuò),不能自動(dòng)解析不帶遍歷器接口的類數(shù)組對(duì)象。

// 作為簡(jiǎn)單的刪除數(shù)組重復(fù)值的方法。
removeDuplicateValues([1, 2, 2, 3]); // [1, 2, 3]
function removeDuplicateValues(arr) {
  return [...new Set(arr)];
}

關(guān)于相等的小知識(shí)
兩值是否相等一般指的是是否全等,里面有兩個(gè)比較特殊的例子:NaN & NaN-0 & +0。在全等中,NaN不等于NaN,-0等于+0都為零。但這兩種認(rèn)定在某些場(chǎng)合中不太接地氣,為此ES6給出用于判斷兩值是否相等方法Object.is()中,認(rèn)定NaN等于NaN,-0不等于+0。

0除以1為正零,0除以負(fù)1為負(fù)零,兩者在生成上方式上看的確不應(yīng)該相等。

非數(shù)NaN是一個(gè)不是數(shù)字的數(shù)字(類型依舊為數(shù)字型),沒(méi)有具體的值,因此兩個(gè)NaN是不相等的。不過(guò)在用NaN作為映射中的鍵時(shí),它應(yīng)該代指這一類型而不是具體的個(gè)體。否者我先設(shè)置代碼NaN指向貂蟬,再設(shè)置NaN指代西施,晚上寬衣解帶后發(fā)現(xiàn)仆人竟將兩人同時(shí)安置在被窩之中,笑盈盈水靈靈的。這,讓我如何是好!

2 Map

其本身是生成Map實(shí)例(數(shù)據(jù)集合)的構(gòu)造函數(shù),可以接受一個(gè)包含鍵值對(duì)的數(shù)組(或具有iterable接口的數(shù)據(jù)結(jié)構(gòu))作為參數(shù)用來(lái)初始化。簡(jiǎn)單的說(shuō),鍵值對(duì)是包含兩元素的數(shù)組,前者為鍵名后者為鍵值。其存儲(chǔ)的結(jié)構(gòu)類似Object,不會(huì)出現(xiàn)重復(fù)的鍵名,之中使用的相等判定方法與Set一致。其實(shí)例的字符串標(biāo)簽為[Object Map]

其與對(duì)象主要有兩點(diǎn)不同。一是鍵名,對(duì)象的鍵名只能是字符串或Symbol值,而Map可以是任意類型,它提供了更為完善的值對(duì)值的Hash結(jié)構(gòu)。二是遍歷順序,對(duì)象的遍歷順序大致為先數(shù)值再字符串后Symbol值(會(huì)在遍歷小節(jié)中介紹),而Map是簡(jiǎn)單的與存儲(chǔ)順序保持一致,這在實(shí)際操作中比較有用。

let map = new Map([[1, "one"], [2, "two"]]);
console.log(...map); // [1,"one"] [2, "two"]
console.log({}.toString.call(map)); // [Object Map]

let o = {};
[...new Map([[o, 1], [o, 2]])]; // [[o, 2]]
[...new Map([[{}, 1], [{}, 2]])]; // [[{}, 2], [{}, 2]]
[...new Map([[null, 1], [undefined, 2]])]; // [[null, 1], [undefined, 2]]

let o = {
  0: [1, "1"],
  1: [2, "2"],
  length: 2,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
};
[...new Map(o)]; // [[1, "1"], [2, "2"]]
3 實(shí)例方法

關(guān)于SetMap的完善API請(qǐng)點(diǎn)擊鏈接查看。

這里會(huì)將SetMap放置在一起,在操作方法和遍歷方法上進(jìn)行異同性說(shuō)明,方便區(qū)分和記憶。另外,為了在方法操作上統(tǒng)一SetMap,如Set小節(jié)中提及的,我們可以認(rèn)為Set是鍵名與鍵值為同一值的存在(JS本身就是這樣做的)。

3.1 操作方法

兩者都有的操作方法
判斷(has),傳入鍵名,返回布爾值。
刪除(delete),傳入鍵名,有且成功刪除為true,否則為false。
清空(clear),無(wú)需傳參,沒(méi)有返回值。

Set獨(dú)有的操作方法
新增(add),傳入值,返回實(shí)例本身。
沒(méi)有相應(yīng)的獲取方法,因?yàn)楂@取需傳入的值就是應(yīng)所傳出的值。

let set = new Set();

set.add(1).add(NaN); // set.size 為 2。
set.has(NaN); // true
set.delete(NaN); // true
set.has(NaN); // false
set.delete(2); // false
set.clear();

console.log(...set); // 它變得一無(wú)所有,只剩一具空殼。

Map獨(dú)有的操作方法
新增(set),傳入鍵名和鍵值,有則更新沒(méi)則新增,返回實(shí)例本身。
獲取(get),傳入鍵名,返回相應(yīng)值沒(méi)有則為undefined。

let o = [1, 2, 3];
let map = new Map();

map.set(o, 1).set(o, 2); // map.size 為 1
map.has(o); // true
map.get(o); // 2
map.get([1, 2, 3]); // undefined
map.delete(o); // true
map.clear();

console.log(...map); // 它再次一無(wú)所有,只剩愈發(fā)饑渴的獸心。
3.2 遍歷方法

返回鍵名的遍歷器對(duì)象(keys)。
返回鍵值的遍歷器對(duì)象(values)。
返回鍵值對(duì)的遍歷器對(duì)象(entries),鍵值對(duì)為[鍵名, 鍵值]。
遍歷每個(gè)成員(forEach),使用方式與Array的方法相同。

因?yàn)?b>Set的鍵名和鍵值相同,所以一般只使用values方法獲取全部值。而Map則根據(jù)相應(yīng)需求獲取即可。

let set = new Set([1, 2, 3]);
let map = new Map([[1, "one"], [null, NaN]]);

[...set.values()]; // [1, 2, 3]
[...set.keys()]; // [1, 2, 3]
[...set.entries()]; // [[1, 1], [2, 2], [3, 3]]

[...map.values()]; // ["one", NaN]
[...map.keys()]; // [1, null]
[...map.entries()]; // [[1, "one"], [null, NaN]]

兩者的forEach方法與數(shù)組的不同點(diǎn)在于回調(diào)函數(shù)的第二個(gè)參數(shù),前者為該項(xiàng)的鍵名后者為該項(xiàng)的序號(hào)。

let set = new Set([1, 2, 3]);
let map = new Map([[1, "one"], [null, NaN]]);

set.forEach((v, i) => console.log(i)); // 1, 2, 3
map.forEach((v, i) => console.log(i)); // 1, null
[1, 2, 3].forEach((v, i) => console.log(i)); // 0, 1, 2

對(duì)象屬性的遍歷順序
不同遍歷對(duì)象的方法面向的數(shù)據(jù)種類不同,但總的說(shuō)其遍歷順序是這樣的:先找到其中可轉(zhuǎn)化成數(shù)值的屬性并按升序遍歷,再遍歷字符串屬性按加入時(shí)間的前后,最后遍歷Symbol值按加入時(shí)間的前后。Map的遍歷順序即其被插入時(shí)的順序,嗯,總有些色咪咪的味道。

let obj = {
  "0": 0,
  1: 1,
  "b": 2,
  "a": 3,
  [Symbol(2)]: 4,
  [Symbol(1)]: 5
};

Reflect.ownKeys(obj); // ["0", "1", "b", "a", Symbol(2), Symbol(1)]
4 弱引用集合

弱引用集合WeakSetWeakMap是由SetMap分別衍生出的,其與本體的異同點(diǎn)一致,因此只對(duì)WeakMap進(jìn)行說(shuō)明。

在JS的垃圾回收機(jī)制中,對(duì)象會(huì)在沒(méi)有引用時(shí)(可意為使用)被回收。這說(shuō)明著,如果有個(gè)數(shù)據(jù)集合(數(shù)組、對(duì)象、SetMap)中包含了某對(duì)象(在使用它),那么在此數(shù)據(jù)集合被回收之前該對(duì)象都不能被回收。這很容易導(dǎo)致內(nèi)存泄漏(專有名詞,可簡(jiǎn)單理解為內(nèi)存被沒(méi)用的數(shù)據(jù)占據(jù))。

弱引用集合的設(shè)計(jì)目的就是為了解決這個(gè)問(wèn)題。弱引用顧名思義是指雖然某對(duì)象被此集合引用了,但該引用不被引擎保護(hù),不被垃圾回收裝置考慮在內(nèi),該回收時(shí)就得乖乖的被回收。那些被慣成畸形的家伙們,要知道,媽媽的懷抱可不是個(gè)萬(wàn)全的地方哦,唯有死神的才是。

WeakMap的行為與Map除了以下幾點(diǎn)不同外,可以認(rèn)為是一致的。
WeakMap的鍵名只能是對(duì)象(不包括null),否者報(bào)錯(cuò)。如果能放入普通類型,那有什么意義呢?
WeakMap的鍵名是動(dòng)態(tài)不定的,不知道什么時(shí)候會(huì)被回收。鍵名指代的對(duì)象被回收后,該項(xiàng)會(huì)被自動(dòng)消除。
因?yàn)轫?xiàng)數(shù)的動(dòng)態(tài)性,所以不能被遍歷(沒(méi)有遍歷方法),沒(méi)有size屬性,沒(méi)有cealr方法。

let o = {};
let wm = new WeakMap();

wm.set(1, 1); // 報(bào)錯(cuò),1 不是對(duì)象。
wm.set(o, 1);
wm.has(o); // true
wm.get(o); // 1
wm.delete(o); // true

"size" in wm; // false
"clear" in wm; // false
"values" in wm; // false

弱引用集合的優(yōu)點(diǎn)在于,我們可以任意為其注冊(cè)對(duì)象,而不用擔(dān)心內(nèi)存泄漏。典型的應(yīng)用場(chǎng)景是將DOM與數(shù)據(jù)進(jìn)行綁定。一些要在DOM中綁定數(shù)據(jù)的庫(kù)中,比如d3,會(huì)直接在DOM對(duì)象上設(shè)置屬性進(jìn)行保存。但在日常組建單頁(yè)面程序中的某個(gè)階段,想將DOM與數(shù)據(jù)聯(lián)系在一起時(shí),我們顯然會(huì)優(yōu)先選用數(shù)據(jù)映射的方式。而弱引用集合的出現(xiàn),更加優(yōu)化了這種方式。

在下面的示例中,每次點(diǎn)擊請(qǐng)求數(shù)據(jù)后都會(huì)生成幫了相應(yīng)數(shù)據(jù)項(xiàng)的li標(biāo)簽,并將該標(biāo)簽與相應(yīng)的數(shù)據(jù)進(jìn)行綁定。在這一系列輪回存儲(chǔ)綁定中,因?yàn)?b>WeakMap的弱引用特性,我們不需要關(guān)心已經(jīng)被刪除的DOM元素。每次只需進(jìn)行相同的操作,方便安心,省時(shí)省力。



    延伸閱讀

    ES6精華:Symbol
    ES6精華:解構(gòu)賦值
    ES6精華:函數(shù)擴(kuò)展
    ES6精華:Proxy & Reflect
    Iterator:訪問(wèn)數(shù)據(jù)集合的統(tǒng)一接口

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

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

    相關(guān)文章

    • 《深入理解java虛擬機(jī)》學(xué)習(xí)筆記系列——垃圾收集器&內(nèi)存分配策略

      摘要:虛擬機(jī)所處的區(qū)域,則表示它是屬于新生代收集器還是老年代收集器。虛擬機(jī)總共運(yùn)行了分鐘,其中垃圾收集花掉分鐘,那么吞吐量就是。收集器線程所占用的數(shù)量為。 本文主要從GC(垃圾回收)的角度試著對(duì)jvm中的內(nèi)存分配策略與相應(yīng)的垃圾收集器做一個(gè)介紹。 注:還是老規(guī)矩,本著能畫(huà)圖就不BB原則,盡量將各知識(shí)點(diǎn)通過(guò)思維導(dǎo)圖或者其他模型圖的方式進(jìn)行說(shuō)明。文字僅記錄額外的思考與心得,以及其他特殊情況 內(nèi)存...

      calx 評(píng)論0 收藏0
    • 《深入理解ES6》筆記——Set集合Map集合(7)

      摘要:常被用來(lái)檢查對(duì)象中是否存在某個(gè)鍵名,集合常被用來(lái)獲取已存的信息。返回一個(gè)布爾值,表示該值在中存在與否。集合存放對(duì)象的弱引用,當(dāng)該對(duì)象的其他強(qiáng)引用被清除時(shí),集合中的弱引用也會(huì)自動(dòng)被垃圾回收機(jī)制回收,追蹤成組的對(duì)象是該集合最好的使用方式。 Map和Set都叫做集合,但是他們也有所不同。Set常被用來(lái)檢查對(duì)象中是否存在某個(gè)鍵名,Map集合常被用來(lái)獲取已存的信息。 Set Set是有序列表,含...

      Charlie_Jade 評(píng)論0 收藏0
    • 細(xì)說(shuō)es6中SetMap

      摘要:返回一個(gè)布爾值,表示該值是否為的成員。返回鍵名的遍歷器返回鍵值的遍歷器返回鍵值對(duì)的遍歷器使用回調(diào)函數(shù)遍歷每個(gè)成員需要特別指出的是,的遍歷順序就是插入順序。該數(shù)組的所有成員,都會(huì)自動(dòng)成為實(shí)例對(duì)象的成員。這意味著,數(shù)組的成員只能是對(duì)象。 1.Set ES6 提供了新的數(shù)據(jù)結(jié)構(gòu) Set。它類似于數(shù)組,但是成員的值都是唯一的,沒(méi)有重復(fù)的值。Set 本身是一個(gè)構(gòu)造函數(shù),用來(lái)生成 Set 數(shù)據(jù)結(jié)構(gòu)...

      Ryan_Li 評(píng)論0 收藏0
    • 【ES6腳丫系列】Set+WeakSet+Map+WeakMap

      摘要:返回一個(gè)布爾值,表示該值是否為的成員。清除所有成員,沒(méi)有返回值。返回的都是遍歷器對(duì)象。結(jié)構(gòu)的實(shí)例的方法,用于對(duì)每個(gè)成員執(zhí)行某種操作,沒(méi)有返回值。這個(gè)特點(diǎn)意味著,無(wú)法引用的成員,因此是不可遍歷的。數(shù)組成員是一個(gè)或多個(gè)表示鍵值對(duì)的一維數(shù)組。 本文字?jǐn)?shù):4700+,閱讀時(shí)間約10分鐘。 如果有理解不到位的地方,歡迎大家糾錯(cuò)。 一、Set 【01】Set是一種數(shù)據(jù)結(jié)構(gòu)。類似于數(shù)組,但是成員的值...

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

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

    0條評(píng)論

    閱讀需要支付1元查看
    <