为什么这些绑定函数的“this”上下文在每个新实例中都是相同的?

时间:2013-03-12 11:16:08

标签: javascript prototype this

(打开编辑以获得更好的问题标题 - 很难说出我要找的内容)

嗨,

我一直在使用原型,但最近在原型中需要一个命名空间来对相关功能进行分组。代码以最简单的形式显示如下:

// Base grid functions.
Grid.prototype = {

    init: function init() {
        document.getElementById("output").innerHTML += "<br>" + this.id;

        this.Rows.init();

        this.Test.init();

        document.getElementById("output").innerHTML += "<br><br>";
    },

    Test: {
        init: function init() {
            document.getElementById("output").innerHTML += "<br>" + this.id;
        }
    }

};

// Additional row-related and row utility functions.
Grid.prototype.Rows = {

    init: function init() {
        document.getElementById("output").innerHTML += "<br>" + this.id;
    }
};

在我的Rows“命名空间”中,我想维护this的上下文,以便开发人员可以调用gridInstance.Rows.get()等函数,而不必在每个函数中传递上下文时间(通过电话或申请)。

为此,我使用LoDash的_.bind函数为每个与行相关的函数设置每个新Grid实例的上下文,我认为是什么。

注意Test“命名空间”纯粹是为了看看嵌套在Grid原型中时是否会产生不同的结果。

var Grid = function Grid(id) {
    var t = this;

    // Assign an id to the control.

    if (!id) {
        // Assign a custom id if the control does not have one.
        id = "grid-" + new Date().getTime();
    }

    t.id = id;

    _.each(t.Rows, function (rowFn, key) {
        t.Rows[key] = _.bind(rowFn, t);
    });

    _.each(t.Test, function (rowFn, key) {
        t.Test[key] = _.bind(rowFn, t);
    });

    t.init();
};

有一个小提琴here,显示输出:

x x x

y x x

z x x

我的问题是,为什么Rows原型没有被实例化为新的(例如每次调用Grid.prototypenew Grid(),我该如何解决这个问题?

其他想法

我的想法是Grid.prototype充当任何新Grid实例的蓝图,并且它将包含命名空间Rows作为其中的一部分。

因此,在Grid构造函数中,当我将this的新上下文应用于this.Rows时,this.Rows最初将是一个副本,而不是参考Grid.prototype.Rows蓝图,仅属于该实例。

Grid构造函数中,我认为我要修改this.Rows,对于该实例,要绑定到this的上下文,而不是原型本身。

发布答案

我的其他想法很愚蠢,因为我忘记了原型是从所有继承它的对象引用的,而不是用作对象实例的蓝图。

小提琴here说明了这一点。

1 个答案:

答案 0 :(得分:1)

因为这就是原型的用途:每个实例的所有成员都是相同的。 您可以在Grid init功能中调用this.Rows = Object.create(Grid.prototype.Rows);,例如,但您必须自己完成。 JavaScript不知道您希望每个Grid实例都有一个新实例。