深拷贝写法>遍历对象的方法
手写深拷贝如下:
function deepCopy(obj) {
//判断是否是简单数据类型,
if (typeof obj == "object") {
//复杂数据类型
var result = obj.constructor == Array ? [] : {};
//对于数组和对象,result的类型不一样,不过调用方式一样,都是result[i]
for (let i in obj) {
// console.log(i);
result[i] = typeof obj[i] == 'object' ? deepCopy(obj[i]) : obj[i];
}
} else {
//简单数据类型 直接 == 赋值
var result = obj;
}
return result;
}
深拷贝原理很简单, 就是多层"浅拷贝", 直到碰到普通数据类型直接赋值.
小tip: 判断数组可以用继承自原型对象的constructor属性,它指向构造函数
obj.constructor == Array ? [] : {};
还有其他方法: 本质也是利用原型链来判断
obj instanceof Array ? [] : {}; Array.isArray(obj) ? [] : {};
但是我仍然碰到很多小bug, 所以要复习以下字符串的基础知识;
1.字符串的属性类型: 都行
var obj2 = {
name: 'peiqi', //属性名是标识符
age: '4',
brother: {
name: 'jorge',
age: 2,
},
family: ['fa', 'ma'], //属性名是数组名
'字符串': 123, //属性名是字符串
null: 123, //null被当成标识符了,避免歧义不要这样
undefined: 123,
};
2.用for item in obj 遍历字符串时, item是string格式, 自带"隐形的"引号
for (var i in obj2) {
var tt = typeof i;
console.log(tt + i);
}
就算是数组也是一样的,字符串形式的下标:
var arr1 = [{
soft: 18
}, {
road: 23
}, 123, '123']
for (var i in arr1) {
console.log(i);
console.log(typeof i);
}
3.获取属性方法
之前说过两种方法:
obj.p // "Hello World" //打点的形式不能打引号
obj['p'] // "Hello World" //如果用中括号需要打引号,否则定位不到obj.p这个指针
进行细节补充:
obj2[name] = 'road'; //中括号不打引号定位不到obj2.name;
console.log('1次' + obj2.name); //1次peiqi, 说明对象的name属性并未改变
obj2['name'] = 'key';
console.log('3次' + obj2.name);
console.log(obj2['字符串']); //成功输出123
console.log(obj2["'字符串'"]); //undefined, 即使是字符串也不用打两次引号!,一次引号即可
总结: 不过属性名是什么类型, 不要在打点形式里带引号, 也不要在中括号形式里不打引号, 或者打两个引号
总结2,3, 所以在for in遍历方式里, 要注意用obj[item]格式, 不要打引号, 因为item本身就是string格式, 自带引号; 也不要用obj.item格式