一、賦值、淺拷貝與深拷貝的區別
二、深拷貝的方法
1.JSON轉換
var targetObj = JSON.parse(JSON.stringify(copyObj))
let arr4 = JSON.parse(JSON.stringify(arr))
缺點:
(1)如果對象里有函數,函數無法被拷貝下來
(2)無法拷貝copyObj對象原型鏈上的屬性和方法
(3)當數據的層次很深,會棧溢出
2.普通遞歸函數
function deepCopy( source ) {
if (!isObject(source)) return source; //如果不是對象的話直接返回
let target = Array.isArray( source ) ? [] : {} //數組兼容
for ( var k in source ) {
if (source.hasOwnProperty(k)) {
if ( typeof source[ k ] === 'object' ) {
target[ k ] = deepCopy( source[ k ] )
} else {
target[ k ] = source[ k ]
}
}
}
return target
}
function isObject(obj) {
return typeof obj === 'object' && obj !== null
}
缺點:
(1)無法保持引用
(2)當數據的層次很深,會棧溢出
3.防棧溢出函數
function cloneLoop(x) {
const root = {};
// 棧
const loopList = [
{
parent: root,
key: undefined,
data: x,
}
];
while(loopList.length) {
// 深度優先
const node = loopList.pop();
const parent = node.parent;
const key = node.key;
const data = node.data;
// 初始化賦值目標,key為undefined則拷貝到父元素,否則拷貝到子元素
let res = parent;
if (typeof key !== 'undefined') {
res = parent[key] = {};
}
for(let k in data) {
if (data.hasOwnProperty(k)) {
if (typeof data[k] === 'object') {
// 下一次循環
loopList.push({
parent: res,
key: k,
data: data[k],
});
} else {
res[k] = data[k];
}
}
}
}
return root;
}
優點:
(1)不會棧溢出
(2)支持很多層級的數據
function copyObject(orig) {
var copy = Object.create(Object.getPrototypeOf(orig));
copyOwnPropertiesFrom(copy, orig);
return copy;
}
function copyOwnPropertiesFrom(target, source) {
Object
.getOwnPropertyNames(source)
.forEach(function (propKey) {
var desc = Object.getOwnPropertyDescriptor(source, propKey);
Object.defineProperty(target, propKey, desc);
});
return target;
}
var obj = {
name: 'Jack',
age: '32',
job: 'developer'
};
var obj2 = copyObject(obj);
console.log(obj2);
obj.age = 39;
obj.name = 'Tom';
console.log(obj);
console.log(obj2);