質問

Since bind is not a cross browser (old ones) function , there is a polyfill for it : ( from John Resig's book)

/*1*/       Function.prototype.bind = function ()
/*2*/       {
/*3*/           var fn = this,
/*4*/               args = Array.prototype.slice.call(arguments),
/*5*/               object = args.shift();
/*6*/           return function ()
/*7*/           {
/*8*/               return fn.apply(object,
/*9*/                   args.concat(Array.prototype.slice.call(arguments)));
/*10*/           };
/*11*/       };

But I don't understand why do we need arguments at line #9.

I mean :

If I have this object :

var foo = {
    x: 3
}

And I have this function :

var bar = function(p,b){

    console.log(this.x+'        '+p+'   '+b);
}

So , if I want bar to run in the foo context , with parameters - All I need to do is :

 var boundFunc = bar.bind(foo,1,2)
 boundFunc ()...

So When I run var.bind(foo,1,2) the arguments is [object Object],1,2.

Those arguments are saved at line #4.

Great.

Now , the bind function returns its own closured function :

function ()
    {
        return fn.apply(object,
            args.concat(Array.prototype.slice.call(arguments)));
    } 

Question

Why do we need arguments here ? it seems that they are for something like :

var boundFunc = bar.bind(foo,1,2)
boundFunc (more1,more2....) //<----- ??

Am I missing something ?

Oonce I set the first var boundFunc = bar.bind(foo,1,2) , I already declared the parameters. why do we need them twice ?

役に立ちましたか?

解決

There are two places you can pass in arguments to the bound function:

1) When you call bind (the first arguments). These are always applied to the bound function when it is called.

2) When you call the bound function (the second arguments). These are the "more1, more2" that you mention. These change depending on what is provided when the bound argument is called.

Line 9 is combining the original bound arguments with the supplied extra arguments.

I guess the concept you might be confused about is that you don't have to bind ALL arguments initially - you can bind just the context object, or you can bind the first one argument as well but have callers of the bound function supply the rest. For example:

function sum() {
 var _sum = 0
 for (var i = 0; i < arguments.length ; i++) {
     _sum += arguments[i];
 }
 return _sum;
}
var sum_plus_two = sum.bind({},2);
sum_plus_two(5,7) == 14;

他のヒント

.bind also serves as partial application solution. Event handlers might be the best example:

var handler = function(data, event) { };

element.addEventListener('click', handler.bind(null, someData));

If the arguments from the actual function call wouldn't be passed on, you couldn't access the event object.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top