Can anyone explain the thread, why does the information from the first bind , and not the last, appear?

 function f() { console.log(this.name); } f = f.bind({name: "Вася"}).bind({name: "Петя"}); f(); // Вася 

  • Explain what ?? - Andrey NOP

3 answers 3

To begin with, let's replace the standard bind method with our own function, which does the same thing. Binds context

 function myBind(func, thisArg) { return (function() { func.apply(thisArg); }); } function f() { console.log(this.name); } f = myBind(myBind(f, {name: "Вася"}), {name: "Петя"}); // Эквивалентно следующим двум строкам //f = myBind(f, {name: "Вася"}) //f = myBind(f, {name: "Петя"}); f(); 

And now myBind add logging to our myBind function myBind

 function objToStr(obj) { if (obj == window) return "window"; else return JSON.stringify(obj); } function myBind(func, thisArg, desc) { console.log("Bind: Desc: " + desc + ", thisArg: " + objToStr(thisArg) + ", this:" + objToStr(this)); return (function() { console.log("Call: Desc: " + desc + ", thisArg: " + objToStr(thisArg) + ", this:" + objToStr(this)); func.apply(thisArg); }); } function f() { console.log(this.name); } f = myBind(f, {name: "Вася"}, "first") f = myBind(f, {name: "Петя"}, "second"); console.log("After Bind"); f(); 

Those. as a result, our call to f() sequentially calls two wrappers, and at the end our function

    And a bit of specification . The bind function returns a so-called exotic object - similar to a function, but not a function.

    This object has three internal fields :

    1. [[BoundTargetFunction]] - link to the function that was called bind
    2. [[BoundThis]] - this value that will be passed when the function is called
    3. [[BoundArguments]] - a list of values ​​that will be used as the first parameters when calling a function

    In addition, the internal method Call redefined for this object. It works as follows:

    1. The arguments passed in the call are added to the list of arguments saved in the [[BoundArguments]] field [[BoundArguments]]
    2. Call the function stored in [[BoundTargetFunction]] with the transfer of the [[BoundThis]] field value and the updated list of arguments as this.

    So for the code

     function f() {...} var firstBind = f.bind({name: "Вася"}) var secondBind = fisrtBind.bind({name: "Петя"}); secondBind(); // Вася 

    calling secondBind() equivalent to calling firstBind.call({name: "Петя"}) , which, in turn, is equivalent to calling f.call({name: "Вася"}) because when calling an exotic this object, the called function is set directly from its internal field.

      The answer (explanation) is already given (o)! Here it is (or, if closer to the question, here ).

      I will quote the main thing:

      The first call to f.bind (.. Vasya ..) returns a "wrapper" that sets the context for f and passes the call to f.

      The next call to bind will set the context already for this wrapper. It will not affect anything.

      • Went to refresh the memory of the details of the work of bind , and there is the same question! - Dan
      • Amazing is next ... - Air