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