实现call、apply、bind,以及他们的区别

区别

call、apply、bind我们要想实现它们首先要知道他们的异同
三者都是改变this的指向,把函数内this指向了第一个参数
不同点:
1、call、apply会执行函数,bind不会需要再次调用
2、传参区别,第一个参数都是函数内部this的指向,其余参数call、bind逐个传入,
apply以数组的形式传入

实现

1、三者由函数调用,所以线检查类型
2、根据传参不同,实现有所区别
call实现
Function.prototype.myCall = function(context) {
	//第一个参数未传(null、undefined)时是window
	context = context || window;
	
	//console.log(this);
	//这里打印this得知在执行时this就是调用myCall的函数
	
	if (typeof this !== 'function') {
		throw new Error('type Error');
	}
	context.fn = this;
	//除第一个参数,其余参数是参入的实参
	const argus = [...arguments].slice(1);
	
	//调用myCall就执行函数,result就是返回值
	const result = context.fn(...argus);
	
	//把context上面的fn删除
	delete context.fn;
	return result;
}

在这里插入图片描述

apply实现,基本上和call一样只是传参的区别
Function.prototype.myApply = function(context){
	context = context || window;
	if (typeof this !== 'function'){
		throw new Error('type error')
	}
	context.fn = this;

	//在函数调用myApply时传参最多两个,第二个参数以数组形式传入
	//所以在context.fn(arguments[1])
	let result;
	if (arguments.length > 1){
		const argus = arguments[1];
		result = context.fn(argus);
	} else {
		result = context.fn();
	}
	delete context.fn;
	return result;
}

在这里插入图片描述

bind实现  bind返回的是改变this的函数
Function.prototype.myBind = function (context) {
	contex = context || window;
	if (typeof this !== 'function'){
		throw new Error('type error');
	}
	const _this = this;
	const argus = [...arguments].slice(1);
	return function () {
		return _this.apply(context, argus);
	}
}
这么些貌似可以实现,但是我们调用可以这样:fn.bind(obj)(1,2);
所以_this.apply(context, argus)参数不全
----------------------------------------------------

Function.prototype.myBind = function (context) {
	contex = context || window;
	if (typeof this !== 'function'){
		throw new Error('type error');
	}
	const _this = this;
	const argus = [...arguments].slice(1);
	return function () {
		_this.apply(context, argus.concat(...arguments));
	}
}
现在看来参数的问题解决了,但是我们还可以这么用bind
(new Fn()).bind(obj)(1,2)
---------------------------------------------------------

Function.prototype.myBind = function (context) {
	contex = context || window;
	if (typeof this !== 'function'){
		throw new Error('type error');
	}
	const _this = this;
	const argus = [...arguments].slice(1);
	return function Fn() {
		if (_this instanceof Fn) {
			return new _this(...argus, arguments);
		}
		_this.apply(context, argus.concat(...arguments));
	}
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值