Javascript deepCopyObject失败
我已经编写了自己的deepCopy函数,可以复制和对象:Javascript deepCopyObject失败,javascript,object,Javascript,Object,我已经编写了自己的deepCopy函数,可以复制和对象: function deepCopyObj(object){ if(object == null || typeof(object) != 'object'){ return object; } var copy = object.constructor(); //This line makes some troubles for (var attr in object) {
function deepCopyObj(object){
if(object == null || typeof(object) != 'object'){
return object;
}
var copy = object.constructor(); //This line makes some troubles
for (var attr in object) {
if(object.hasOwnProperty(attr) && typeof(object[attr]) !== "undefined") {
copy[attr] = deepCopyObj(object[attr]);
}
}
return copy;
}
此代码一直运行良好-直到现在:
有时,当我想要复制一个对象时,命令var copy=object.constructor()代码>返回未定义的
原因是什么?当我将对象
打印到控制台时,它会提供正确的输出
注意,我的代码有时使用delete object.anaAttribute
删除函数-但我不知道这是否是原因。还请注意,您的deepCopyObj()只会复制源对象的可枚举属性
var obj = {name: "Andrew", lastname:"Smith"};
Object.defineProperty(obj,"id",{
enumerable:false,
configurable:true,
writeable:true,
value:"1"
});
var newObj = deepCopyObj(obj);
newObj.id返回未定义的
请参阅以获得进一步解释,问题很简单:我复制的对象有一些参数
deepCopy功能不需要防弹,所以我只为这类对象添加了特殊处理:
var copy;
if(object instanceof ParserAPI){ //only for debugging-purposes
var constructorParams = object.getConstructorParameters();
copy = new ParserAPI(constructorParams[0], constructorParams[1]);
}else{
copy = object.constructor();
}
if(typeof(copy) == "undefined"){ //pls pls pls, don't appear
throw new Error("deepCopyObj failed");
}
在需要复制的ParserAPI对象中,我现在有以下代码:
function ParserAPI (_input, _reporter){
var input=_input, reporter=_reporter;
self.getConstructorParameters = function(){
return [self.input, self.reporter];
}
...
}
你不能依赖构造函数来调用那样的函数。您也不能指望它们不需要一个或多个参数。以下是创建一个通用的“万无一失”JavaScript深度复制工具的挑战性原因:)有两个原因:1。在代码中的其他地方,您已经运行了一个删除\u对象。构造函数
,然后将其传递到deepCopyObj
-或-2。您正在传入一个没有构造函数的对象,例如。G使用对象创建的对象。创建(空)
。唯一可以确定的方法是打断该错误并查看对象是什么,然后返回堆栈以找出它的来源。下面是上述代码的一个更健壮的版本:。它将处理构造函数参数,还有第二个版本处理循环引用。我知道这个对象-它叫parserAPI,其中的函数和属性总是变化的。我通过parserAPI.foo=function(){…}
添加它们,并使用硬编码的delete命令删除它们-因此我从未接触过构造函数。你真的无法“处理”需要参数的构造函数,因为参数可以在作为对象属性公开的函数所使用的闭包中捕获。请不要使用泛型方法进行测试。相反,为每个ParserApi
实例指定一个.copy()
或.clone()
方法,这样可以对它们进行特殊处理。在deepCopy
中,仅通过typeof object.clone==“function”
检查接口,并在可用时调用它。@Bergi这是一个很棒的主意,我会这么做的