深度复制一个对象,看到很多种方法,最简单的是:
var newObject = JSON.parse(JSON.stringify(oldObject));
这样写有什么弊端吗?
怪我咯2017-04-10 14:37:47
一般情况下通过 JSON
来复制挺好的,代码写起来也方便——不过并不是所有环境都实现了 JSON
,这个需要考虑下。
通过 deep clone 一般都是有限定复制层次的,一般情况下不会无限层的复制下去。如果使用 JSON
方式来复制,通常不能控制层次。
大家讲道理2017-04-10 14:37:47
深拷贝不就好了么。
https://github.com/XadillaX/nbut-online-judge-v2/blob/master/util/functions.js#L7-L28
/**
* Deepin clone an object
* @param obj
* @returns {*}
*/
exports.cloneObject = function(obj) {
if(typeof obj === "object") {
if(util.isArray(obj)) {
var newArr = [];
for(var i = 0; i < obj.length; i++) newArr.push(obj[i]);
return newArr;
} else {
var newObj = {};
for(var key in obj) {
newObj[key] = this.cloneObject(obj[key]);
}
return newObj;
}
} else {
return obj;
}
};
天蓬老师2017-04-10 14:37:47
使用JSON接口有弊端,使用Object.create
不会复制对象本身, 而是用对象的constructor重新构造一个对象。
所以可以考虑使用Object.assign
:
let old_obj = [{a:1},{b:2}];
let new_obj = old_obj.map((ele)=>{
return Object.assign({},ele);
});
old_obj[0].a=99;
console.log(new_obj); // "[{a:1},{b:2}]"
巴扎黑2017-04-10 14:37:47
这个看需求,我是搜索进来的,之前使用封装出来的深拷贝方法,结果不能满足我的需求,
建议如果数据格式大而且多样的话,最好是用楼主说的方法; 如果deepcopy的层级小的话,可以看下面的代码:
var hasOwn = Object.prototype.hasOwnProperty;
function deepCopy(receiver, obj){
var args = [].slice.call(arguments), key, i = 1, deep, ride, value, valueType;
if( typeof args[args.length-2] === "boolean" ){
deep = args.pop();
ride = args.pop();
}else{
ride = (typeof args[args.length-1] === "boolean")?args.pop():true;
deep = false;
if(args.length < 2){
receiver = ( this !== global ) ? this : {};
if( args.length === 0 ){
return receiver;
}
}
}
while( obj = args[ i++ ] ){
for( key in obj ){
if( hasOwn.call(obj, key) ){
if( ride || !(key in receiver) ){
value = obj[key];
valueType = type(value);
if( deep && ( valueType==="object")){
receiver[key]={};
deepCopy(receiver[key], value, ride, deep);
}else if( deep && ( valueType==="array" )){
receiver[key]=[];
deepCopy(receiver[key], value, ride, deep);
}else{
receiver[key] = obj[key];
}
}
}
}
}
return receiver;
}
// 类型判定对象
var class2type = {
"[objectHTMLDocument]" : "document",
"[objectHTMLCollection]" : "nodeList",
"[objectStaticNodeList]" : "nodeList",
"[objectIXMLDOMNodeList]" : "nodeList",
"null" : "null",
"NaN" : "NaN",
"undefined" : "undefined"
};
"Boolean, Number, String, Function, Array, Date, RegExp, Document, Arguments, NodeList"
.replace( /[^, ]+/g, function( type ){
class2type["[object " + type + "]"] = type.toLowerCase();
} );
// 类型判定
function type( obj, isType ){
var key = ((obj == null || obj !== obj ) ? obj + "" : Object.prototype.toString.call( obj )),
result;
if( typeof(result = class2type[ key ]) !== "string" ){
if( obj.nodeType === 9 ){
result = class2type["Document"];
}else if( obj.item && typeof obj.length === "number" ){
result = class2type["NodeList"];
}else{
result = key.slice(8, -1);
}
}
if( isType ){
return result === isType.toLowerCase;
}
return result;
}
export { deepCopy }; //根据开发模式选择使用或不使用,可取消