/**
* 1 constructor === Array
* 2 hasOwnProperty
* JavaScript 并没有保护 hasOwnProperty 这个属性名,
* 因此,当某个对象可能自有一个占用该属性名的属性时,
* 就需要使用外部的 hasOwnProperty 获得正确的结果
*/
function deepClone(source) {
// 基本数据类型直接跳出循环
if (typeof source !== 'object' || typeof source === null) {
return 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;
}
const a = [{b: 11}, 123]
const o = {a: 111, b: 222}
const b = '12346'
console.log(deepClone(a))
console.log(deepClone(o))
console.log(deepClone(b))
console.log(typeof [])
const obj1 = {
foo: 1111,
}
// 修改 hasOwnProperty
const obj2 = {
hasOwnProperty: function(){
return false
},
foo: 123,
}
console.log(obj1.hasOwnProperty('foo'), 123)
console.log(obj2.hasOwnProperty('foo'), 123)
// 解决 修改风险 两种方案
console.log(
({}).hasOwnProperty.call(obj2, 'foo')
)
console.log(
Object.prototype.hasOwnProperty.call(obj2, 'foo')
)
console.log(
Object.prototype.toString.call([]).slice(7,-1),
Object.prototype.toString.call({}).slice(7,-1),
Object.prototype.toString.call(()=>{}).slice(7,-1),
)
console