84669 Lernen von Personen
152542 Lernen von Personen
20005 Lernen von Personen
5487 Lernen von Personen
7821 Lernen von Personen
359900 Lernen von Personen
3350 Lernen von Personen
180660 Lernen von Personen
48569 Lernen von Personen
18603 Lernen von Personen
40936 Lernen von Personen
1549 Lernen von Personen
1183 Lernen von Personen
32909 Lernen von Personen
深度复制一个对象,看到很多种方法,最简单的是:
var newObject = JSON.parse(JSON.stringify(oldObject));
这样写有什么弊端吗?
学习是最好的投资!
oldObject = {a: 1, b: function() {}}
var newObject = Object.create(oldObject);
一般情况下通过 JSON 来复制挺好的,代码写起来也方便——不过并不是所有环境都实现了 JSON,这个需要考虑下。
JSON
通过 deep clone 一般都是有限定复制层次的,一般情况下不会无限层的复制下去。如果使用 JSON 方式来复制,通常不能控制层次。
深拷贝不就好了么。
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; } };
可以参考一下stackoverflow上关于克隆一个对象的有效方法
使用JSON接口有弊端,使用Object.create不会复制对象本身, 而是用对象的constructor重新构造一个对象。所以可以考虑使用Object.assign:
Object.create
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}]"
这个看需求,我是搜索进来的,之前使用封装出来的深拷贝方法,结果不能满足我的需求,
建议如果数据格式大而且多样的话,最好是用楼主说的方法; 如果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 }; //根据开发模式选择使用或不使用,可取消
oldObject = {a: 1, b: function() {}}
一般情况下通过
JSON
来复制挺好的,代码写起来也方便——不过并不是所有环境都实现了JSON
,这个需要考虑下。通过 deep clone 一般都是有限定复制层次的,一般情况下不会无限层的复制下去。如果使用
JSON
方式来复制,通常不能控制层次。深拷贝不就好了么。
可以参考一下stackoverflow上关于克隆一个对象的有效方法
使用JSON接口有弊端,使用
Object.create
不会复制对象本身, 而是用对象的constructor重新构造一个对象。所以可以考虑使用
Object.assign
:这个看需求,我是搜索进来的,之前使用封装出来的深拷贝方法,结果不能满足我的需求,
建议如果数据格式大而且多样的话,最好是用楼主说的方法; 如果deepcopy的层级小的话,可以看下面的代码: