When using higher order function of the Array API in javascript (forEach, map, filter, etc.) there are 2 means to pass "this" variable :
myArray.forEach(function(value) {
    this.aContextualFunction();
}, this);
Or
var self = this;
myArray.forEach(function(value) {
    self.aContextualFunction();
});
Which one is the better ? What are the pros and cons ?
Example: http://jsfiddle.net/TkZgX/
I always prefer the first one.
pro: no extra var declaration
con: maybe confusion as seen in the comments on this question..
When using higher order functions I prefer my functions not to make any assumptions about the callbacks it receives as arguments. In general, the more loosely coupled the code the better.
For example, say I write a higher order function for forEach:
function forEach(array, callback, that) { // that is optional
    var length = array.length;
    for (var i = 0; i < length; i++)
        callback.call(that, array[i], i); // pass the value and the index
}
Now say I want to use it:
Array.prototype.double = function () {
    forEach(this, function (value, index) {
        this[index] = 2 * value;
    });                                     // oops, I forgot that
};
var array = [1, 2, 3];
array.double();
The above code will cause variables to leak into the global scope. Not a good thing. See the demo here: http://jsfiddle.net/8dad4/
What's the alternative? Remove the optional third parameter and use closures:
function forEach(array, callback) {
    var length = array.length;
    for (var i = 0; i < length; i++)
        callback(array[i], i);
}
Not only is the code smaller, but there won't be any accidental global leaks (unless you use this instead of the external that like an idiot). Let's see an example:
Array.prototype.double = function () {
    var that = this;
    forEach(this, function (value, index) {
        that[index] = 2 * value;
    });
};
var array = [1, 2, 3];
array.double();
The demo is here: http://jsfiddle.net/8dad4/1/
Hmmm... that doesn't seem very enticing - I don't want to create a new variable. May we do something better? Yes, we sure can. This is the method I prefer (we still use the second forEach function):
Array.prototype.double = function () {
    forEach(this, function (value, index) {
        this[index] = 2 * value;
    }.bind(this));
};
var array = [1, 2, 3];
array.double();
The demo is here: http://jsfiddle.net/8dad4/2/
Wow, isn't this better? We combined both methods one and two. Advantages:
forEach function doesn't assume anything. The code is more loosely coupled.that. No closures needed.We can do this because the anonymous function passed to forEach is a function expression. So we just append .bind(this) to it and we're done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With