Join the Stack Overflow Community
Stack Overflow is a community of 6.3 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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

share|improve this question
up vote 2 down vote accepted

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.

share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.