0

我在创建对象的新实例时遇到问题。

使用下面的代码,我期望每个元素都有自己的随机值(正在发生)。

但是后来我也期望该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();
});​

现在我知道我可以将 subInstance 移出原型并使用构造函数,this.subInstance = {...但这似乎是错误的,为什么this.$element不包含在对象的每个实例中?

两个示例的 JSFiddle:http: //jsfiddle.net/q7zAg/

4

3 回答 3

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;
})();
于 2012-11-04T22:37:57.300 回答
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());
于 2013-02-06T07:30:03.843 回答
0

请注意,函数的this设置取决于函数的调用方式,而不是它的声明或初始化方式(使用bind除外)。

在您的代码中,您有:

> Instance.prototype = {
>     subInstance: {

它将对象分配给Instance.prototype具有subInstanceObject 属性的对象。

然后是:

>         init: function() {
>             var $this = this;
>             this.$element = this.parent.$element;

该方法被称为:

> instance.subInstance.init();

所以thisinit方法内总是引用同一个对象(即Instance.prototype.subInstance),所以赋值要this.$element不断替换值。

于 2012-11-04T23:29:06.100 回答