我想在Javascript中执行此操作:
function Z( f )
{
f();
}
function A()
{
this.b = function()
{
Z( function () { this.c() } );
}
this.c = function()
{
alert('hello world!');
}
}
var foo = new A();
foo.b();
可以通过这种方式实现:
function Z( f )
{
f();
}
function A()
{
var self = this;
this.b = function()
{
Z( function () { self.c() } );
}
this.c = function()
{
alert('hello world!');
}
}
var foo = new A();
foo.b();
有更好的方法吗?
答案 0 :(得分:6)
保持对父级的引用(就像你一样)是一种很好的方法,但是对于你的具体例子,不需要匿名包装器,你可以直接传递函数,如下所示:
var self = this;
this.b = function()
{
Z(self.c);
}
You can test it out here,如果没有此包装器,实际上不需要self
变量,您可以直接使用this
,如下所示:
this.b = function()
{
Z(this.c);
}
You can test that version here
由于以下评论中似乎存在一些混淆,如果您想维护this
/上下文,上面的代码会为问题维护this
回调也是,使用.call()
like this:
this.b = function()
{
Z.call(this, this.c);
}
对于Z
:
function Z( f )
{
f.call(this);
}
答案 1 :(得分:1)
有一种模式通常被称为“委托”,它解决了这个问题。
在javascript中,一个不太花哨的实现可能看起来像这样:
/** class Delegate **/
var Delegate = function(thisRef, funcRef, argsArray) {
this.thisRef=thisRef;
this.funcRef=funcRef;
this.argsArray=argsArray;
}
Delegate.prototype.invoke = function() {
this.funcRef.apply(this.thisRef, this.argsArray);
}
/** static function Delegate.create - convenience function **/
Delegate.create = function(thisRef, funcRef, argsArray) {
var d = new Delegate(thisRef, funcRef, argsArray);
return function() { d.invoke(); }
}
在您的示例中,您可以像这样使用它:
this.b = function() {
Z( Delegate.create(this, this.c) );
}
您还可以编写期望接收代表的函数:
function Z( d ) {
d.invoke();
}
然后,在A
中,b
的impl变为:
this.b = function() {
var d = new Delegate(this, this.c);
Z( d );
SomeOtherFunc( d );
}
Delegate
只是提供了一种简单,一致的方法来封装this
引用(你称之为self
),在一个可以像任何其他方式处理的对象实例中对象实例。它更具可读性,它使您不必使用诸如self
之类的多余变量来污染您的功能范围。一个更高级的代表实现可以有自己的方法和其他相关的状态。也可以通过这种方式构建委托,以便最大限度地减少与范围相关的内存管理问题(虽然我在这里展示的代码绝对不是一个例子)。
答案 2 :(得分:1)
您也可以使用
this.b = function()
{
Z( (function () { this.c() }).apply(this) );
}