var obj = {
a: "zs",
b: undefined,
c: Symbol("score"),
d: null,
e: function () {
console.log("show");
},
f: /a/
};
console.log(JSON.parse(JSON.stringify(obj)));
const obj1 = {
name: "obj1",
};
const obj2 = {
name: "obj2",
relative: obj1,
};
obj1.relative = obj2;
console.log(JSON.parse(JSON.stringify(obj2)));
由上可知:
1、当属性值为undefined、函数、symbol 、正则表达式时该属性会丢失
2、拷贝循环引用对象时会报错
const Child = () => {
useEffect(() => {
console.log(1);
}, []);
useLayoutEffect(() => {
console.log(2);
}, []);
return null;
};
const Parent = () => {
useEffect(() => {
console.log(3);
}, []);
useLayoutEffect(() => {
console.log(4);
}, []);
return ;
};
输出结果:
解释:react中会先执行子组件、useLayoutEffect是同步、useEffect是异步, 所以最开始输出子组件的同步任务2,然后把子组件的异步任务回调添加到异步队列,然后回到父组件相同执行。
var obj = {
name: "zs",
age: 2,
1: "a",
0: "c",
};
console.log(obj);
for (var k in obj) {
console.log(k);
}
由上可知无论是直接输出obj,还是遍历obj,都和我们定义的obj属性顺序不同。所以普通对象是无序的。
var value = new Map();
value.set(2, "a");
value.set(0, "b");
value.set(1, "c");
value.set(1, "w");
value.set(null, "d");
value.set(undefined, "e");
value.set(undefined, "w");
console.log(value.get(undefined))
console.log(value.get(null))
console.log(value);
由上可知:
1、null和undefined可以作为Map对象的key
2、相同key后设置的会覆盖之前的(包括null、undefined)
3、Map对象的key是有序的,和你插入顺序有关
// 使用weakmap解决循环引用
// 优点:
// 1 .WeakMap来记录对象是否被克隆,主要考虑一下三点。
// 2 .WeakMap对象是key=>value形式,不会重复记录
// 3 .WeakMap是弱引用,如果不在使用,空间会直接释放
function deepCopy (obj, hash= new WeakMap()) {
// 不是对象(普通值类型/function),null,undefined,正则,Date都会直接返回
if(obj == null || typeof obj != 'object') {
return obj
}
if(obj instanceof RegExp ) {
return new RegExp(obj)
}
if( obj instanceof Date) {
return new Date(obj)
}
// 判断是否循环引用的(判断属性是不是存在了)
if(hash.get(obj)) return hash.get(obj)
let cloneObj = new obj.constructor()
// 存obj
hash.set(obj, cloneObj)
for(let key in obj) {
// in 循环会遍历原型链的,所以需要判断是否是当前对象的属性
if(obj.hasOwnProperty(key)) {
cloneObj[key] = deepCopy(obj[key], hash)
}
}
return cloneObj
}
function hasChanged(x, y) {
if (x === y) {
return x === 0 && 1 / x !== 1 / y;
} else {
return x === x || y === y;
}
}
疑惑:已经判断了x === y,为什么else里还要判断?
NaN === NaN //false
因为NaN的缘故,如果x为NaN,又给它赋值为NaN,其实是没有变化的, 所以在else中判断x === x就可以知道它是NaN这种情况
疑惑:为什么判断 x === 0 && 1 / x !== 1 / y ?
+0 === -0 //true
1/+0 //Infinity
1/-0 //-Infinity