Reputation: 15646
I achieve a forEach
function:
function forEach(arr, fn) {
for (var i = 0; i < arr.length; i++) {
fn.call({}, arr[i], i);
}
}
what I confused is about fn.call({}, arr[i], i);
the first parameter is pass empty just like above {}
is better
or pass this
in: fn.call(this, arr[i], i);
is better?
Or it doesn't matter
Upvotes: 0
Views: 70
Reputation: 301
Personally I would go with passing this. By passing {} you are limiting the flexibility of your function. You will never be able to bind another object to this function the way it is currently written. This won't work:
forEach.call(newContext, array, fn)
Neither will this:
forEach(array, fn.bind(newContext));
By binding {} inside your forEach you are adding unexpected behavior.
Upvotes: 0
Reputation: 413976
It matters quite a bit. The first parameter to .call()
is the value to be used for this
inside the called function. Thus, it doesn't make sense to talk about what value is "better"; the right value to pass is the one you need in order for the called function to operate properly.
For example, if you want to call a function on the Array prototype, then the value of this
inside that function has to be something that "feels like" an array (a "length" property and numerically-indexed properties). Thus:
var sneaky = {
"0": "hello",
"1": "world",
"length": 2
};
alert( Array.prototype.join.call(sneaky, " - ") ); // "hello - world"
That works because that function expects this
to refer to the array to be joined.
There are as many other examples as there are functions that have expectations about this
. In your sample code, passing {}
gives the called function a this
reference to that newly-created empty object. Will that work? I don't know, because that function could expect anything. There's no way to find out, either, except by looking at the code (or trusting documentation). If all you know is that it's some random arbitrary function, then {}
is a reasonable guess, though undefined
might be better, to force early failure.
Upvotes: 1