文章目录
1. Symbol(符号)
1.1 Symbol的定义
Symbol是一种基本数据类型,Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法,每一个Symbol()函数返回的值都是唯一的
1.2 Symbol的创建
let sym = Symbol(1) // Symbol(1)
// Symbol表示唯一值
let sym1 = Symbol("name")
let sym2 = Symbol("name")
sym1 === sym2 // false
1.3 Symbol的一些api
注意:Symbol的有些属性是可以给对象添加,比如迭代器等,所有不会有返回值
属性/方法 | 作用 |
---|---|
1. asyncIterator | 如果对象添加了这个属性,那么它就是异步可迭代对象,可以使用for await of循环 |
2. hasInstance | 用于判断某对象是否为某构造器的实例,因此你可以用它自定义 instanceof |
3. iterator | 为一个对象添加一个迭代器,使该对象可以通过for of 迭代 |
4. description | 一个只读属性,它会返回 Symbol 对象的可选描述的字符串,比如:Symbol(111).description ==> “111”,返回字符串 |
Symbol的很多方法都不太常用,这些也都是在mdn上面查看的,有需要可以直接在上面查看就可以
1.4 Symbol作为对象的key
let obj = {
[Symbol("name")]: "小红",
age: 18,
};
// 作为对象的 key 基本使用是获取不到的
obj.name // undefined
Object.keys[obj] // [ 'age' ]
// 获取 symbol 类型的key
Object.getOwnPropertySymbols(obj) // [ Symbol(name) ]
// 也是获取对象的 key,包括 symbol 类型
Reflect.ownKeys(obj) // [ 'age', Symbol(name) ]
2. BigInt(大数)
2.1 BigInt的定义
- BigInt是一种内置对象,用来表示大于2^53 - 1的整数,它可以表示任意大的整数,如果有小数的话会向下取整。
- 因为在使用Number类型来表示特别大的数的时候,会变成科学计数法的形式,会有一些偏差的问题,使用BigInt可以避免这种问题
2.2 BigInt的创建
let big = BigInt(1) // 1n
// 它们之间也可以进行运算
1n + 1n = 2n
3n - 1n = 2n
7n / 4n = 1n // 向下取整
3n * 2n = 6n
3. Set(集合)
3.1 集合的定义
集合就是一组值,与数组类似。但是与数组不同的是,集合没有索引或顺序,也不允许重复
3.2 集合的创建
let set1 = new Set("2213") // Set(3) {'2', '1', '3'}
// 在创建集合时传入的值必须是一个可迭代对象
let set2 = new Set(1) // number 1 is not iterable
// 这两个数组存的引用不一样,所以没有去重
let set3 = new Set([1,2,3,[123],[123]]) // Set(5) {1, 2, 3, Array(1), Array(1)}
3.3 集合常用api
方法 | 作用 | 返回值 |
---|---|---|
1. size:属性 | 查看集合中的元素个数,和数组的length类似 | 数字 |
2. add(data) | 向集合的末尾添加数据 | Set对象本身 |
3. delete(data) | 删除集合中的指定数据 | 布尔值 |
4. clear() | 清空集合 | undefined |
5. has(data) | 查询集合中是否存在该数据 | 布尔值 |
6. forEach(callback) | 和数组的方法一样,按插入的顺序遍历 | |
7. values() | 按照插入顺序,返回一个具有set对象每个属性的迭代器 | 迭代器对象 |
8. entries() | 返回一个 [value, value] 形式的数组迭代器对象 | 迭代器对象 |
3.4 集合的补充
Set类是可迭代的,可以for of遍历,也可以使用 … 扩展操作符
集合中不会出现重复数据的判断,是类似于 === 的,而不是 ==
因为通过add操作是返回集合本身,所以可以使用 add(1).add(2).add(3) 这种链式的方法去添加数据
从集合开始,下面的都是引用数据类型
4. Map(映射)
4.1 映射的定义
Map对象表示一组被称为键(key)的值,其中每个键都关联着(或映射到)另一个值,它的key可以为引用数据类型
4.2 映射的创建
// 映射的创建也必须为一个可迭代对象,每一个值为[key, value]
let map = new Map([
["one", 111],
[123, 222],
[true, 333],
[function () { }, 444],
[new Set(), 555]
]) // Map(5) {'one' => 111, 123 => 222, true => 333, ƒ => 444, Set(0) => 555}
4.3 映射常用api
方法 | 作用 | 返回值 |
---|---|---|
1. size:属性 | 查看映射的成员数量,和数组的length类似 | 数字 |
2. set(key,value) | 向映射中添加或修改了指定key和value | Map对象本身 |
3. get(key) | 返回映射中指定key的value,如果没有返回undefined | value |
4. clear() | 清空映射 | undefined |
5. delete(key) | 删除指定元素 | 布尔值 |
6. has(key) | 查看元素 | 布尔值 |
7. keys() | 按照插入顺序,返回key | 迭代器对象 |
8. values() | 按照插入顺序,返回value | 迭代器对象 |
9. entries() | 返回一个 [key, value] 形式的数组迭代器对象 | 迭代器对象 |
10. forEach() | forEach(callback(value, key, map)),先value后key |
4.4 映射的补充
Map类也是可迭代的,它使用for of遍历要注意,是先key后value,和forEach()相反
5. WeakMap和WeakSet
5.1 WeakMap(弱映射)
-
弱映射是映射的变体(不是子类),它不会阻止键值被当作垃圾回收
垃圾回收:比如在函数调用后会被浏览器垃圾回收,如果没有去调用这个函数,而是保存到一个变量中,那么他就不会被浏览器垃圾回收
在弱映射中,即使没有去使用它,它也会被浏览器给垃圾回收
-
弱映射不是可迭代对象,它只实现了set()、get()、has()、delete()方法
-
弱映射的主要用途是实现值与对象的关联,因为它容易被垃圾回收,所以不会造成内存泄漏
-
弱映射的key只能为引用数据类型,value可以为任意类型
5.2 WeakSet(弱集合)
- 在弱集合只允许添加对象,存储在集合中,弱集合中的数据很容易被浏览器垃圾回收
- 弱集合也不是可迭代对象,只实现了add()、delete()、has()方法
5.3 案例
class Person {
constructor() {
this.set = new Set([{}, {}])
this.map = new Map([
[{}, {}],
[{}, {}]
])
this.wSet = new WeakSet([{}, {}])
this.wMap = new WeakMap([
[{}, {}],
[{}, {}]
])
}
}
let p1 = new Person()
// 这里可以很明显的看出,在wMap和wSet中的数据已经被回收了
console.log(p1);
// Person {set: Set(2), map: Map(2), wSet: WeakSet, wMap: WeakMap}
// ----> 下面是展开的部分 <----
// map: Map(2) { {… } => {… }, {… } => {… } }
// set: Set(2) { {… }, {… } }
// wMap: WeakMap { }
// wSet: WeakSet { }
// 但是直接获取是可以获取到的,弱引用中的数据是可以获取到的,但是不去使用它就会被浏览器回收
// 获取也是代表建立了引用关系,所以获取并不会被回收
console.log(p1.wMap); // WeakMap {{…} => {…}, {…} => {…}}
console.log(p1.wSet); // WeakSet {{…}, {…}}
6. TypedArray(类型化数组)
…这个还没用过