![](/img/trans.png)
[英]JS Array.prototype.filter with Array extending class constructor call
[英]JS Array.prototype.filter on prototype method
有一种更简单的方法来在没有匿名函数的原型方法上调用过滤器吗?
我想知道是否有与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);
让我们设置一些变量:
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
没有给你一个绑定到method
的call
版本。 为了安排call
绑定到右边this
method
,你需要绑定它:
array.filter(method.call.bind(method));
走过这个:
method.call.bind(method)
返回一个新版本的Function#call
,它绑定到X#method
; 把它想象成method.call(waiting)
,它等待用一个值来调用,该值将针对特定的X实例调用X#method
。
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
参数进行filter
您可以使用filter
及其兄弟(除了reduce )之前使用的context
参数,基本上,让filter
为您执行绑定,如果您选择以这种方式查看它,
Array#filter(fn, context) === Array#filter(fn.bind(context))
所以我们可以写:
array.filter(method.call, method);
这对我来说实际上看起来更干净 我怀疑它是否会变得简单得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.