【JavaScript】原生实现call bind apply

回顾call apply bind用途

let obj = {
	name:"obj1"
	say:function(){
		//输出arguments
		console.log(arguments);
		console.log(this.name);
	}
	let obj2 = {
		name:"obj2";
	}
	obj.say();
	obj.say.call(obj2,1,2,3);
	obj.say.apply(obj2,[1,2,3]);
	sayClone = obj.bind(obj,1,2,3);
	sayClone();
}

原生实现bind()

bind的特点:

  1. 接受调用传参和新建对象构造函数传参
  2. 如果是外部没有传入this就要新建一个this
  3. 和call接受的参数和实现的回调功能一样
  4. 返回的是一个新创建的原来传入的this克隆的对象
//函数的构造函数 : Function
//用es6解构rest的方式传参
Function.prototype.myBind = function(objThis,...params){
	//定义指向当前函数this的指针
	const thisTn = this;
	//因为最终返回的是一个函数,所以声明一个函数返回
	//用let表示块作用域
	let funcForBind = function(...secondParams){
		/*因为例如
		let sayClone = obj.say.bind(obj2,1,2,3);
		sayClone(4);
		这里还是可以进行传参,最终传的就是1,2,3,4,所以可以用解构	...secondParams
		*/
		//判断是不是新创建的对象 如果新创建的对象的话 this就是当前函数的this 不是新创建的话就是传进来的那个对象的上下文
		const isNew = this instanseof funcForBind;
		const thisArg = isNew ? this : objThis;
		//返回调用 并分别解构传入的参数params和创建对象传入的参数secondParams
		return thisFn.call(thisArg,...params,...secondParams);
	}
	//因为bind返回的是克隆的对象,所以还要把原型链进行克隆
	funForBind.prototype = Object.create(thisFn.prototype);
	return funcForBind;
}

原生实现call()和apply()

之前的例子:

//给obj2增加一个obj的call的函数,然后用传入的参数进行调用返回最终值
obj.say.call(obj2,1,2,3);
Function.prototype.myCall = function(thisArg,...arr){
	if(thisArg == null || thisArg == undefined){
		thisArg = window;
	}
	//定义一个不重复的方法名称
	const specialMethod = Symbol('anything');
	//将这个不重复的方法Function的指针给thisArg的specialMethod方法
	thisArg[specialMethod] = this;
	//调用函数并结果返回
	let result = thisArg[specialMethod](...arr);
	//delete 新增的属性
	delete thisArg[specialMethod];
	return result;
}
obj.say.myCall(obj2,1,2,3);
Function.prototype.myApply = function(thisArg,arr){
	if(thisArg == null || thisArg == undefined){
		thisArg = window;
	}
	//定义一个不重复的方法
	const specialMethod = Symbol('anything');
	//将这个不重复的方法的指针给thisArg的specialMethod方法
	thisArg[specialMethod] = this;
	//调用函数并结果返回
	let result = thisArg[specialMethod](...arr);
	//delete 新增的属性
	delete thisArg[specialMethod];
	return result;
}
obj.say.myApply(obj2,[1,2,3]);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值