1

(开放编辑以获得更好的问题标题 - 很难说出我在寻找什么)

你好,

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

// 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();
};

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

x x x

y x x

z x x

我的问题是,为什么Rows原型没有被实例化为新的(就像Grid.prototype你每次调用时一样new Grid(),我该如何解决这个问题?

额外的想法

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

因此,在构造函数中,当我应用toGrid的新上下文时,最初将是蓝图的副本,而不是仅属于该实例的引用。thisthis.Rowsthis.RowsGrid.prototype.Rows

Grid构造函数中,我想我会修改this.Rows,例如,绑定到的上下文this,而不是原型本身。

发布答案

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

这里的小提琴说明了这一点。

4

1 回答 1

1

因为这就是原型的用途:它的所有成员对于每个实例都是相同的。例如,您可以调用this.Rows = Object.create(Grid.prototype.Rows);Grid 初始化函数,但您必须自己进行。JavaScript 不知道您需要为每个 Grid 实例创建一个新实例。

于 2013-03-12T11:36:03.073 回答