- 在ES6之前仅仆,我們存儲數(shù)據(jù)的結(jié)構(gòu)主要有兩種:數(shù)組、對象垢袱。
- 在ES6中新增了另外兩種數(shù)據(jù)結(jié)構(gòu):Set墓拜、Map,以及它們的另外形式WeakSet请契、WeakMap咳榜。
Set和WeakSet
Set的使用
- Set是一個新增的數(shù)據(jù)結(jié)構(gòu),可以用來保存數(shù)據(jù)爽锥,類似于數(shù)組涌韩,但是和數(shù)組的區(qū)別是元素不能重復(fù)。
- 創(chuàng)建Set我們需要通過Set構(gòu)造函數(shù)(暫時沒有字面量創(chuàng)建的方式):
- 可以發(fā)現(xiàn)Set中存放的元素是不會重復(fù)的氯夷,那么Set有一個非常常用的功能就是給數(shù)組去重臣樱。
//通過new關(guān)鍵字創(chuàng)建
const set1 = new Set();
set1.add(1)
set1.add(2)
set1.add(2)
set1.add({name:13})
console.log(set1); //Set(3) { 1, 2, { name: 13 } }
//根據(jù)數(shù)組創(chuàng)建set對象
const set2 = new Set([1,2,3,4,5,5])
console.log(set2); //Set(5) { 1, 2, 3, 4, 5 }
//將set轉(zhuǎn)變?yōu)閿?shù)組
const newArray1 = [...set2]
console.log(newArray1);
const newArray2 = Array.from(set2)
console.log(newArray2);
Set的常見屬性和方法
- size:返回Set中元素的個數(shù);
method:
- add(value):添加某個元素腮考,返回Set對象本身雇毫;
- delete(value):從set中刪除和這個值相等的元素,返回boolean類型踩蔚;
- has(value):判斷set中是否存在某個元素棚放,返回boolean類型;
- clear():清空set中所有的元素馅闽,沒有返回值飘蚯;
- forEach(callback, [, thisArg]):通過forEach遍歷set;
- Set是支持for of的遍歷的福也。
WeakSet的使用
- 和Set類似的另外一個數(shù)據(jù)結(jié)構(gòu)稱之為WeakSet孝冒,也是內(nèi)部元素不能重復(fù)的數(shù)據(jù)結(jié)構(gòu)。
- 和Set的區(qū)別
區(qū)別一:WeakSet中只能存放對象類型拟杉,不能存放基本數(shù)據(jù)類型庄涡;
區(qū)別二:WeakSet對元素的引用是弱引用,如果沒有其他引用對某個對象進(jìn)行引用搬设,那么GC可以對該對象進(jìn)行回收(弱引用可以理解為有地址指向?qū)ο笱ǖ辏菍ο笠廊荒軌虮讳N毀)撕捍;
const wset = new WeakSet()
const obj1 = {
name:"zs",
age:14
}
const obj12 = {
name:"zsss",
age:142
}
wset.add(10) //報錯:invalid val used
wset.add(obj1)
wset.add(obj12)
console.log(wset);
WeakSet常見的方法:
- add(value):添加某個元素,返回WeakSet對象本身泣洞;
- delete(value):從WeakSet中刪除和這個值相等的元素忧风,返回boolean類型;
- has(value):判斷WeakSet中是否存在某個元素球凰,返回boolean類型狮腿;
const wset = new WeakSet();
const obj1 = {
name: "zs",
age: 14,
};
const obj2 = {
name: "zsss",
age: 142,
};
const obj3 = {
name: "zsss",
age: 142,
};
// wset.add(10)
wset.add(obj1);
wset.add(obj2);
console.log(wset.has(obj2)); //true
console.log(wset.has(obj3)); //false,注意
wset.delete(obj2);
console.log(wset.has(obj2)); //false
WeakSet的應(yīng)用
- 阻止其他的對象的借用調(diào)用
const wset = new WeakSet();
class Person {
constructor() {
wset.add(this); //將創(chuàng)建的對象保存到weakset中
}
running() {
//每次調(diào)用該方法先判斷weakset中是否有保證該對象呕诉,保證只有Person類的子對象可以調(diào)用
if (!wset.has(this)) {
throw new Error("不能通過其他類型的對象調(diào)用running方法");
}
console.log("running", this);
}
}
Map和WeakMap
Map的使用
- Map用于存儲映射關(guān)系缘厢。
之前我們可以使用對象來存儲映射關(guān)系,有什么區(qū)別呢甩挫?
對象存儲映射關(guān)系只能用字符串(ES6新增了Symbol)作為屬性名(key)贴硫;某些情況下我們可能希望通過其他類型作為key,比如對象伊者,這個時候會自動將對象轉(zhuǎn)成字符串來作為key英遭;那么我們就可以使用Map:
const obj = { name: "zs", age: 18, height: 1.88 };
const obj2 = { name: "zsss", age: 11, height: 1.55 };
const map1 = new Map();
map1.set(obj, "abc");
map1.set(obj2, "bcd");
console.log(map1);
/* Map(2) {
{ name: 'zs', age: 18, height: 1.88 } => 'abc',
{ name: 'zsss', age: 11, height: 1.55 } => 'bcd'
} */
console.log(map1.get(obj)); //abc
Map的常用屬性方法
- size:返回Map中元素的個數(shù);
Map常見的方法:
- set(key, value):在Map中添加key亦渗、value挖诸,并且返回整個Map對象;
- get(key):根據(jù)key獲取Map中的value法精;
- has(key):判斷是否包括某一個key税灌,返回Boolean類型;
- delete(key):根據(jù)key刪除一個鍵值對亿虽,返回Boolean類型菱涤;
- clear():清空所有的元素;
- forEach(callback, [, thisArg]):通過forEach遍歷Map洛勉;
- Map也可以通過for of進(jìn)行遍歷粘秆。
WeakMap的使用
- 和Map區(qū)別
區(qū)別一:WeakMap的key只能使用對象,不接受其他的類型作為key收毫;
區(qū)別二:WeakMap的key對對象想的引用是弱引用攻走,如果沒有其他引用引用這個對象,那么GC可以回收該對象此再;
WeakMap的常用屬性方法:
- set(key, value):在Map中添加key昔搂、value,并且返回整個Map對象输拇;
- get(key):根據(jù)key獲取Map中的value摘符;
- has(key):判斷是否包括某一個key,返回Boolean類型;
- delete(key):根據(jù)key刪除一個鍵值對逛裤,返回Boolean類型瘩绒;
WeakMap的應(yīng)用 :
- vue3響應(yīng)式原理
//WeakMap(fkey(對象):value.}):key是一個對象,弱引用
const targetMap = new WeakMap();
function getDep(target, key) {
//·1.根據(jù)對象(target)取出對應(yīng)的Map對象
let depsMap = targetMap.get(target);
if (!depsMap) {
depsMap = new Map();
targetMap.set(target, depsMap);
//·2.取出具體的dep對象
let dep = depsMap.get(key);
if (!dep) dep = new Dep();
depsMap.set(key, dep);
}
return dep;
}