亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

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

AprilJ / 2927人閱讀

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

前言

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

1 Set

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

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

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ù)組對象。
function F() {
  console.log([...new Set(arguments)]);
}

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

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

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

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

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

2 Map

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

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

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 實例方法

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

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

3.1 操作方法

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

Set獨有的操作方法
新增(add),傳入值,返回實例本身。
沒有相應(yīng)的獲取方法,因為獲取需傳入的值就是應(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); // 它變得一無所有,只剩一具空殼。

Map獨有的操作方法
新增(set),傳入鍵名和鍵值,有則更新沒則新增,返回實例本身。
獲取(get),傳入鍵名,返回相應(yīng)值沒有則為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); // 它再次一無所有,只剩愈發(fā)饑渴的獸心。
3.2 遍歷方法

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

因為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ào)函數(shù)的第二個參數(shù),前者為該項的鍵名后者為該項的序號。

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

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

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分別衍生出的,其與本體的異同點一致,因此只對WeakMap進行說明。

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

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

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

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

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

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



    延伸閱讀

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

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

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

    相關(guān)文章

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

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

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

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

      Charlie_Jade 評論0 收藏0
    • 細說es6中SetMap

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

      Ryan_Li 評論0 收藏0
    • 【ES6腳丫系列】Set+WeakSet+Map+WeakMap

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

      lyning 評論0 收藏0

    發(fā)表評論

    0條評論

    閱讀需要支付1元查看
    <