我正在使用一个数据对象点亮,然后尝试创建一个新对象,该对象仅为该实例更改data属性中的属性,这里是来自jsbin的一些测试代码
data = {
innerData : 1
}
-------------
'This works :-)'
construct = function(d){
this.data = Object.create(d);
};
construct.prototype.c = function(n){
this.data.innerData = n;
};
construct.prototype.d = function(){
console.log(this.data.innerData)
};
--------------
'This does not :-{'
construct = {
data : Object.create(data),
changeData : function(n){
this.data.innerData = n;
},
showData:function(){
console.log(this.data.innerData)
}
}
--------------
newInst = Object.create(construct);
newInst.changeData(5);
newInst.showData();
newInst2 = Object.create(construct);
newInst2showData();
当我使用构造函数/原型函数运行它时它工作,控制台输出5,2
当我使用对象文字运行它时,控制台输出5,5我想当我创建第一个实例时,它会更改实际数据对象而不是构造对象实例的数据属性。
如果有人能够深入解释为什么会发生这种情况会有很大帮助,因为我没有长时间与OOJS合作
更新
所以我有点想把我觉得有用的东西从答案中合并而且我想出了这个....
data = {
innerData : 1
}
function construct(d){
return {
data : Object.create(d),
changeData : function(n){
this.data.innerData = n;
},
showData : function(){
console.log(this.data.innerData)
}
}
}
build = function(){
return(new construct(data));
}
newInst = build();
newInst.changeData(5);
newInst.showData();
newInst2 = build();
newInst2.showData();
答案 0 :(得分:2)
鉴于我们对继承的了解,以下实际做了什么
this.data.innerData = n;
其中this
是Object.create(construct)
的结果?
this
没有自己的属性data
,因此请查看继承的属性。data === Object.getPrototypeOf(this).data
,称之为d
innerData
的{{1}}设置为d
那么实际结果是什么?{<1}}属性已经在 prototype 的引用上设置,而不是新的 Object 。 / p>
为什么会这样?因为如果您有n
并尝试执行innerData
,则会得到o = {}
,因此不会抛出错误,它必须访问已定义的对象< / em>的
o.foo.bar
答案 1 :(得分:1)
第二段代码工作正常:
construct.changeData(2);
construct.showData(); // 2
唯一的区别是,在上面的示例中,construct
不是构造函数,因此与第一种方法相比,只有construct.data
的单个实例;在其上调用Object.create()
将创建一个新对象,但将保留与第一个相同的.data
引用。
答案 2 :(得分:1)
在第二个示例中,只有一个data
对象。该对象位于construct
内,可用于原型链上的所有后续对象。
在第一个示例中,每次创建新实例时都会创建一个新的data
对象。因此每个对象都有自己的data
副本。
试试这个,第一个例子:
console.log(newInst.data === newInst2.data); // should be false
和第二个例子:
console.log(newInst.data === newInst2.data); // should be true
答案 3 :(得分:1)
这看起来像是尝试创建工厂函数而不是构造函数。由于Object.create
现在已经普及,并且可以在不可用的情况下用于这些目的,这可能是最好的默认值,尽管仍然有很多构造函数。
其他一些答案解释了您的尝试出了什么问题。这是你如何做到这一点,以便它按预期工作:
var factory = (function() {
var clone = function(obj) {return JSON.parse(JSON.stringify(obj));};
var data = {
innerData : 1
};
var proto = {
changeData : function(n){
this.data.innerData = n;
},
showData:function(){
console.log(this.data.innerData)
}
};
return function() {
var obj = Object.create(proto);
obj.data = clone(data);
return obj;
}
}());
但看起来你的innerData
可能是尝试让这些事情发挥作用的实验。它没有必要,这将更清洁:
var factory = (function() {
var proto = {
data: 1,
changeData : function(n){
this.data = n;
},
showData:function(){
console.log(this.data)
}
};
return function() {
return Object.create(proto);
}
}());