如何在JavaScript中传递方法?

3

我经常需要将对象中的方法传递到其他对象中。然而,我通常希望该方法附加到原始对象上(通过附加,我指“this”应该指向原始对象)。我知道一些方法可以实现这个目的:

a) 在对象构造函数中:ObjectA = function() { var that = this; var method = function(a,b,c) { that.abc = a+b+c }}

b) 将对象B传递给对象A:objectB.assign(function(a,b,c) { that.method(a,b,c) })

c) 在两个对象之外:objectB.assign(function(a,b,c) { objectA.method(a,b,c) })

我想知道是否有更简单的方法来传递附加到原始对象的方法。

3个回答

4
您可以为所有函数定义一个“createDelegate”方法:

您可以为所有函数定义一个“createDelegate”方法:

Function.prototype.createDelegate = function(scope) {
    var method = this;
    return function() {
        return method.apply(scope, arguments);
    }
}

然后像这样使用:

var myDelegate = myFunction.createDelegate(myScope);

调用"myDelegate"将使用指向"myScope"的"this",并使用与传递给myDelegate相同的参数执行"myFunction"


也许值得看一下Prototype的当前(1.7 RC 2)源代码中的Function#bind,它与ob1的createDelegate具有相同的目的,但在几个月前经过了相当一轮的性能测试和优化:http://github.com/sstephenson/prototype/blob/master/src/lang/function.js#LC108 另外:我会使用scope || undefined而不是scope || window,以避免不必要的浏览器特定性和window被覆盖的问题。使用undefined作为范围调用apply将使用全局对象。 - T.J. Crowder
@peterjwest:“虽然我还不理解它。” 它基本上是在做你正在做的事情:创建一个函数,当调用时,将使用给定的上下文(this值)调用实际目标函数。有时候更有效率的方法是使用闭包(其中你有 var self = this 然后一个使用 self.foo() 的函数来关闭它),其他时候使用像 ob1 的示例一样创建委托更有效率 - 对于相对较新的Javascript和/或不太了解闭包的人来说,后者更清晰易懂,这是有价值的。 - T.J. Crowder
@T.J. 提供的实现正是这样做的 - 创建一个函数,该函数关闭了方法、作用域和调用参数。 - ob1
@peterjwest:关于效率:ob1提供的委托方法的好处在于它非常容易使用,而且它只需要工作。我经常使用它。然而,有时候,如果你因为其他原因要创建闭包,就没有必要再增加一层间接性——相反,只需执行var self = this;,然后在闭包中使用self即可。同样地,每当我定义一个接受回调的API时,我总是允许调用者指定上下文并在给定时使用它;这样做的API意味着你根本不需要创建委托。 - T.J. Crowder
@T.J. 感谢您的澄清。关于 API 回调,您是指像 method(a, b, c, callback, context) 这样的东西,然后有一个默认上下文,比如 this 吗? - peterjwest
显示剩余4条评论

0

如果你喜欢的话,可以委托代理,或者直接从定义的方法作用域中调用缺少该方法的对象。

instance.method.call(Other-Object/*,argument,...*/)

例如,如果数组有一个过滤方法,您可以像调用节点列表对象的方法一样调用它。
var list=document.getElementsByTagName('p'), a=[], 

list= a.filter.call(list,function(itm){return itm.className=='sidebar'});

0
只要您使用适当的所有者对象调用其他方法,this 就会始终引用正确的所有者。

你认为我应该如何做?传递对象和表示方法的字符串:assign(object, 'method')?我不想在其他对象中硬编码方法名称。 - peterjwest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接