连续bind返回值的个人理解

我心飞翔 分类:javascript

对连续bind的一些理解:

先贴上自己理解的手写bind实现,参考了一些大佬的理解:

zhuanlan.zhihu.com/p/160315811

zhuanlan.zhihu.com/p/85438296

Function.prototype.myBind = function(asThis, ...arg) {
	let _this = this;
	if (typeof _this !== 'function') {
		throw new Error('not a function');
	}
	let newFn = function() {
		console.log('打印的asThis', asThis);//帮助理解
		console.log('打印的_this', _this);//帮助理解
		return _this.apply(
			newFn.prototype.isPrototypeOf(this) ? this : asThis,
			[...arg, ...arguments]
		)
	}
	newFn.prototype = _this.prototype;
	return newFn;
}
 

自己的测试运行代码:

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
 

浏览器打印出如下内容:

QQ拼音截图20210405005724.png
自己的理解:
1、bind()方法会创建一个新的函数;
2、bind()的第一个参数为新函数的this的指向,后边的参数会作为新函数的前几个参数传入;
3、新函数在运行时,会调用原函数;
4、连续bind会产生闭包,算是一种函数柯里化的应用。
fn.bind(o1, 10).bind(o2, 22).bind(o3, 99)(18);相当于:

let a = fn.bind(o1, 10);
let b = a.bind(o2, 22);
let c = b.bind(o3, 99);
c(18);
 

c(18)在运行的时候,会调用b函数,并把参数99, 18(bind直接绑定的参数会在前)传给b函数,b函数内部this指向o3;

b在运行的时候,会调用a函数,并把参数22, 99, 18传给a函数,a函数内部this指向o2;

a在运行的时候,会调用fn函数,并把参数10, 22, 99, 18传给fn函数,fn函数内部this指向o1;

即最后执行的时候相当于fn.apply(o1, 10, 22, 99, 18),this指向为o1,且fn会接收到10、22、99、18这四个参数。

上边的实现的myBind和js自身的bind有不一样的地方

测试代码如下:

let a = fn.bind(o1); //自带的bind
let aa = new a();
let b = fn.myBind(o1); //自己实现的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
 

产生了这些差异,自己的理解:

bind()方法会创建一个新的函数,这个新函数相当于原函数的副本,但在原型链上并不存在关系。新函数的prototype为undefined

(同样typeof值为'function',但prototype属性值为undefined的还有任意箭头函数,console.log等)

通过新函数new出来的实例,这个实例的__proto__指向原函数的prototype。理解为这个示例是由原函数这个构造函数生成的。

如何解决自己实现bind的这一不一致的问题,暂时没找到,希望读者可以帮忙解决这一不一致。

回复

我来回复
  • 暂无回复内容