2013-04-20 60 views
0

考虑下面的例子原型的JavaScript构造

问题

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并假定上下文是创建的画布上下文。如何像这样创建一个变量“new context.foo()”,使得foo函数可以使用上下文变量?

+1

什么是'fooInstance'?什么是“Foo”的“孩子”和“父母”?什么是你调用但不定义的'bar'方法? “原型指令”是什么意思? – Bergi 2013-04-20 19:28:24

+0

顺便说一句,[这个答案](http://stackoverflow.com/questions/13418669/javascript-do-i-need-to-put-this-var-for-every-variable-in-an-object/13418980# 13418980)可能会帮助您了解变量和属性之间的差异。 – Bergi 2013-04-20 19:31:16

+0

让我把问题放在背景下。我在CanvasRenderingContext2D上进行原型设计,以便canvas元素的所有上下文都将包含我的新方法。让我们调用该方法foo并假定上下文是创建的画布上下文。如何像这样创建一个变量“new context.foo()”,使得foo函数可以使用上下文变量? – 2013-04-20 19:36:46

回答

1

我怎么能创造酒吧函数将返回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具有相同的解决方案,但包裹在一个模块闭合)

+0

谢谢,我想问题是“this”是函数之间唯一的向上关系,并且使用构造函数可以有效地除去它。这是javascript阻碍我的那些时刻之一。 – 2013-04-20 19:53:19

0

Foo.prototype.bar只是一个关于Foo原型的函数。除非您在其范围链中明确定义它,否则没有办法让该函数知道其“父”。

I.e.如果你愿意

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

这将工作。

+0

是的,但是一旦我创建了多个fooInstance该方法就会中断。代码需要是动态的。每个fooInstance都是唯一的,每个bar实例必须能够获得它的唯一父对象。 – 2013-04-20 19:38:51

2

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

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(); 
+0

这正是我的想法,但我正在设计一个API,并发现这个繁琐的用户。然而,尽管工厂方法消除了传递参数的烦人需求,但在我的程序中,使用新的前缀在逻辑上更合理,我宁愿让用户保持逻辑。子方法是否可以动态获取原始对象?通常绑定和使用这可以完成这一点,但由于构造函数的性质,不适用于此...是否有任何其他方式? – 2013-04-20 19:47:00