作为参考的对象的新实例?

时间:2012-11-04 22:32:23

标签: javascript object reference prototype instance

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

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

但是我还希望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/

3 个答案:

答案 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());