Reputation: 3234
I was reading the source code for pallet.js and came across this.
var ret = (function(proto) {
return {
slice: function(arr, opt_begin, opt_end) {
return proto.slice.apply(arr, proto.slice.call(arguments, 1));
},
extend: function(arr, arr2) {
proto.push.apply(arr, arr2);
}
};
})(Array.prototype);
var slice = ret.slice;
var extend = ret.extend;
Why is this necessary? Why could they not simply write this:
var slice = function(arr,opt_begin,opt_end) {
return Array.prototype.slice.apply(arr,[opt_begin,opt_end]));
}
var extend = function(arr,arr2) {
return Array.prototype.push.apply(arr,arr2);
}
EDIT 1:
In response to the duplicate question. I don't think it is a duplicate, but that question definitely does address my question. So it is an optimization. But won't each one only be evaluated once? So is there really a significant improvement here for two function calls?
Also if we are worried about performance why are we calling proto.slice.call(arguments,1)
instead of constructing the array of two elements by hand [opt_begin,opt_end]
, is slice faster?
Upvotes: 2
Views: 101
Reputation: 114491
I can't be sure what was the original rationale behind that code (only the author knows) but I can see a few differences:
proto
is a closed-over local variable, while instead Array
is a global. It's possible for a smart enough Javascript engine to optimize access because proto
is never changed and thus it could even be captured by value, not reference. proto.slice
can be faster than Array.prototype.slice
because one lookup less is needed.
passing opt_begin
and opt_end
as undefined
is not the same as not passing them in general. The called function can know if a parameter was passed and happens to be undefined
or if instead it wasn't passed. Using proto.slice.call(arguments, 1)
ensures that the parameters are passed to slice
only if they were actually passed to the closure.
Upvotes: 0
Reputation: 8192
Because the syntax is just so much cooler. Plus you can rationalize it's use by telling yourself that it's more DRY. You didn't have to type Array.prototype
twice.
Upvotes: 3