封装call apply bind函数
三者的区别
如果当时就想执行,参数是数组用apply否则用call;如果是调用才执行,则用bind
🚩一、call函数
模拟实现第一步:整体思路
Function.prototype.call2=function(context){
context.fn=this; //1、将函数(谁调用 即this)设为对象(参数)的属性
context.fn(); //2、执行该函数
delete context.fn;//3、删除对象中的函数属性
}
模拟实现第二步:加上参数
Function.prototype.myCall = function (context, ...args) {
context = context || window;
context.fn = this;
let result = context.fn(...args);
delete context.fn;
return result;
}
function a(m, n) {
return console.log(this.name + ' ' + m + ' ' + n)
}
const b = {
name: 'kong'
};
a.myCall(b, 7, 8);
运行结果:
🚩二、apply函数
和call的思路是一样的,注意一下参数的处理即可
Function.prototype.myApply = function (context, arr) {
context = context || window;
context.fn = this;
let result
if (!arr) {
result = context.fn()
} else {
result = context.fn(arr)
}
delete context.fn
return result
}
function a(arr) {
return console.log(this.name + ' ' + arr)
}
const b = {
name: 'kong'
};
a.myApply(b, [7, 8]);
a.myApply(b);
运算结果:
🚩三、bind函数
- 因为 bind 的使用方法是 某函数.bind(某对象,...剩余参数),所以需要在 Function.prototype 上进行编程
- 将传递的参数中的某对象和剩余参数使用 apply 的方式在一个回调函数中执行即可
- 要在第一层获取到被绑定函数的 this,因为要拿到那个函数用 apply
Function.prototype.myBind = function (that, ...args) {
// 注意:这里不能用箭头函数 因为箭头函数中的this对象,就是定义时所在的对象,而不是使用时所在的对象。
const funcThis = this;
return (..._args) => {
// 注意箭头函数主体中只有一条语句时 可以省略return
return funcThis.apply(that, args.concat(_args));
}
}
function a(m, n, o) {
return console.log(this.name + ' ' + m + ' ' + n + ' ' + o)
}
const b = {
name: 'kong'
};
// a.myBind(b, 7, 8)(9);
a.myBind(b, 7, 8);
运行结果: