原型方法上的JS Array.prototype.filter

时间:2014-08-09 03:25:01

标签: javascript

是否有更简单的方法在没有匿名函数的原型方法上调用过滤器?

我想知道是否有等同于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);

1 个答案:

答案 0 :(得分:6)

让我们设置一些变量:

var method = X.prototype.method,
    array = [new X(), new X()];    

您的尝试现在可以写成:

array.filter(method.call);

问题是call被调用但没有this。它需要this methodmethod.call与原始Function.prototype.call完全相同,不会绑定任何this。仅仅说method.call并未向您提供call与[{1}}绑定的版本。要安排将method绑定到右侧call,即this,您需要绑定它:

method

走过这个:

  1. array.filter(method.call.bind(method)); 返回一个新内容 绑定到method.call.bind(method)的{​​{1}}版本;把它想象成 Function#call,等待用a调用 将针对特定X实例调用X#method的值。

  2. method.call(waiting)将数组中的每个参数传递给该绑定版本 X#method的{​​{1}},结果为Array#filter, 这相当于Function#call

  3. 输出:

    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

    这对我来说实际上看起来更干净。我怀疑它是否比这更简单。