复制自己的对象而不是参考(更新后的帖子,不同的Q)



解决方案

我仍然掌握着它的窍门,对你们很多人来说,这可能是合乎逻辑的。但我已经更新了我的帖子,也许有人会通过搜索来这里。

声明:

var test=Element({"id" : 1, "name" : "wrapper"}).
append(Element({"id" : 2, "name" : "elm A"}),
Element({"id" : 3, "name" : "elm b"})
);
alert(test.getInfo("name"));
alert(test.aArguments["children"][1].getInfo("name"));

"class":

var Element = function ($aPassArguments) {
aArguments: {
"id" : false,
"name" : false,
"type" : false,
"title" : false, 
"style" : false,
"action" : [],
"parent" : false,
"children" : []
};
for (var prop in this.aArguments)
if (prop in $aPassArguments) 
this.aArguments[prop] = $aPassArguments[prop];
return {
append: function () {
$argList = arguments;
for ($i = 0; $i < $argList.length; $i++)
if (typeof $argList[$i]=="string")
this.setChild(this.importDB($argList[$i],true));
else
this.setChild($argList[$i]);
},
setChild: function($oChild) {
this.aArguments["children"][this.aArguments["children"].length]=$oChild; 
}
};
};

上一次编辑

我不知道javascript中的新对象实例是引用而不是副本。现在我想要一个我自己的对象Element的副本。很有吸引力(谢谢@blurd)我希望它是一款工厂混合动力车:http://javascript.info/tutorial/factory-constructor-pattern

多亏了@blurd和我定义一些问题的帮助,我想出了一个解决方案,如下所示:

(但我对下面的用法声明不满意)

在其中,我最终获得了Element对象的副本,而不是引用。下面的好答案并不能完全解决我的问题。但这是由于我对问题的澄清和理解不力

某种解决方案

var Element = function (initialConfig) {
return {
aArguments: {
"id" : false,
"name" : false,
"type" : false,
"title" : false, 
"style" : false,
"action" : [],
"parent" : false,
"children" : [],
},

create:function ($aPassArguments) {
for (var prop in this.aArguments)
if (prop in $aPassArguments) 
this.aArguments[prop] = $aPassArguments[prop];
},
append: function () {
$argList = arguments;
for ($i = 0; $i < $argList.length; $i++)
if (typeof $argList[$i]=="string")
this.setChild(this.importDB($argList[$i],true));
else
this.setChild($argList[$i]);
},
setChild: function($oChild) {
this.aArguments["children"][this.aArguments["children"].length]=$oChild; 
}
};
};

用法

var test=Element();
test.create({"id" : 1, "name" : "wrapper"});
var test2=Element();
test2.create({"id" : 2, "name" : "elm A"});
test3.create({"id" : 3, "name" : "elm B"});
test.append(test2,test3);
alert(test.aArguments["name"]);
alert(test.aArguments["children"][0].aArguments["name"]);

现在我对用法很不满意,我希望它是一行,然后再次使用构造函数。这很有可能,而且。。。经过更多的自学,我可能会解决它。但现在我已经完成了:P刚刚更新了我的帖子。当我再次访问它并有一个更好的声明时,我会再次更新它。也许有人会分享一种方法(更好的方法)来做到这一点。最终拥有这样的东西:

var test=new Element({"id" : 3, "name" : "wrapper"})
.append( new Element{"id" : 3, "name" : "elm A"}), 
new Element({"id" : 3, "name" : "elm B"}) 
);

旧职位

我在这里把我的头发拔出来,我搜索到的关于javascript和对象的所有东西告诉我都是一样的,这是不够的,因为我不知道为什么下面的代码不能正常工作:

例如,我正在制作这样一个对象:

var Element = {
aArguments: {                                                       //set Default arguments
"id" : false,
"name" : false,
"type" : false,
"title" : false, 
"style" : false,
"action" : [],
"parent" : false,
"children" : {},
},
create:function ($aPassArguments) {
for (var prop in this.aArguments)
if (prop in $aPassArguments) 
this.aArguments[prop] = $aPassArguments[prop];
return this;
},
append: function () {
$argList = arguments;
for ($i = 0; $i < $argList.length-1; $i++)
if (typeof $argList[$i]=="string")
this.setChild(this.importDB($argList[$i],true));
else
this.setChild($argList[$i]);
return this;
},
setChild: function($oChild) {
this.aArguments["children"][this.aArguments["children"].length-1]=$oChild; 
},
getInfo: function($sKey) {
return this.aArguments[$sKey];
}
};

它将$aPassArgumentsthis合并。调用.create()时的参数(我无法说明是否可以使用'__constructor')。替换aArguments中的给定proparties

并使用添加传递的对象。将附加到aArguments["childeren"]

但是当我这样调用对象时:

$set=(Element.create({"id": 1, "name" : "wrapper"})).
append(Element.create({"id" : 3, "name" : "elm A"}));
alert($set.getInfo("name"));

它会提醒我"Elm A"而不是"wrapper"。

我认为这是因为我不是在创建Element的新对象,而是在处理同一个对象。现在,对我来说,逻辑解决方案和开始应该是写:

$set=(new Element.create({"id": 1, "name" : "wrapper"})).
append(new Element.create({"id" : 3, "name" : "elm A"}));
alert($set.getInfo("name"));

但我得到了错误:TypeError:(中间值)。append不是函数

为什么我的代码没有按照我的预期工作?这可能吗?如果可能,我该如何向对象添加构造函数?所以我可以跳过调用。创建并使用:

$set=new Element({"id": 1, "name" : "wrapper"}).
append(new Element({"id" : 3, "name" : "elm A"}));

您是对的,您应该使用new运算符。除此之外,看起来你正试图制造这种工厂混合动力车。我建议如下。

使用构造函数函数

包括创建对象时可以使用的可选配置。

var Element = function (initialConfig) {
if (initialConfig) {
this.create(initialConfig);
}
};

添加到原型

所有共享的Element成员都应该是原型的一部分。

Element.prototype = {
aArguments: {
"id" : false,
"name" : false,
"type" : false,
"title" : false, 
"style" : false,
"action" : [],
"parent" : false,
"children" : {},
},
create:function ($aPassArguments) {
for (var prop in this.aArguments)
if (prop in $aPassArguments) 
this.aArguments[prop] = $aPassArguments[prop];
return this;
},
append: function () {
$argList = arguments;
for ($i = 0; $i < $argList.length-1; $i++)
if (typeof $argList[$i]=="string")
this.setChild(this.importDB($argList[$i],true));
else
this.setChild($argList[$i]);
return this;
},
setChild: function($oChild) {
this.aArguments["children"][this.aArguments["children"].length-1]=$oChild; 
},
getInfo: function($sKey) {
return this.aArguments[$sKey];
}
};

示例

您的示例现在应该如您所期望的那样工作。请注意,不能调用new Element.create(),因为这会将Element.create视为构造函数。相反,将初始值传递到构造函数中。

$set = new Element({"id": 1, "name" : "wrapper"}).
append(new Element({"id" : 3, "name" : "elm A"}));
alert($set.getInfo("name"));

小心

您没有在循环中检查自己的属性,省略了{},我发现了至少一个隐含的全局属性。如果你不小心,JavaScript会咬你的。考虑使用JSLint或JSHint来帮助您发现这些问题。

您的create函数不创建任何对象,而是在放置Element. aArguments对象时进行更改。任何奇怪的事情都可能随之而来
不管怎样,只要选择一个干净简单的原型继承方案,不要使用$,记住总是声明你的vars,并保持简单:

function Element(initialValues) {
this.id = this.prototype.id++;
this.name = null;
this.type = null;
this.title = null;
this.style = null;
this.action = [];
this.parent = null;
this.children = [];
for (var prop in initialValues)
if (this[prop] != undefined) this[prop] = initialValues[prop];
}
Element.prototype = {
append: function () {
for (var i = 0; i < arguments.length - 1; i++) {
var thisElement = arguments[i];
if (typeof thisElement == "string") this.setChild(this.importDB(thisElement, true));
else this.setChild(thisElement);
}
return this;
},
setChild: function (child) {
this.children.push(child);
return this;
},
getInfo: function (key) {
return this[Key];
},
id: 0
};

最新更新