0

考虑以下示例

var Foo = function(){
    this.identity = 'Foo';
};
Foo.prototype.bar = function(){
    this.identity = 'bar';
};
var fooInstance = new Foo(),
    bar = new fooInstance.bar();

问题

在 内bar,我如何获得fooInstance变量?有没有办法让孩子Foo识别其父母fooInstance?例如,我如何创建一个bar返回的函数fooInstance。一个小小的警告是 bar 必须使用prototype命令创建,不能简单地嵌套Foo以访问任何Foo实例。

我的想法以及为什么它们不起作用

可以像这样重写函数

var Foo = function(){
    this.identity = 'Foo';
};
Foo.prototype.createBar = function(){
    var parent = this;
    function bar(){
        this.parent = parent;
        this.identity = 'bar';
    };
    return new bar();
};
var fooInstance = new Foo(),
    bar = fooInstance.createBar();

然而,为了创建易于阅读的代码,如果不需要,我宁愿不使用这种方法。

进一步澄清

让我把这个问题放在上下文中。我在 CanvasRenderingContext2D 上进行原型设计,以便画布元素的所有上下文都包含我的新方法。让我们调用该方法 foo 并假设 context 是创建的画布上下文。如何创建像“new context.foo()”这样的变量,以便 foo 函数可以使用上下文变量?

4

3 回答 3

2

如果你需要fooInstance从对象中引用bar对象,你可以像这样使用依赖注入:

Foo.prototype.bar = function(fooInstance) {
    this.identity = 'bar';
    this.fooInstance = fooInstance;
};

var fooInstance = new Foo(),
    bar = new foo.bar(fooInstance);

您可以通过在Foo.

Foo.prototype.createBar = (function() {
    function Bar(parent){
        this.parent = parent;
        this.identity = 'bar';
    };

    return function () {
        return new Bar(this);
    };
})();

var fooInstance = new Foo(),
    bar = fooInstance.createBar();
于 2013-04-20T19:33:17.883 回答
1

我如何在 bar 中创建一个返回 fooInstance 的函数

如果该函数被调用为构造函数(使用new),则您无法真正做到这一点。this关键字,对“父”(您调用该方法的对象)的唯一引用在构造函数调用中设置为新实例。您只能使用闭包来获取引用,例如通过在父构造函数中创建构造函数(这对您不起作用)或通过从原型上的闭包返回构造函数(您在第二个示例中几乎得到了):

Foo.prototype.getBarCoonstructor = function() {
    var parentFoo = this;
    return function Bar() {
        // constructor things
        // using "parentFoo" reference
    };
};
// Usage:
var bar = new (foo.getBarConstructor()) (); // ugly.

与其为每次调用创建新的构造函数getBarConstructor,不如将其放在方法之外并parentFoo作为参数。你的想法已经很不错了。

function Bar(parent) {
    // constructor things, referring "parent"
}
Bar.prototype.… = …;

Foo.prototype.createBar = function() {
    return new Bar(this); // passing the Foo instance
};

(@plalx 具有相同的解决方案,但包装在模块闭包中)

于 2013-04-20T19:50:35.783 回答
0

Foo.prototype.bar只是Foo原型对象上的一个函数。除非您在其作用域链中明确定义它,否则该函数无法知道其“父级”。

即如果你愿意

var Foo = function(){
    this.identity = 'Foo';
};
var fooInstance = new Foo();

Foo.prototype.bar = function(){
    console.log(fooInstance); // retrieve from scope
    this.identity = 'bar';
};
bar = new foo.bar();

那行得通。

于 2013-04-20T19:32:56.037 回答