js

JS高级知识总结02

严格模式,原型/原型链,继承,ES6类新特性

Posted by AzirKxs on 2022-11-03
Estimated Reading Time 8 Minutes
Words 1.9k In Total
Viewed Times

JS高级知识总结02

let,const

函数增强

函数默认值

箭头函数

rest剩余参数

对象增强

变量作为键名

对象解构

展开运算符

引用赋值,浅拷贝,深拷贝

symbol类型

对象作为参数的弊端

思考如下代码

1
2
3
4
5
6
7
8
let obj = {
name: '123',
age: 22
}

function foo(obj){
obj.age = 19
}

foo函数的本意是想要添加一个age属性,但是它不知道传入的obj中已经有了age属性而导致自己覆盖了age的。

当我们想要做类似的操作时,必须做到属性名独一无二,因此就有了symbol用来生成一个独一无二的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const s1 = Symbol()
const obj = {
name:'obj',
[s1]:'aaa'
}
const s2 = Symbol()
obj[s2] = 'bbb'
console.log(s1 == s2) //false
console.log(s1 === s2) //false
console.log(obj)
/*
Object
Symbol(): "aaa"
Symbol(): "bbb"
*/

获取symbol对应的key

1
2
3
console.log(Object.keys(obj)) ////['name'] 无法获取到symbol的键值

console.log(Object.getOwnPropertySymbols(obj))//[Symbol(), Symbol()] 获取到了symbol键值的数组

遍历symbol属性

1
2
3
4
5
let symobls = Object.getOwnPropertySymbols(obj)
for(let key of symobls){
console.log(obj[key])
}
//aaa bbb

description

可以在创建symbol时传入参数作为symbol的描述

1
2
const a1 = Symbol('aaa')
console.log(a1.description) //aaa

Symbol.for

通过symbol.for创建的symbol类型当传入相同的描述时,===成立

1
2
3
4
5
6
7
const a1 = Symbol('aaa')
const a2 = Symbol('aaa')
console.log(a1 === a2) //false

const b1 = Symbol.for('bbb')
const b2 = Symbol.for('bbb')
console.log(b1 === b2) //true

Symbol.keyFor

获取symbol类型的key

1
2
3
4
5
const a1 = Symbol('aaa')
console.log(Symbol.keyFor(a1)) //undefined

const b1 = Symbol.for('bbb')
console.log(Symbol.keyFor(b1)) //bbb

set

特点:不能有重复元素,会自动去重

属性

size属性

实例方法

add(value):添加某个值,返回 Set 结构本身(可以链式调用)。

delete(value):删除某个值,删除成功返回 true,否则返回 false

has(value):返回一个布尔值,表示该值是否为 Set 的成员。

clear():清除所有成员,没有返回值。

遍历方法

  • keys():返回键名的遍历器。
  • values():返回键值的遍历器。
  • entries():返回键值对的遍历器。
  • forEach():使用回调函数遍历每个成员。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let set = new Set(['red', 'green', 'blue'])

for (let item of set.keys()) {
console.log(item)
}
// red
// green
// blue

for (let item of set.values()) {
console.log(item)
}
// red
// green
// blue

for (let item of set.entries()) {
console.log(item)
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

WeakSet

和set的区别:

只能存放对象类型

对对象都是弱引用,不能保证GC是否会回收

weakset不能遍历,没有size属性

map

1
Map` 中存储的是 `key-value` 形式的键值对, 其中的 `key` 和 `value` 可以是任何类型的, 即对象也可以作为 `key

属性

size属性

Map 对象的方法

  • set(key, val): 向 Map 中添加新元素
  • get(key): 通过键值查找特定的数值并返回
  • has(key): 判断 Map 对象中是否有 Key 所对应的值,有返回 true,否则返回 false
  • delete(key): 通过键值从 Map 中移除对应的数据
  • clear(): 将这个 Map 中的所有元素删除

遍历方法

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
onst map = new Map([
['a', 1],
['b', 2],
])

for (let key of map.keys()) {
console.log(key)
}
// "a"
// "b"

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

for (let item of map.entries()) {
console.log(item)
}
// ["a", 1]
// ["b", 2]

// 或者
for (let [key, value] of map.entries()) {
console.log(key, value)
}
// "a" 1
// "b" 2

// for...of...遍历map等同于使用map.entries()

for (let [key, value] of map) {
console.log(key, value)
}
// "a" 1
// "b" 2

数据类型转化

Map 转为数组

1
2
let map = new Map()
let arr = [...map]

数组转为 Map

1
Map: map = new Map(arr)

index为键

Map 转为对象

1
2
3
4
let obj = {}
for (let [k, v] of map) {
obj[k] = v
}

对象转为 Map

1
2
3
for( let k of Object.keys(obj)){
map.set(k,obj[k])
}

WeakMap

WeakMap 结构与 Map 结构类似,也是用于生成键值对的集合。

  • 只接受对象作为键名(null 除外),不接受其他类型的值作为键名
  • 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的
  • 不能遍历,方法有 getsethasdelete

为 DOM 元素添加事件监听时可以用到WeakMap 和 WeakSet,在垃圾回收机制方面会更优

ES8-padStart和padEnd

用于填充数字

1.对时间进行格式化,填充

1
2
3
4
let hour = '5'.padStart(2,'0') //填充2位。用0来填充
let minute = '18'.padStart(2,'0')

console.log(`${hour}:${minute}`) //05:18

2.对敏感数据进行格式化

隐藏身份证号银行卡手机号之类的

ES10-flat和flatMap

flat:

按照指定的深度递归数组,将遍历到的元素和子数组中的元素组合成为一个新的数组并返回,数组扁平化

flatMap:

先对所有元素应用 一次map操作,在做flat操作

ES10-entries和fromEntries

entries和obj的相互转化

1
2
3
4
5
6
7
8
let obj = {
name:'obj',
age:'22'
}
let ent = Object.entries(obj)
let info = Object.fromEntries(ent)
console.log(ent)
console.log(info)

ES10-trimStart和trimEnd

去除首部和尾部的空格

ES11-BigInt

可以准确表示比Number.Max_SAFE_INTEGER更大的数字

bigint的表示方式只需要在后面加上一个n

ES11-空值合并运算符

空值也可以被当作是有值,只有null和undefined才会走后面的逻辑

1
2
3
4
5
6
7
let info = ""
info = info ||'默认值'
console.log(info) //默认值

let info2 = ""
info2 = info2 ??'默认值'
console.log(info2) //空值

ES11-可选链

只有判断属性存在,才继续执行下一步操作

1
2
3
4
5
6
7
8
9
10
11
const obj = {
name: 'obj',
friend: {
running() {
console.log('running~')
}
}
}
obj.friend.running() //不安全,当friend不存在或者running不存在时会报错

obj?.friend?.running?.() //只有当属性存在才会执行下去,若有某个属性不存在则返回undefined

ES12-FinalizationRegistry

FinalizationRegistry对象可以让对象在被垃圾回收时请求一个回调

1
2
3
4
5
6
7
8
9
10
11
let obj = {

}

const finalRegistry = new FinalizationRegistry((value)=>{
console.log(`${value}被回收了`)
})

finalRegistry.register(obj,'obj')

obj = null

ES12-WeakRef

添加为弱引用,保证能被垃圾回收器回收

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let info = {name:'info'}
//let obj = info 这种写法当info为null时,info不会被垃圾回收器回收
let obj = new WeakRef(info)

const finalRegistry = new FinalizationRegistry((value)=>{
console.log(`${value}被回收了`)
})

finalRegistry.register(info,'info')

console.log(obj.deref()) //{name:'info'} 取值需要调用deref函数

info = null
obj = null

ES12-逻辑赋值运算符

下面的两种写法等价

1
2
3
4
message = message ||'默认值 '
message ||= '默认值'
//也可结合空值合并运算符一起使用
message ??='默认值 '

ES12-replaceAll

String.replace只能体换一个,而replaceAll可以全部替换

ES13-at

字符串和数组取指定位置的值

ES13-hasOwn

对象属性判断方法,用于替换hasOwnProperty方法 。

hasOwn是类方法,hasOwnProperty是实例方法

hasOwnProperty当调用该方法的对象指向null的时候会报错,而Object为类方法则不会报错

ES13-类中增加新成员和私有属性

#开头的属性名为私有属性,外界无法访问

类属性(静态属性,使用static修饰的属性为静态属性)

静态代码块


如果这篇文章对你有帮助,可以bilibili关注一波 ~ !此外,如果你觉得本人的文章侵犯了你的著作权,请联系我删除~谢谢!