Reading through the source at: .js
This is the _bind method so frequently used (I've removed the native check for clarity)
_.bind = function(func, obj) {
var args = slice.call(arguments, 2);
return function() {
return func.apply(obj, args.concat(slice.call(arguments)));
};
};
The args that get passed func.apply seems unnecessarily duplicated at the end
An example using Node interpreter (remove last line to try in Firebug etc..)
var arguments = [1,2,3,4,5,6];
var args = Array.prototype.slice.call(arguments, 2);
var appliedArgs = args.concat(Array.prototype.slice.call(arguments));
require('sys').puts(appliedArgs);
This outputs:
3,4,5,6,1,2,3,4,5,6
I highly doubt I've found a bug but confused as to why its working this way, why append the args again in such fashion. Confused
Reading through the source at: http://documentcloud.github.com/underscore/underscore.js
This is the _bind method so frequently used (I've removed the native check for clarity)
_.bind = function(func, obj) {
var args = slice.call(arguments, 2);
return function() {
return func.apply(obj, args.concat(slice.call(arguments)));
};
};
The args that get passed func.apply seems unnecessarily duplicated at the end
An example using Node interpreter (remove last line to try in Firebug etc..)
var arguments = [1,2,3,4,5,6];
var args = Array.prototype.slice.call(arguments, 2);
var appliedArgs = args.concat(Array.prototype.slice.call(arguments));
require('sys').puts(appliedArgs);
This outputs:
3,4,5,6,1,2,3,4,5,6
I highly doubt I've found a bug but confused as to why its working this way, why append the args again in such fashion. Confused
Share Improve this question edited Jan 8, 2012 at 22:39 Charles 51.4k13 gold badges106 silver badges144 bronze badges asked Apr 9, 2011 at 5:43 user53791user537912 Answers
Reset to default 16The bind method returns a closure, which can accept additional arguments to be passed to the function. The two references to arguments
in the underscore code do not refer to the same set of arguments. The first is from the enclosing function, and the second is from the returned closure. Here is a slightly modified version of this method, which hopefully makes it clearer:
_.bind = function(func, obj /*, arg1, arg2 ... argN */) {
// Prepare default arguments for currying, removing
// the function and object references
var args = Array.prototype.slice.call(arguments, 2);
// Return a closure that has access to the parent scope
return function(/* arg1, arg2 ... argN */) {
// Prepare arguments that are passed when bound
// method is called
var args2 = Array.prototype.slice.call(arguments);
// Curry the method with the arguments passed
// to the enclosing function and those passed
// to the bound method
return func.apply(obj, args.concat(args2));
}
This essentially allows you to curry a method when it is bound to an object. An example of its usage would be:
var myObj = {},
myFunc = function() {
return Array.prototype.slice.call(arguments);
};
myObj.newFunc = _.bind(myFunc, myObj, 1, 2, 3);
>>> myObj.newFunc(4, 5, 6);
[1, 2, 3, 4, 5, 6]
The call to _bind
binds an object and some arguments to a method. You can pass additional arguments to the bound method when you invoke it. You wouldn't likely pass the same arguments twice. Usage is:
function sum() {
var total = 0;
for (var i=0; i < arguments.length; ++i) {
total += arguments[i];
}
return total;
}
var sumsome = _bind(sum, {}, 1, 2, 3);
sumsome(4,5,6); // equivalent to the call ({summ: sum}).summ(1,2,3,4,5,6)
sumsome('a','b','c'); // equivalent to the call ({summ: sum}).summ(1,2,3,'a','b','c')