搜集来源:(代码中的同类变量已被我修改优化为同名变量)
【JS】深拷贝与浅拷贝的区别,实现深拷贝的几种方法(递归一)js实现深拷贝(递归二、树广度一)JS实现深拷贝(递归一、树深度一)深度优先遍历,广度优先遍历实现对象的深拷贝(树深度二、树广度二)
关于赋值、浅拷贝、深拷贝的区别
文章目录
JSON 对象方法
防坑注意:
【jQuery】extend()方法递归函数(一)递归函数(二)【DFS】树深度优先遍历(一)【DFS】树深度优先遍历(二)【BFS】树广度优先遍历(一)【BFS】树广度优先遍历(二)
JSON 对象方法
Object
.prototype
.deepClone = function() {
return JSON.parse(JSON.stringify(this));
}
防坑注意:
【jQuery】extend()方法
无论修改拷贝对象第几层嵌套层,原对象均不会被影响:PS:别忘了引入【jq库】
递归函数(一)
无论修改拷贝对象第几层嵌套层,原对象均不会被影响:【缺点】当数据的层次很深,会栈溢出,所以最好用【DFS / BFS】
function deepClone(obj
) {
if (obj
=== null) {
return null;
} else if (typeof obj
!== 'object') {
return obj
;
} else if (obj
.constructor
=== Date
) {
return new Date(obj
);
}
var objClone
= new obj.constructor ();
for (var k
in obj
) {
if (obj
.hasOwnProperty(k
)) {
if (obj
[k
] && typeof obj
[k
] === 'object') {
objClone
[k
] = deepClone(obj
[k
]);
} else {
objClone
[k
] = obj
[k
];
}
}
}
return objClone
;
};
递归函数(二)
演示图与上面一样就不发了【缺点】当数据的层次很深,会栈溢出,所以最好用【DFS / BFS】
function getType(obj
) {
var _toString
= Object
.prototype
.toString
;
var map
= {
'[object Boolean]' : 'boolean',
'[object Number]' : 'number',
'[object String]' : 'string',
'[object Function]' : 'function',
'[object Array]' : 'array',
'[object Date]' : 'date',
'[object RegExp]' : 'regExp',
'[object Undefined]' : 'undefined',
'[object Null]' : 'null',
'[object Object]' : 'object'
};
if (obj
instanceof Element) {
return 'element';
}
return map
[_toString
.call(obj
)];
}
function deepClone(obj
) {
var type
= getType(obj
);
var objClone
;
if (type
=== 'array') {
objClone
= [];
} else if (type
=== 'object') {
objClone
= {};
} else {
return obj
;
}
if (type
=== 'array') {
for (var i
= 0, len
= obj
.length
; i
< len
; i
++) {
objClone
.push(deepClone(obj
[i
]));
}
} else if (type
=== 'object') {
for (var k
in obj
) {
objClone
[k
] = deepClone(obj
[k
]);
}
}
return objClone
;
}
【DFS】树深度优先遍历(一)
function deepClone(obj
) {
var objClone
= {};
var loopList
= [{
parent
: objClone
,
key
: undefined
,
data
: obj
,
}];
while (loopList
.length
) {
var node
= loopList
.pop();
var parent
= node
.parent
;
var key
= node
.key
;
var data
= node
.data
;
var res
= parent
;
if (typeof key
!== 'undefined') {
res
= parent
[key
] = {};
}
for (var 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 objClone
;
}
【DFS】树深度优先遍历(二)
function getType(obj
) {
var _toString
= Object
.prototype
.toString
;
var map
= {
'[object Boolean]' : 'boolean',
'[object Number]' : 'number',
'[object String]' : 'string',
'[object Function]' : 'function',
'[object Array]' : 'array',
'[object Date]' : 'date',
'[object RegExp]' : 'regExp',
'[object Undefined]' : 'undefined',
'[object Null]' : 'null',
'[object Object]' : 'object'
};
if (obj
instanceof Element) {
return 'element';
}
return map
[_toString
.call(obj
)];
}
function deepClone(obj
) {
var type
= getType(obj
);
var objClone
= {};
var visitQueue
= [];
if (type
=== 'array' || type
=== 'object') {
var index
= visitQueue
.indexOf(obj
);
if (index
> -1){
objClone
= visitQueue
[index
]
} else {
visitQueue
.push(obj
);
for (var key
in obj
) {
objClone
[key
] = deepClone(obj
[key
], visitQueue
);
}
}
} else if (type
=== 'function') {
objClone
= eval( '(' + obj
.toString() + ')');
} else {
objClone
= obj
;
}
return objClone
;
}
【BFS】树广度优先遍历(一)
function deepClone(obj
) {
var objClone
= {};
var originQueue
= [obj
];
var copyQueue
= [objClone
];
var visitQueue
= [];
var copyVisitQueue
= [];
while (originQueue
.length
> 0) {
var _obj
= copyQueue
.shift();
var _data
= originQueue
.shift();
copyVisitQueue
.push(_obj
);
visitQueue
.push(_data
);
for (var k
in _data
) {
var _value
= _data
[k
];
if (typeof _value
!== 'object') {
_obj
[k
] = _value
;
} else {
var index
= visitQueue
.indexOf(_value
);
if (index
>= 0) {
_obj
[k
] = copyVisitQueue
[index
];
} else {
originQueue
.push(_value
);
_obj
[k
] = {};
copyQueue
.push(_obj
[k
]);
}
}
}
}
return objClone
;
}
【BFS】树广度优先遍历(二)
function getType(obj
) {
var _toString
= Object
.prototype
.toString
;
var map
= {
'[object Boolean]' : 'boolean',
'[object Number]' : 'number',
'[object String]' : 'string',
'[object Function]' : 'function',
'[object Array]' : 'array',
'[object Date]' : 'date',
'[object RegExp]' : 'regExp',
'[object Undefined]' : 'undefined',
'[object Null]' : 'null',
'[object Object]' : 'object'
};
if (obj
instanceof Element) {
return 'element';
}
return map
[_toString
.call(obj
)];
}
function deepClone(obj
) {
var objClone
= {};
var originQueue
= [obj
];
var copyQueue
= [objClone
];
var visitQueue
= [];
while(originQueue
.length
){
var _obj
= originQueue
.shift();
var _data
= copyQueue
.shift();
if (getType(_obj
) === 'array' || getType(_obj
) === 'object') {
for(item
in _obj
){
var val
= _obj
[item
];
if (getType(val
) === 'object') {
var index
= visitQueue
.indexOf(val
);
if (~index
) {
_data
[item
] = visitQueue
[index
];
} else {
originQueue
.push(val
);
_data
[item
] = {};
copyQueue
.push(_data
[item
]);
visitQueue
.push(val
);
}
}
else if (getType(val
) === 'array') {
originQueue
.push(val
);
_data
[item
] = [];
copyQueue
.push(_data
[item
])
} else if (getType(val
) === 'function') {
_data
[item
] = eval( '(' + val
.toString() + ')');
} else {
_data
[item
] = val
;
}
}
} else if (getType(obj
) === 'function') {
_data
= eval( '(' + _obj
.toString() + ')');
} else {
_data
= _obj
;
}
}
return objClone
;
}