我在创建对象的新实例时遇到问题。
使用下面的代码我希望每个元素都有自己的随机值(正在发生)。
但是我还希望this.element
值包含在对象的每个实例中,但是每次在对象的任何实例中更改值时,它都会在所有对象中更新。
var Instance = function(element) {
this.$element = $(element);
this.subInstance.parent = this;
}
Instance.prototype = {
subInstance: {
parent: null,
$element: null,
init: function() {
var $this = this;
this.$element = this.parent.$element;
//test for what this.$element refers to in init function
var random = Math.random();
$('.element', this.$element).text('Updated ' + random);
//test for what this.$element refers to in an event handler
$('.element', this.$element).on('click', function(e) {
$this.$element.css('background-color', '#f00');
});
}
}
}
$('div.instance').each(function(i, o) {
var instance = new Instance(o);
instance.subInstance.init();
});
现在我知道我可以使用this.subInstance = {...
将subInstance移出原型并进入构造函数,但这似乎不对,为什么this.$element
不包含在对象的每个实例中?
两个例子的JSFiddle:http://jsfiddle.net/q7zAg/
答案 0 :(得分:1)
看起来似乎不对,但事实并非如此。如果从构造函数创建的每个对象都需要使用唯一的subInstance
,则需要为每个单独的实例创建一个新对象。在prototype
,它将被共享。
然而,您可以做的一件事是使用Object.create
创建一个继承自原型subInstance
的新实例。然后,您将获得一些重用的好处,每个实例都可以修改自己的对象。
var Instance = function(element) {
this.$element = $(element);
this.subInstance = Object.create(this.subInstance);
this.subInstance.parent = this;
}
现在有些人可能认为subInstance
仍然不应该在prototype
上,而应该是IIFE中的局部变量。我倾向于同意这一点。
以下是一个例子:
var Instance = (function() {
var _subInstance = {
parent: null,
$element: null,
init: function() {
// ...
}
};
var Instance = function(element) {
this.$element = $(element);
this.subInstance = Object.create(_subInstance);
this.subInstance.parent = this;
};
// other prototyped props
Instance.prototype.foo = "bar";
return Instance;
})();
答案 1 :(得分:0)
注意函数的this
是根据函数的调用方式设置的,而不是如何声明或初始化函数(除了使用 bind )。
在您的代码中,您有:
> Instance.prototype = {
> subInstance: {
将对象分配给Instance.prototype
,该对象具有作为Object的subInstance
属性。
然后有:
> init: function() {
> var $this = this;
> this.$element = this.parent.$element;
该方法称为:
> instance.subInstance.init();
因此this
方法中的init
始终引用相同的对象(即Instance.prototype.subInstance
),因此this.$element
的分配会继续替换该值。
答案 2 :(得分:0)
var Obj =
{
internal:null,
__init:function(data){
this.internal = data;
return this
},
get:function(){
return this.internal;
},
init:function(){
var args = arguments,instance = function(){
return this.__init.apply(this,args);
};
instance.prototype = this;
return new instance();
}
}
console.log(Obj.init(123).get());
console.log(Obj.get());
console.log(Obj.init(321).get());
console.log(Obj.get());