是否有更简单的方法在没有匿名函数的原型方法上调用过滤器?
我想知道是否有等同于myArray.filter(function(it){ it.method() })
。
这看起来很接近可能有用的东西(它没有):
function X() {}
X.prototype.method = function() { console.log(this); }
[new X(), new X()].filter(X.prototype.method.call);
相反,我在最新的Firefox和Chrome中都遇到了TypeError,因为它并没有完全符合我的要求:
x = function() { console.log(this) }
x.call(123) //logs 123
y = x.call //reports that y is of type function in console
y(123) //TypeError: Function.prototype.call called on incompatible undefined
y.call(x, 123); //this is what you really need
我尝试使用bind,也许我错过了它,但如果它不是单行,那么它并不比匿名方法形式更好:
function X() {}
X.prototype.method = function() { console.log(this); }
y = X.prototype.method.call
y.bind(X.prototype.method)
[new X(), new X()].filter(y);
答案 0 :(得分:6)
让我们设置一些变量:
var method = X.prototype.method,
array = [new X(), new X()];
您的尝试现在可以写成:
array.filter(method.call);
问题是call
被调用但没有this
。它需要this
method
。 method.call
与原始Function.prototype.call
完全相同,不会绑定任何this
。仅仅说method.call
并未向您提供call
与[{1}}绑定的版本。要安排将method
绑定到右侧call
,即this
,您需要绑定它:
method
走过这个:
array.filter(method.call.bind(method));
返回一个新内容
绑定到method.call.bind(method)
的{{1}}版本;把它想象成
Function#call
,等待用a调用
将针对特定X实例调用X#method
的值。
method.call(waiting)
将数组中的每个参数传递给该绑定版本
X#method
的{{1}},结果为Array#filter
,
这相当于Function#call
。
输出:
method.call(elt, remaining_args...)
使用一个小包装器可以使它更具语义和可读性,我们称之为elt.method(remaining_args...)
:
> array.filter(method.call.bind(method));
X {method: function}
X {method: function}
thisify
参数function thisify(fn) { return fn.call.bind(fn); }
array.filter(thisify(method));
你可以使用context
及其兄弟(reduce除外)的少用filter
参数,基本上,让context
为你做绑定,如果你选择这样看,因为
filter
所以我们可以写:
filter
这对我来说实际上看起来更干净。我怀疑它是否比这更简单。