Some understanding of continuous bind:
First paste the handwritten bind implementation you understand, and refer to the understanding of some bosses:
Function.prototype.myBind = function(asThis, ...arg) { let _this = this; if (typeof _this !== 'function') { throw new Error('not a function'); } let newFn = function() { console.log('Printed asThis', asThis);//Help understand console.log('Printed_this', _this);//Help understand return _this.apply( newFn.prototype.isPrototypeOf(this) ? this : asThis, [...arg, ...arguments] ) } newFn.prototype = _this.prototype; return newFn; }
Own test run code:
function fn(age) { console.log(arguments); console.log(this.name, age); } let o1 = { name: 'xiao_ming' }, o2 = { name: 'xiao_hong' }, o3 = { name: 'xiao_jun' }; let a = fn.bind(o1, 10); let b = a.bind(o2, 22); let c = b.bind(o3, 99); c(18); //xiao_ming 15 fn.bind(o1, 10).bind(o2, 22).bind(o3, 99)(18); //xiao_ming 10 fn.myBind(o1, 10).myBind(o2, 22).myBind(o3, 99)(18); //xiao_ming 10
The browser prints the following:
Own understanding:
1. The bind() method will create a new function;
2. The first parameter of bind() is the direction of this of the new function, and the following parameters will be passed in as the first few parameters of the new function;
3. When the new function is running, it will call the original function;
4. Continuous bind will produce closures, which is an application of function curry.
fn.bind(o1, 10).bind(o2, 22).bind(o3, 99)(18); amount to:
let a = fn.bind(o1, 10); let b = a.bind(o2, 22); let c = b.bind(o3, 99); c(18);
When c(18) is running, it will call b function and pass the parameters 99 and 18 (the parameters directly bound by bind will be in the front) to b function. this in b function points to o3;
When b is running, it will call function a and pass the parameters 22, 99 and 18 to function A. this in function a points to o2;
When a is running, it will call fn function and pass parameters 10, 22, 99 and 18 to fn function. this in fn function points to o1;
That is, the final execution is equivalent to fn Apply (o1, 10, 22, 99, 18), this points to o1, and fn will receive four parameters: 10, 22, 99 and 18.
The myBind implemented above is different from the bind of js itself
The test code is as follows:
let a = fn.bind(o1); //Self contained bind let aa = new a(); let b = fn.myBind(o1); //Self implemented bind let bb = new b(); console.log(a.prototype); //undefined console.log(aa.__proto__ === a.prototype); //false console.log(aa.__proto__ === fn.prototype); //true console.log(b.prototype); //{constructor: ƒ} console.log(bb.__proto__ === b.prototype); //true console.log(bb.__proto__ === fn.prototype); //true
As a result of these differences, my own understanding:
The bind() method will create a new function, which is equivalent to a copy of the original function, but there is no relationship on the prototype chain. The prototype of the new function is undefined
(similarly, if the typeof value is' function ', but the prototype attribute value is undefined, there are also any arrow functions, console.log, etc.)
The instance through the new function NEW__ proto__ Point to the prototype of the original function. It is understood that this example is generated by the constructor of the original function.
How to solve this inconsistency in the implementation of bind has not been found yet. I hope readers can help solve this inconsistency.
Article transferred from
Personal understanding of the return value of continuous bind