Is there an easier way to call filter on a prototype method without an anonymous function?
I wonder if there is an equivalent to myArray.filter(function(it){ it.method() })
.
This looks close to what might work (it doesn't):
function X() {}
X.prototype.method = function() { console.log(this); }
[new X(), new X()].filter(X.prototype.method.call);
Instead I get a TypeError in both latest Firefox and Chrome, it's because it doesn't quite do what I want:
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
I tried using bind, maybe I'm missing it, but if it's not a one-liner, it's not any better than the anonymous method form:
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);
Let's set up some variables:
Your attempt can now be written as:
The problem is that
call
is getting called but with nothis
. It needs athis
ofmethod
.method.call
is precisely the same as the rawFunction.prototype.call
, with no binding to anythis
. Merely sayingmethod.call
does not give you a version ofcall
bound tomethod
. To arrange forcall
to be bound to the rightthis
, namelymethod
, you need to, well, bind it:Walking through this:
method.call.bind(method)
returns a new version ofFunction#call
which is bound toX#method
; think of it asmethod.call(waiting)
, which is waiting to be called with a value which will callX#method
against a particular instance of X.Array#filter
passes each argument in the array to that bound version ofFunction#call
, which results inmethod.call(elt, remaining_args...)
, which is the equivalent ofelt.method(remaining_args...)
.Output:
Some sugar
One could make this more semantic and readable with a little wrapper, which we will call
thisify
:Using the
context
parameter tofilter
You could use the little-used
context
parameter offilter
and its brethren (except reduce), essentially, lettingfilter
do the binding for you, if you choose to look at it that way, sinceSo we can just write:
That actually looks cleaner to me. I doubt if it could get much simpler than that.