最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Underscore behavior with Bind - Stack Overflow

programmeradmin3浏览0评论

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 user53791user53791
Add a comment  | 

2 Answers 2

Reset to default 16

The 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')
发布评论

评论列表(0)

  1. 暂无评论