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(); // Вася 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(); // Вася 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 :
[[BoundTargetFunction]] - link to the function that was called bind[[BoundThis]] - this value that will be passed when the function is called[[BoundArguments]] - a list of values that will be used as the first parameters when calling a functionIn addition, the internal method Call redefined for this object. It works as follows:
[[BoundArguments]] field [[BoundArguments]][[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.
Source: https://ru.stackoverflow.com/questions/798632/
All Articles