使用Javascript构造函数进行原型设计

时间:2013-04-20 19:22:12

标签: javascript function constructor prototype

请考虑以下示例

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的函数。需要注意的是,必须使用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上进行原型设计,以便canvas元素的所有上下文都包含我的新方法。让我们调用方法foo并假设context是一个创建的画布上下文。如何创建一个像“new context.foo()”这样的变量,以便foo函数可以使用上下文变量?

3 个答案:

答案 0 :(得分: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();

答案 1 :(得分:1)

  

如何在bar中创建一个返回fooInstance

的函数

如果将该函数作为构造函数调用(使用new),则无法真正执行此操作。 this keyword,对“父”(您调用该方法的对象)的唯一引用设置为构造函数调用中的新实例。你只能通过一个闭包获得引用,例如在父的构造函数中创建构造函数(这对你不起作用)或者从原型的闭包中返回构造函数(你在第二个例子中几乎得到了) ):

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有相同的解决方案,但包含在模块闭包中)

答案 2 :(得分:0)

Foo.prototype.bar只是原型Object of 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();

可行。