Observe the following:
function array_map(array, callback) {
for (var i = 0; i < array.length; i += 1) {
callback(array[i]);
}
}
var a = [], b = [];
array_map([1, 2, 3], function (x) { a.push(x); });
// just gives a = [1, 2, 3] as expected
// but why does this not work: ?
array_map([1, 2, 3], b.push);
// Chrome: a = [], Firefox: can't convert undefined to object
I do understand why this happens, namely: push is no longer bound to b (but to the global object) if you pass it to array_map directly. I don’t really understand why Chrome doesn’t give an error, at least Firefox seems to give some kind of error.
How can I detect if a function like this is passed to array_map to avoid these kinds of bugs?
I’m hoping there are advanced reflection techniques available to trace the origin of a function. For instance b.push.constructor gives Function, but that’s not what I’m looking for.
I’m not sure what you expect there to happen.Array.prototype.maprequires a function as second parameter, which returns a new value for every iteration.Passing in just a function reference (which you do in your second example) doesn’t tell the function what it has to do anyway. So you’re kinda expecting that
.map()applies some black magic and calls the passed in method with the correct parameter, which it obviously, can’t do.I totally didn’t get that you wrote your own mapping function. However, your problem there is that you’re losing scope of that
.push()function. Only if you call it on theArray / Objectlikexxx.push(), thethiswithin the called function will correctly reference the target object. Once you just passed the reference,thiswill either point to global /windoworundefinedand won’t work anymore.So solve that issue you could call it like
which also would apply an ES5 function. You can’t really detect for it within the
array_map(). A function is a function, your best shot would be to detect whether or not the passed in method is a native or not, but I wouldn’t recommend that.