deepClone 对象深度克隆
注意
由于JS
对象包括的范围非常广,加上ES6
又有众多的新特性,很难、也没必要做到囊括所有的类型和情况,这里说的”对象”,指的是普通的对象,不包括修改对象原型链, 或者为”Function
“,”Promise
“等的情况,请留意。
场景
我们平时可能会遇到需要通过console.log
打印一个对象,至执行打印的时刻,此对象为空,后面的逻辑
中对此对象进行了修改赋值,但是我们在控制台直接看到的打印结果 却是修改后的值,这让人匪夷所思,虽然我们可以通过
console.log(JSON.parse(JSON.stringify(object)))
的形式处理,但是需要写这长长的一串,难免让人心生抵触。
当我们将一个对象(变量 A)赋值给另一个变量(变量 B)时,修改变量 B,因为对象引用的特性,导致 A 也同时被修改,所以有时候我们需要将 A 克隆给 B,这样修改 B 的时候,就不会 导致 A 也被修改。
deepClone(object = {})
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| let a = { name: '小明', }
let b = a
b.name = '小明' console.log(b) console.log(a)
let b = deepClone(a)
b.name = '小红' console.log(b) console.log(a)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function isArray(arr) { return Object.prototype.toString.call(arr) === '[object Array]' }
function deepClone(obj) { if ([null, undefined, NaN, false].includes(obj)) return obj if (typeof obj !== 'object' && typeof obj !== 'function') { return obj } var o = isArray(obj) ? [] : {} for (let i in obj) { if (obj.hasOwnProperty(i)) { o[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i] } } return o }
|