区别
call、apply、bind我们要想实现它们首先要知道他们的异同
三者都是改变this的指向,把函数内this指向了第一个参数
不同点:
1、call、apply会执行函数,bind不会需要再次调用
2、传参区别,第一个参数都是函数内部this的指向,其余参数call、bind逐个传入,
apply以数组的形式传入
实现
1、三者由函数调用,所以线检查类型
2、根据传参不同,实现有所区别
call实现
Function.prototype.myCall = function(context) {
context = context || window;
if (typeof this !== 'function') {
throw new Error('type Error');
}
context.fn = this;
const argus = [...arguments].slice(1);
const result = context.fn(...argus);
delete context.fn;
return result;
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191226152412825.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BpZ19mdQ==,size_16,color_FFFFFF,t_70)
apply实现,基本上和call一样只是传参的区别
Function.prototype.myApply = function(context){
context = context || window;
if (typeof this !== 'function'){
throw new Error('type error')
}
context.fn = this;
let result;
if (arguments.length > 1){
const argus = arguments[1];
result = context.fn(argus);
} else {
result = context.fn();
}
delete context.fn;
return result;
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191226153618459.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BpZ19mdQ==,size_16,color_FFFFFF,t_70)
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));
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/2019122616101838.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BpZ19mdQ==,size_16,color_FFFFFF,t_70)