原型的JavaScript构造
考虑下面的例子原型的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函数可以使用上下文变量?
我怎么能创造酒吧函数将返回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具有相同的解决方案,但包裹在一个模块闭合)
谢谢,我想问题是“this”是函数之间唯一的向上关系,并且使用构造函数可以有效地除去它。这是javascript阻碍我的那些时刻之一。 – 2013-04-20 19:53:19
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();
这将工作。
是的,但是一旦我创建了多个fooInstance该方法就会中断。代码需要是动态的。每个fooInstance都是唯一的,每个bar实例必须能够获得它的唯一父对象。 – 2013-04-20 19:38:51
如果您需要从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();
这正是我的想法,但我正在设计一个API,并发现这个繁琐的用户。然而,尽管工厂方法消除了传递参数的烦人需求,但在我的程序中,使用新的前缀在逻辑上更合理,我宁愿让用户保持逻辑。子方法是否可以动态获取原始对象?通常绑定和使用这可以完成这一点,但由于构造函数的性质,不适用于此...是否有任何其他方式? – 2013-04-20 19:47:00
什么是'fooInstance'?什么是“Foo”的“孩子”和“父母”?什么是你调用但不定义的'bar'方法? “原型指令”是什么意思? – Bergi 2013-04-20 19:28:24
顺便说一句,[这个答案](http://*.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
让我把问题放在背景下。我在CanvasRenderingContext2D上进行原型设计,以便canvas元素的所有上下文都将包含我的新方法。让我们调用该方法foo并假定上下文是创建的画布上下文。如何像这样创建一个变量“new context.foo()”,使得foo函数可以使用上下文变量? – 2013-04-20 19:36:46