先举例说下深拷贝和浅拷贝的区别:
var a = { name: 'bob' }; var b = a; // b: { name: 'bob' }; a.name = 'tom'; console.log(b); //b: { name: 'tom' };
可以发现直接拷贝,当原对象 a 改变时, b 也发生了改变;这种就是浅拷贝,因为虽然是拷贝成功但是 a 和 b 所指向的内存地址是相同的,所以a改变时,b也会发生改变。
那么如何拷贝才能使b不受a的影响呢;也就是深拷贝呢?
1 function typeOf(obj) { 2 const toString = Object.prototype.toString; 3 const map = { 4 '[object Boolean]' : 'boolean', 5 '[object Number]' : 'number', 6 '[object String]' : 'string', 7 '[object Function]' : 'function', 8 '[object Array]' : 'array', 9 '[object Date]' : 'date', 10 '[object RegExp]' : 'regExp', 11 '[object Undefined]': 'undefined', 12 '[object Null]' : 'null', 13 '[object Object]' : 'object' 14 }; 15 return map[toString.call(obj)]; 16 } 17 function deepCopy(data) { 18 const t = typeOf(data); 19 let o; 20 21 if (t === 'array') { 22 o = []; 23 } else if ( t === 'object') { 24 o = {}; 25 } else { 26 return data; 27 } 28 29 if (t === 'array') { 30 for (let i = 0; i < data.length; i++) { 31 o.push(deepCopy(data[i])); 32 } 33 } else if ( t === 'object') { 34 for (let i in data) { 35 o[i] = deepCopy(data[i]); 36 } 37 } 38 return o; 39 }
解释: 通过typeOf方法我们可以准确区别数组和对象,然后直接调用deepCopy就可以深拷贝成功。
第二种深拷贝方法
function deepcopy(source) { if (!source || (!(source instanceof Array) && !(source instanceof Object))) { return source } const sourceCopy = source instanceof Array ? [] : {} for (const item in source) { sourceCopy[item] = typeof source[item] === 'object' ? deepcopy(source[item]) : source[item] } return sourceCopy }