杂记
document.documentElement
<html></html>
document.body
<body></body>
# Promise 的理解
promise构造函数是同步,resolve,reject执行不影响下面代码执行.promise 有三个状态 pedding,fulfilled,rejected状态,状态一改变不再变化,且有了一个值,后续每次调用,then和catch直接拿到该值.promise不能返回本身,否则死循环.如果then传不是函数,会发生值传递
Promise.all([promise1, promise2]).then(success, fail)
// 只有当promise1和promise2都成功时才会调用success
// 有一个promise失败都会调用fail
Promise.race([promise1, promise2]).then(success, fail)
// promise1和promise2只要有一个成功就会调用success;
// promise1和promise2只要有一个失败就会调用fail;
// 总结: 谁第一个成功或失败,就认为是race的成功或失败。
2
3
4
5
6
7
8
# for in 和 for of 的理解
for in 返回字符串key,数组下标也是字符串 for of 遍历集合对象
# 垃圾回收机制
垃圾回收机制: 周期性找出不在使用的变量,然后释放其内存 变量进入环境,标记"进入",在离开环境,标记"回收",离开会被回收内存 不在使用变量:局部变量,在函数调用完,局部变量会被标记为回收 全局变量生命周期是浏览器页面关闭..全局变量不会被当垃圾回收
🌈简短记忆:周期标注局部全局
# Set WeakSet Map WeakMap
set 类数组 唯一
- 方法: size add(value) delete(value) has(value) clear()
- 遍历: keys() values() entries() forEach()
- Set 结构没有键名,所以keys() 和 values()是一样的
WeakSet 类set 和set两个区别:
- WeakSet的成员只能是对象.
- WeakSet的对象是弱引用
js 对象 默认使用强引用,唯一两个弱引用WeakSet和WeakMap
// 强引用
let cat = { name: "Kitty" };
const pets = [cat];
cat = null;
console.log(pets); // [{ name: "Kitty" }]
2
3
4
5
6
// 弱引用
let pets = new WeakMap();
let cat = { name: "Kitty" };
pets.set(cat, "Kitty");
console.log(pets); // WeakMap {{…} => 'Kitty'}
cat = null;
// 等待垃圾回收后
console.log(pets); // WeakMap{}
2
3
4
5
6
7
8
9
特点
- WeakSet 不可遍历,没有size,没有forEach。
- 不会发生内存泄漏
- 没有size
- 无法清空clear
Map
- 方法: size set(key,value) get(key) delete(key) has(key) clear()
- 遍历: keys() values() entries() forEach()
Map 的键是跟内存地址绑定的
Map 的遍历顺序就是插入顺序
WeakMap应用场景
在网页的 DOM 元素上添加数据,就可以使用WeakMap
结构。当该 DOM 元素被清除,其所对应的WeakMap
记录就会自动被移除
# 深克隆(deepclone)
简单版:
const newObj = JSON.parse(JSON.stringify(oldObj));
const newObj = Object.assign({}, oldObj);
2
局限性:
- 他无法实现对函数 、RegExp正则表达式对象等特殊对象的克隆
- 会抛弃对象的constructor,所有的构造函数会指向Object
- 对象有循环引用,会报错
简单版:
function deepClone(source){
const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
for(let keys in source){ // 遍历目标
if(source.hasOwnProperty(keys)){
if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = deepClone(source[keys]);
}else{ // 如果不是,就直接赋值
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# computed和watch有什么区别?
computed:
computed是计算属性,也就是计算值,它更多用于计算值的场景 computed具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时才会重新调用对应的getter来计算 computed适用于计算比较消耗性能的计算场景 watch:
更多的是「观察」的作用,类似于某些数据的监听回调,用于观察props $emit或者本组件的值,当数据变化时来执行回调进行后续操作 无缓存性,页面重新渲染时值不变化也会执行 小结:
当我们要进行数值计算,而且依赖于其他数据,那么把这个数据设计为computed 如果你需要在某个数据变化时做一些事情,使用watch来观察这个数据变化