7.(ECMAScript)es6完全解读(6)

1. 重点提炼

  • Symbol基本使用
  • Set及Weakset使用及应用场景
  • Map及Weakmap使用及应用场景

2. 新的原始数据类型Symbol

ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值。它是 JavaScript语言的第七种数据类型,前六种是:undefinednull、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol类型。凡是属性名属于 Symbol类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

  • 一种新的原始数据类型
  • 声明方式
  • 应用场景

=> 基本数据类型7种

undefined、null、boolean、number、string、object(包括数组、function)、symbol

let s1 = Symbol()
let s2 = Symbol()
console.log(s1)
console.log(s2)
console.log(s1 === s2) // false

symbol表示独一无二的,不同的Symbol,可能长得一样,但不是一个东西。

既然是独一无二的,那么两个Symbol()就一定是不相等的:

image-20201123114714717

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.14
Branch: branch02

commit description:a2.14(新的原始数据类型Symbol——使用)

tag:a2.14


以上声明方式很少使用,因为无法说明s1s2是什么!

一般会加上描述信息。

Symbol函数可以接受一个字符串作为参数,表示对 Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

let s1 = Symbol('foo')
let s2 = Symbol('bar')
console.log(s1)
console.log(s2)
console.log(s1 === s2)// false

image-20201123115036428

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.15
Branch: branch02

commit description:a2.15(新的原始数据类型Symbol——描述信息)

tag:a2.15


const obj = {
    name: 'lisi'
}
let s = Symbol(obj)
console.log(s)

如果描述参数是一个对象,它会自动调用toString方法,将其转化为字符串。

image-20201123115251409

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.16
Branch: branch02

commit description:a2.16(新的原始数据类型Symbol——描述信息是对象)

tag:a2.16


const obj = {
    name: 'lisi',
    toString() {
        return this.name
    }
}
let s = Symbol(obj)
console.log(s)

在对象里定义一个toString方法,返回当前对象的name属性。会自动调用该方法。

image-20201123115432129

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.17
Branch: branch02

commit description:a2.17(新的原始数据类型Symbol——描述信息是对象-设置toString方法)

tag:a2.17


let s = Symbol()
s.name = 'abc'
console.log(s)

Symbol不是对象,追加属性是没有用的。同时也不能new。 => let s = new Symbol()

Symbol函数前不能使用new命令,否则会报错。这是因为生成的 Symbol是一个原始类型的值,不是对象。也就是说,由于 Symbol值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。

image-20201123115952859

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.18
Branch: branch02

commit description:a2.18(新的原始数据类型Symbol——Symbol不是对象,追加属性是没有用的。)

tag:a2.18


可以将其理解为不能重复的字符串,它提供一个api=> description

let s = Symbol('foo')
console.log(s.description)

image-20201123133358375

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.19
Branch: branch02

commit description:a2.19(新的原始数据类型Symbol——api => description)

tag:a2.19


Symbol.for =>

Symbol.for() 接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol值。如果有,就返回这个 Symbol值,否则就新建一个以该字符串为名称的 Symbol值,并将其注册到全局。

let s1 = Symbol.for('foo')
let s2 = Symbol.for('foo')
console.log(s1.description)
console.log(s1 === s2) // true

Symbol.for声明的相同描述的Symbol代表同一个值。而直接用Symbol.for声明的变量,相当于定义在全局中,用for方法,它会去找,如这里,去找有没有'foo'Symbol变量,如果有则直接s2指向s1

然后直接使用Symbol声明的变量,相当于并不会在全局环境中定义,而是每次都会生成一个新的Symbol变量。

注意

Symbol.for()与Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。

image-20201123133621435

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.20
Branch: branch02

commit description:a2.20(新的原始数据类型Symbol——Symbol.for)

tag:a2.20


综上,注意通过Symbol.for声明的变量,无论在哪个位置声明,它都属于全局变量。

function foo() {
    return Symbol.for('foo')
}
const x = foo()
const y = Symbol.for('foo')
console.log(x === y) // true

true

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.21
Branch: branch02

commit description:a2.21(新的原始数据类型Symbol——通过Symbol.for声明的变量,无论在哪个位置声明,它都属于全局变量)

tag:a2.21


Symbol.keyFor => 返回一个(全局)已经登记的SymbolkeySymbol.for声明的变量定义在全局,如果仅仅是通过Symbol定义的,它并没有定义在全局。keyFor实际就是找对应Symbol是否在全局登记过。

const s1 = Symbol('foo')
console.log(Symbol.keyFor(s1)) // undefined

const s2 = Symbol.for('foo')
console.log(Symbol.keyFor(s2)) // foo

image-20201123134522592

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.22
Branch: branch02

commit description:a2.22(新的原始数据类型Symbol——Symbol.keyFor)

tag:a2.22


2.1 应用场景

2.1.1 作为属性名

描述一个班级信息的类,将人名作为key。

但是可能存在同名的同学 =>

// 班级信息
const grade = {
    张三: {address: 'xxx', tel: '111'},
    李四: {address: 'yyy', tel: '222'},
    李四: {address: 'zzz', tel: '333'},
}
console.log(grade)

但是实际只有两个人,因为对象中的key值是唯一的,如果有重复的,后定义的会覆盖先定义的。

image-20201123163425092

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.23
Branch: branch02

commit description:a2.23(新的原始数据类型Symbol——对象key值唯一)

tag:a2.23


通过变量的形式定义属性 => 仍然不能改变对象key值唯一的问题。

const stu1 = '李四'
const stu2 = '李四'
const grade = {
    [stu1]: {address: 'yyy', tel: '222'},
    [stu2]: {address: 'zzz', tel: '333'},
}
console.log(grade)

image-20201123164419810

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.24
Branch: branch02

commit description:a2.24(新的原始数据类型Symbol——通过变量的形式定义属性 => 仍然不能改变对象key值唯一的问题。)

tag:a2.24


利用Symbol来解决 => 保证姓名相同也不会与之产生冲突了。

由于每一个 Symbol值都是不相等的,这意味着 Symbol值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。

const stu1 = Symbol('李四')
const stu2 = Symbol('李四')
const grade = {
    [stu1]: {address: 'yyy', tel: '222'},
    [stu2]: {address: 'zzz', tel: '333'},
}
console.log(grade)
console.log(grade[stu1])
console.log(grade[stu2])

image-20201123175221688

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.25
Branch: branch02

commit description:a2.25(新的原始数据类型Symbol——通过Symbol保证对象的key并不冲突。)

tag:a2.25


const sym = Symbol('abc')
class User {
    constructor(name) {
        this.name = name
        this[sym] = '@abc.com'
    }
    getName() {
        return this.name + this[sym]
    }
}
const user = new User('lisi')
console.log(user.getName())

image-20201123180040044

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.26
Branch: branch02

commit description:a2.26(新的原始数据类型Symbol——通过Symbol定义对象属性。)

tag:a2.26


2.1.2 属性遍历

const sym = Symbol('abc')
class User {
    constructor(name) {
        this.name = name
        this[sym] = '@abc.com'
    }
    getName() {
        return this.name + this[sym]
    }
}
const user = new User('lisi')

for(let key in user){
    console.log(key)
}

发现只遍历出了name属性,并没有遍历出Symbol属性。

Symbol在一定程度上会对属性进行隐藏。for…in取不到Symbol类型的属性。

image-20201123180255226

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.27
Branch: branch02

commit description:a2.27(新的原始数据类型Symbol——Symbol在一定程度上会对属性进行隐藏。)

tag:a2.27


const sym = Symbol('abc')
class User {
    constructor(name) {
        this.name = name
        this[sym] = '@abc.com'
    }
    getName() {
        return this.name + this[sym]
    }
}
const user = new User('lisi')

for(let key of Object.keys(user)){
    console.log(key)
}

for…offor…in都获取不到Symbol类型的属性。

image-20201123194410945

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.28
Branch: branch02

commit description:a2.28(新的原始数据类型Symbol——for…of和for…in都获取不到Symbol类型的属性。)

tag:a2.28


const sym = Symbol('abc')
class User {
    constructor(name) {
        this.name = name
        this[sym] = '@abc.com'
    }
    getName() {
        return this.name + this[sym]
    }
}
const user = new User('lisi')

for(let key of Object.getOwnPropertySymbols(user)){
    console.log(key)
}

for…of配合 Object.getOwnPropertySymbols只能获取到Symbol类型的属性。

image-20201123194713367

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.29
Branch: branch02

commit description:a2.29(新的原始数据类型Symbol——for…of 配合 Object.getOwnPropertySymbols 只能获取到Symbol类型的属性。)

tag:a2.29


const sym = Symbol('abc')
class User {
    constructor(name) {
        this.name = name
        this[sym] = '@abc.com'
    }
    getName() {
        return this.name + this[sym]
    }
}
const user = new User('lisi')

for(let key of Reflect.ownKeys(user)){
    console.log(key)
}

for…of 配合 Reflect.ownKeys能获取到Symbol类型和普通的属性。

image-20201123200555000

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.30
Branch: branch02

commit description:a2.30(新的原始数据类型Symbol——for…of 配合 Reflect.ownKeys能获取到Symbol类型和普通的属性。)

tag:a2.30


2.1.3 消除魔术字符串

function getArea(shape) {
    let area = 0
    switch (shape) {
        case 'Triangle':
            area = 1
            break
        case 'Circle':
            area = 2
            break
    }
    return area
}
console.log(getArea('Triangle'))

'Triangle' 在代码中多次出现,很容易写错,并且形成了耦合 => 魔术字符串

1

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.31
Branch: branch02

commit description:a2.31(新的原始数据类型Symbol——魔术字符串)

tag:a2.31


Symbol类型消除魔术字符串 =>

const shapeType = {
    triangle: Symbol(),
    circle: Symbol()
}
function getArea(shape) {
    let area = 0
    switch (shape) {
        case shapeType.triangle:
            area = 1
            break
        case shapeType.circle:
            area = 2
            break
    }
    return area
}
console.log(getArea(shapeType.triangle))

1

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.32
Branch: branch02

commit description:a2.32(新的原始数据类型Symbol——Symbol类型消除魔术字符串)

tag:a2.32


3. 新的数据结构Set

JavaScript里通常使用 ArrayObject来存储数据。但是在频繁操作数据的过程中查找或者统计并需要手动来实现,并不能简单的直接使用。 比如如何保证 Array是去重的,如何统计 Object的数据总数等,必须自己去手动实现类似的需求,不是很方便。 在 ES6中为了解决上述痛点,新增了数据结构 SetMap,它们分别对应传统数据结构的“集合”和“字典”。

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

  • 一种新的数据结构
  • 常用方法
  • 遍历
  • 应用场景
  • WeakSet
// 唯一的
let s = new Set([1, 2, 3, 2])
console.log(s)

注意

初始化的参数必须是可遍历的,可以是数组或者自定义遍历的数据结构。

Set中的成员值是唯一的,不能重复。

image-20201123205455361

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.33
Branch: branch02

commit description:a2.33(新的数据结构Set——值唯一)

tag:a2.33


Set支持链式操作 => 连续增添元素

add => 添加数据

delete => 删除数据

has => 判断是否有某个值

size => 长度

clear => 清空数据

// 唯一的
let s = new Set([1, 2, 3, 2])
// 添加数据
s.add('abc').add('def')
// 删除数据
s.delete(2)
// 判断是否有某个值
console.log(s.has('abc'))
console.log(s)
// 长度
console.log(s.size)
// 清空数据
s.clear()
console.log(s)
console.log(s.size)

image-20201123210231515

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.34
Branch: branch02

commit description:a2.34(新的数据结构Set——基本使用)

tag:a2.34


// 唯一的
let s = new Set([1, 2, 3, 2])
// 添加数据
s.add('abc').add('def')

// 遍历
s.forEach(item => console.log(item))

for (let item of s) {
    console.log(item)
}

for (let item of s.keys()) {
    console.log(item)
}
for (let item of s.values()) {
    console.log(item)
}
for (let item of s.entries()) {
    console.log(item[0], item[1])
}

Set的key与value是一样的!

1
2
3
abc
def
1
2
3
abc
def
1
2
3
abc
def
1
2
3
abc
def
1 1
2 2
3 3
abc abc
def def

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.35
Branch: branch02

commit description:a2.35(新的数据结构Set——遍历)

tag:a2.35


3.1 应用场景

数组去重

let arr = [1, 2, 3, 4, 2, 3]
let s = new Set(arr)
console.log(s)

image-20201123212721884

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.36
Branch: branch02

commit description:a2.36(新的数据结构Set——数组去重)

tag:a2.36


数组合并去重set->array

=> 合并利用扩展运算符

// 合并去重 set->array
let arr1 = [1, 2, 3, 4]
let arr2 = [2, 3, 4, 5, 6]
let s = new Set([...arr1, ...arr2])
console.log(s)
// Set转为数组(两种方法)
console.log([...s])
console.log(Array.from(s))

image-20201123214208146

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.37
Branch: branch02

commit description:a2.37(新的数据结构Set——数组合并去重 set->array)

tag:a2.37


求两个数组的交集

let arr1 = [1, 2, 3, 4]
let arr2 = [2, 3, 4, 5, 6]
// 交集
let s1 = new Set(arr1)
let s2 = new Set(arr2)
let result = new Set(arr1.filter(item => s2.has(item)))
console.log(Array.from(result))

image-20201123220704988

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.38
Branch: branch02

commit description:a2.38(新的数据结构Set——求两个数组的交集)

tag:a2.38


求两个数组的差集

let arr1 = [1, 2, 3, 4]
let arr2 = [2, 3, 4, 5, 6]
let s1 = new Set(arr1)
let s2 = new Set(arr2)
// 差集
let arr3 = new Set(arr1.filter(item => !s2.has(item)))
let arr4 = new Set(arr2.filter(item => !s1.has(item)))
console.log(arr3)
console.log(arr4)
console.log([...arr3, ...arr4])

image-20201123221850703

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.38
Branch: branch02

commit description:a2.38(新的数据结构Set——求两个数组的差集)

tag:a2.38


3.2 WeakSet

es6中除了有Set对象,还提供WeakSet对象。

WeakSet对象中只能存储对象,不能存储字符串、数字、基本类型等。即WeakSet的成员只能是对象,而不能是其他类型的值。

注意:删除某个对象不可直接用{….},因为引用类型传址,并非长得一样就是一个东西。

ws.delete({
    name: 'lisi'
})

add=> 添加WeakSet对象

delete=> 删除WeakSet对象

has=> 判断是否存在WeakSet中的对象

// WeakSet
let ws = new WeakSet()
const obj1 = {
    name: 'lisi'
}
const obj2 = {
    age: 25
}
ws.add(obj1)
ws.add(obj2)
console.log(ws)

ws.delete(obj1)
console.log(ws)
console.log(ws.has(obj2))

image-20201123230257707

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.39
Branch: branch02

commit description:a2.39(新的数据结构Set——WeakSet使用)

tag:a2.98


let ws = new WeakSet()
const obj1 = {
    name: 'lisi'
}
const obj2 = {
    age: 25
}
ws.add(obj1)
ws.add(obj2)
console.log(ws)

ws.delete(obj1)
console.log(ws)
console.log(ws.has(obj2))

ws.forEach(item => console.log(item))

WeakSet没有size属性,没有办法遍历它的成员。

image-20201123231215908

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.40
Branch: branch02

commit description:a2.40(新的数据结构Set——WeakSet不可遍历)

tag:a2.40


WeakSet对象不可遍历,因为WeakSet的对象都是弱引用,在js当中存在垃圾回收机制,垃圾回收机制不考虑弱引用,即如果其他对象不再引用当前对象的时候,垃圾回收机制会自动回收这个对象占用的内存空间。实际这里垃圾回收的时候不会考虑WeakSet对象还被其他对象引用,而是直接回收。即垃圾回收机制不考虑 WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet之中。

js的垃圾回收机制,是计数的机制,如果定义一个值,它被引用一次就被加1,依次类推,如果引用次数不为0,垃圾回收不会回收该元素。但如果这种元素非常多,就会引发内存泄漏。WeakSet对象则不会考虑这种计数的机制,因此称为弱引用。

WeakSet对象应用场景 => 临时存放一些对象,和跟对象绑定相关信息。

与Set区别 =>

  • WeakSet对象只能存对象
  • Set可以循环遍历,但WeakSet不可循环遍历
  • WeakSet是一种弱引用,不会把垃圾回收机制考虑,如果其内的对象消失,则它会直接消失

4. 新的数据结构Map

ES6 提供了 Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的 Hash结构实现。如果你需要“键值对”的数据结构,MapObject更合适。

  • 一种新的数据结构
  • 常用方法
  • 遍历
  • 应用场景
  • WeakMap

Map相对应的是对象,是键值对的形式。对象的key主要有字符串和Symbol两种形式,这实际会有很多限制,然而Mapkey不仅限于这两种形式,各种类型的数据都可作为mapkey,甚至对象都可作为key

set(key, value) => 添加值

get(key) => 获取值

delete(key) => 删除

has(key) => 判断该元素是否存在

clear() => 删除所有数据

注意:如果key是引用类型的数据,一定记得用地址的方式,不可只关注值相等就直接传参。

 let map = new Map([iterable])

Iterable可以是一个数组或者其他 iterable对象,其元素为键值对(两个元素的数组,例如: [[ 1, ‘one’ ], [ 2, ‘two’ ]])。 每个键值对都会添加到新的 Mapnull会被当做 undefined

let m = new Map()
let obj = {
    name: 'lisi'
}
m.set(obj, 'es')
console.log(m)
console.log(m.get(obj))
console.log(m.has(obj))
m.delete(obj)
console.log(m)

image-20201123234156597

image-20201123234234395

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.41
Branch: branch02

commit description:a2.41(新的数据结构Map——基本使用)

tag:a2.41


new map的时候可以直接传参,用数组,第一个索引表示key,第二个索引表示value

let map = new Map([
    ['name', 'lisi'],
    ['age', 5]
])
console.log(map)

image-20201124010620725

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.42
Branch: branch02

commit description:a2.42(新的数据结构Map——数组创建)

tag:a2.42


let map = new Map([
    ['name', 'lisi'],
    ['age', 5]
])
console.log(map.size)
console.log(map.has('name'))
console.log(map.get('age'))
map.set('name', 'zhangsan')
console.log(map)

key值是唯一的,同key会被新值所覆盖。

image-20201124011441962

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.43
Branch: branch02

commit description:a2.43(新的数据结构Map——key值是唯一的,同key会被新值所覆盖。)

tag:a2.43


遍历 =>

注意:foreach遍历的回调参数第一个是value,第二个是key。而for…of是第一个是key,第二个是value,容易混乱。

let map = new Map([
    ['name', 'lisi'],
    ['age', 5]
])
map.forEach((value, key) => console.log(value, key))

for(let [key, value] of map){
    console.log(key, value)
}

for(let key of map.keys()){
    console.log(key)
}

for(let value of map.values()){
    console.log(value)
}

for(let [key, value] of map.entries()){
    console.log(key, value)
}

image-20201124011748078

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.44
Branch: branch02

commit description:a2.44(新的数据结构Map——遍历)

tag:a2.44


4.1 应用场景

实际map的应用场景和对象时差不多的,但是也有区别,如果想判断键值对是否包含哪些属性!

object得循环遍历当前的对象,检查当前是否包含某一个属性,如果使用map,只需要使用has方法即可。

map和对象相比,它的api更加灵活,并且mapkey可以是多种多样的。

并且mapsize属性可以获取键值对的个数,而object中是不能直接获取键值对的个数的,还是得靠循环遍历,一点点地计算。

对象上的原形链上的键名,还可能会和自己写的对象上的键名产生冲突。

const obj = {
    age: 5
}

obj.__proto__.age = 6
obj.__proto__.xx = 99

for(let p in obj){
    console.log(p)
}

注意:对于频繁增删键值对的时候,使用map会更有性能优势。(网上资料说明)

综上,实际使用object的场景,都可以使用map。


小结与object区别:

  • 键的类型

    一个Object的键只能是字符串或者 Symbols,但一个 Map的键可以是任意值,包括函数、对象、基本类型。

  • 键的顺序

    Map中的键值是有序的,而添加到对象中的键则不是。因此,当对它进行遍历时,Map对象是按插入的顺序返回键值。

  • 键值对的统计

    你可以通过 size属性直接获取一个 Map的键值对个数,而 Object的键值对个数只能手动计算。

  • 键值对的遍历

    Map可直接进行迭代,而 Object的迭代需要先获取它的键数组,然后再进行迭代。

  • 性能

    Map在涉及频繁增删键值对的场景下会有些性能优势。


4.2 weakmap

weakmapkey只支持引用数据类型。 => 数组、对象、function

let wm = new WeakMap()
wm.set(1, 2)

使用非引用类型的数据作为key会报错。

image-20201124013421165

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.45
Branch: branch02

commit description:a2.45(新的数据结构Map——weakmap使用非引用类型的数据作为key会报错)

tag:a2.45


weakmap支持大部分map的方法,但是不支持clear方法,也无法使用size属性,同时它也不支持遍历

weakmapweakset一样,都是弱引用,这种引用类型的值如果被垃圾回收机制回收了,那么它实例对应的键值也会被回收。它不会被垃圾回收机制的引用次数而计数,而是被其忽视。 => 有助于防止内存泄漏。

// weakmap
let wm = new WeakMap()
// wm.set(1, 2)
wm.set([1], 2)
wm.set({
    name: 'lisi'
}, 'es')
console.log(wm)
console.log(wm.size)

image-20201124014008346

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.46
Branch: branch02

commit description:a2.46(新的数据结构Map——weakmap使用)

tag:a2.46


应用场景 => 获取dom元素,将获取dom元素放入WeakMap,可以存储一些信息。然后通过get获取对应元素的信息。

let wm = new WeakMap()
let elem = document.getElementsByTagName('h1')
wm.set(elem, 'info')
console.log(wm.get(elem))

image-20201124014212589

参考:https://github.com/6xiaoDi/blog-ECMScript-Series/tree/a2.47
Branch: branch02

commit description:a2.47(新的数据结构Map——weakmap应用)

tag:a2.47




(后续待补充)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值