摘要:中模擬與長久以來,數(shù)組一直是中唯一的集合類型。用數(shù)組初始化集合事實(shí)上,只要是可迭代對(duì)象數(shù)組集合集合,都可以作為構(gòu)造函數(shù)的參數(shù)。構(gòu)造函數(shù)通過迭代器從參數(shù)中提取值。
ES5中模擬Set與Map
長久以來,數(shù)組一直是JavaScript中唯一的集合類型。如果開發(fā)者們需要使用非數(shù)值型索引,就會(huì)用非數(shù)組對(duì)象創(chuàng)建所需的數(shù)據(jù)結(jié)構(gòu),而這就是Set集合與Map集合的早期實(shí)現(xiàn)。
一般來說,Set集合常被用于檢查對(duì)象中是否存在某個(gè)鍵名,而Map集合常被用于獲取已存在的信息。
ES5模擬的Set集合var set = Object.create(null); set.foo = true; // 檢查屬性是否存在 if(set.foo) { // 要執(zhí)行的代碼 }
ES5中,開發(fā)者們經(jīng)常用類似的方法檢查對(duì)象的某個(gè)屬性是否存在。
ES5模擬的Map集合var map = Object.create(null); map.foo = "bar"; // 獲取已存值 var value = map.foo; console.log(value); // "bar"
模擬這兩種集合對(duì)象的唯一區(qū)別是存儲(chǔ)的值不同。
ES5模擬解決方案的問題一般情況下,確實(shí)可以用對(duì)象來模擬Set集合與Map集合,但如果觸碰到對(duì)象屬性的某些限制,情況會(huì)變得復(fù)雜。請(qǐng)看這段代碼:
var map = Object.create(null); map[5] = "foo"; console.log(map["5"]); // "foo"
由于對(duì)象屬性名必須是字符串類型,示例中數(shù)值型的map[5],會(huì)被自動(dòng)轉(zhuǎn)換成字符串map["5"]。如果你想分別用數(shù)字和字符串作為對(duì)象屬性的鍵名,則內(nèi)部的自動(dòng)轉(zhuǎn)換機(jī)制會(huì)導(dǎo)致許多問題。
再看下面這個(gè)示例:
var map = Object.create(null), key1 = {}, key2 = {}; map[key1] = "foo"; console.log(map[key2]); // "foo"
同樣,由于對(duì)象屬性名必須是字符串,代碼中的map[key1]和map[key2]都將被轉(zhuǎn)換成map["[object object]"]。這種錯(cuò)誤很難被發(fā)現(xiàn)。
對(duì)于Map集合來說,如果它的屬性值是假值,則在要求使用布爾值的情況下(例如在if語句中)會(huì)被自動(dòng)轉(zhuǎn)換為false。強(qiáng)制轉(zhuǎn)換本身沒有問題,但如果考慮這個(gè)值的使用場景,就有可能發(fā)生問題。例如:
var map = Object.create(null); map.count = 1; // 本意是檢查"count"屬性是否存在,實(shí)際上檢查的是該值是否非零 if (map.count) { // 要執(zhí)行的代碼 }
這個(gè)示例有些模棱兩可的地方。在if語句中,我們是檢查map.count是否存在,還是檢查值是否非零?由于value的值是1,為真值,if語句中的代碼將被執(zhí)行。然而,如果map.count的值為0或者不存在,if語句中的代碼將不被執(zhí)行。
大型應(yīng)用中,一旦發(fā)生此類問題將難以定位和調(diào)試,促使ES6加入Set與Map集合兩種新特性。
ES6中的Set集合ES6新增的Set是一種集合類型的數(shù)據(jù)結(jié)構(gòu),承載著有序不可重復(fù)的值。
Set集合的相關(guān)操作new Set()構(gòu)造函數(shù):創(chuàng)建Set集合
add()方法:往集合添加元素
size屬性:集合長度
has()方法:判斷集合內(nèi)是否包含某元素
delete()方法:從集合中刪除某元素
clear()方法:清空集合元素
forEach()方法:遍歷集合元素
相關(guān)操作示例:
let set = new Set(); set.add("5"); set.add(5); // 不會(huì)強(qiáng)制類型轉(zhuǎn)換,數(shù)字5和字符串"5"可以作為兩個(gè)獨(dú)立元素存在 set.add(5); // 重復(fù) - 本次調(diào)用直接被忽略 console.log(set.has(5)); // true console.log(set.has("5")); // true console.log(set.has(6)); // false console.log(set.size); // 2 set.delete(5); console.log(set.has(5)); // false console.log(set.has("5")); // true console.log(set.size); // 1 set.clear(); console.log(set.has("5")); // false console.log(set.size); // 0
如果向Set集合添加多個(gè)對(duì)象,它們之間也是彼此獨(dú)立的:
let set = new Set(); key1 = {}, key2 = {}; set.add(key1); set.add(key2); console.log(set.size); // 2
由于key1和key2不會(huì)被轉(zhuǎn)換成字符串,因而它們?cè)赟et集合中是兩個(gè)獨(dú)立元素。
用數(shù)組初始化Set集合let set = new Set([1, 2, 3, 4, 5, 5, 5, 5]); console.log(set.size); // 5
事實(shí)上,只要是可迭代對(duì)象(數(shù)組、Set集合、Map集合),都可以作為Set構(gòu)造函數(shù)的參數(shù)。構(gòu)造函數(shù)通過迭代器從參數(shù)中提取值。
Set集合的forEach方法Set集合的forEach方法與Map集合和數(shù)組中的forEach()方法類似,回調(diào)函數(shù)都接受3個(gè)參數(shù):
Set集合當(dāng)前遍歷元素的值
Set集合當(dāng)前遍歷元素的鍵(Set集合鍵與值相同;數(shù)組是索引值)
Set集合本身
let set = new Set([1, 2]); set.forEach(function(value, key, ownerSet) { console.log(key + " " + value); console.log(ownerSet === set); });
以上示例輸出的內(nèi)容:
1 1 true 2 2 true
如果需要在回調(diào)函數(shù)中使用this引用,則可以將它作為第二個(gè)參數(shù)傳入forEach()函數(shù):
let set = new Set([1, 2]); let processor = { output(value) { console.log(value); }, process(dataSet) { dataSet.forEach(function(value)) { this.output(value); // 從而正確調(diào)用到processor.output()方法 }, this); } }; processor.process(set);
當(dāng)然,你可以使用箭頭函數(shù),這樣就無需再講this作為第二個(gè)參數(shù)傳入了:
let set = new Set([1, 2]); let processor = { output(value) { console.log(value); }, process(dataSet) { dataSet.forEach(value => this.output(value)); } }; processor.process(set);將Set集合轉(zhuǎn)換為數(shù)組
盡管Set集合適合用來跟蹤多個(gè)值,而且又可以通過forEach()方法操作集合中的每一個(gè)元素,但是你不能像訪問數(shù)組元素那樣直接通過索引訪問集合中的元素。如有需要,先將Set集合轉(zhuǎn)換成一個(gè)數(shù)組。
展開運(yùn)算符可以很方便地將諸如Set集合的可迭代對(duì)象轉(zhuǎn)換為數(shù)組:
let set = new Set([1, 2, 3, 3, 3, 4, 5]), array = [...set]; console.log(array); // [1,2,3,4,5]
如果已經(jīng)創(chuàng)建過一個(gè)數(shù)組,想要復(fù)制它并創(chuàng)建一個(gè)無重復(fù)元素的新數(shù)組,則上述這個(gè)方法十分管用,請(qǐng)看:
function eliminateDuplicates(items) { return [...new Set(items)]; } let numbers = [1, 2, 3, 3, 3, 4, 5], noDuplicates = eliminateDuplicates(numbers); console.log(noDuplicates); // [1,2,3,4,5]ES6中的Map集合
ES6中的Map類型是一種存儲(chǔ)著許多鍵值對(duì)的有序列表,其中的鍵名和對(duì)應(yīng)的值支持所有的數(shù)據(jù)類型。
Map集合的相關(guān)操作new Map()構(gòu)造函數(shù):創(chuàng)建Map集合
set()方法:往集合中添加新元素[鍵值對(duì)]
size屬性:集合元素個(gè)數(shù)
get()方法:從集合中獲取某個(gè)鍵對(duì)應(yīng)的值
has()方法:判斷集合中是否存在某鍵的元素
delete()方法:從集合中刪除某鍵的元素
clear()方法:清空集合元素
forEach()方法:遍歷集合元素
相關(guān)操作示例:
let map = new Map(); map.set("name", "Nicholas"); map.set("age", 25); console.log(map.size); // 2 console.log(map.has("name")); // true console.log(map.get("name")); // "Nicholas" console.log(map.has("age")); // true console.log(map.get("age")); // 25 map.delete("name"); console.log(map.has("name")); // false console.log(map.get("name")); // undefined console.log(map.size); // 1 map.clear(); console.log(map.has("name")); // false console.log(map.get("name")); // undefined console.log(map.has("age")); // false console.log(map.get("age")); // undefined console.log(map.size); // 0用數(shù)組初始化Map集合
let map = new Map([["name", "Nicholas"], ["age", 25]]); console.log(map.has("name")); // true console.log(map.get("name")); // "Nicholas" console.log(map.has("age")); // true console.log(map.get("age")); // 25 console.log(map.size); // 2Map集合的forEach方法
Map集合的forEach方法與Set集合和數(shù)組中的forEach()方法類似,回調(diào)函數(shù)都接受3個(gè)參數(shù):
Map集合當(dāng)前遍歷元素的值
Map集合當(dāng)前遍歷元素的鍵
Map集合本身
let map = new Map([["name", "Nicholas"], ["age", 25]]); map.forEach(function(value, key, ownerMap) { console.log(key + " " + value); console.log(ownerMap === map); });
會(huì)按照鍵值對(duì)插入Map集合順序遍歷,輸出內(nèi)容:
name Nicholas true age 25 true
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85105.html
摘要:前言新增了兩種基本的原生數(shù)據(jù)集合和加上和現(xiàn)在共有四種,以及由兩者衍生出的弱引用集合和。其本身是生成實(shí)例數(shù)據(jù)集合的構(gòu)造函數(shù),可以接受一個(gè)數(shù)組或具有接口的數(shù)據(jù)結(jié)構(gòu)作為參數(shù)用來初始化。返回鍵值對(duì)的遍歷器對(duì)象,鍵值對(duì)為鍵名鍵值。 前言 ES6新增了兩種基本的原生數(shù)據(jù)集合:Set和Map(加上Array和Object現(xiàn)在共有四種),以及由兩者衍生出的弱引用集合:WeakSet和WeakMap。從...
摘要:由于和不會(huì)被轉(zhuǎn)換為字符串,所以在內(nèi)部是不同的項(xiàng),如果他們被轉(zhuǎn)化為字符串,那么都會(huì)等于,如果多次調(diào)用并傳入相同的值作為參數(shù)。第二次重復(fù)傳入并不會(huì)被添加到集合中,那么的屬性值還是為。的方法和共享了幾個(gè)方法。小結(jié)正式將與引入。 se5中的set與map 在est5中開發(fā)者使用對(duì)象屬性來模擬。set多用于檢查鍵的存在,map多用于提取數(shù)據(jù)。 { let set = Object.cre...
摘要:常被用來檢查對(duì)象中是否存在某個(gè)鍵名,集合常被用來獲取已存的信息。返回一個(gè)布爾值,表示該值在中存在與否。集合存放對(duì)象的弱引用,當(dāng)該對(duì)象的其他強(qiáng)引用被清除時(shí),集合中的弱引用也會(huì)自動(dòng)被垃圾回收機(jī)制回收,追蹤成組的對(duì)象是該集合最好的使用方式。 Map和Set都叫做集合,但是他們也有所不同。Set常被用來檢查對(duì)象中是否存在某個(gè)鍵名,Map集合常被用來獲取已存的信息。 Set Set是有序列表,含...
閱讀 3789·2021-09-22 15:17
閱讀 1975·2021-09-22 14:59
閱讀 2377·2020-12-03 17:00
閱讀 3244·2019-08-30 15:55
閱讀 522·2019-08-30 11:23
閱讀 3520·2019-08-29 13:56
閱讀 546·2019-08-29 12:54
閱讀 2275·2019-08-29 12:49