手写apply、bind、call
apply
首先分析apply调用的时候主要传入俩种参数,第一个是目标this,第二个是需要调用的参数。参数可以是多个,最后都会传入到函数中,并且返回值是函数的返回值。
-
获取需要执行的函数(就是 this,因为 call 的调用都是 fn.call(),fn 是一个函数)
-
对 thisArg 进行转换成对象类型(防止传入的是一个非对象类型),这个 thisArg 就是需要绑定的 this
-
调用需要被执行的函数(通过给 thisArg 增加方法属性)
Function.prototype.myApply = function (thisArg, args) {
// 拿到函数体
const fn = this;
args = args || [];
//需要的函数指向
const thisArgs =
thisArg !== null && thisArg !== undefined ? Object(thisArg) : Window;
// 模板this上挂载函数
thisArgs.fn = fn;
const res = thisArgs.fn(...args);
delete thisArgs.fn;
return res;
};
bind
分析bind传入特点:主要传入两种参数:一个是目标this,第二个是需要调用的参数。参数可以是多个,最后都会传入到函数中,并且返回值是改变到目标this的函数。
-
获取需要执行的函数(就是 this,因为 bind 的调用都是 fn.bind(),fn 是一个函数)
-
对 thisArg 进行转换成对象类型(防止传入的是一个非对象类型),这个 thisArg 就是需要绑定的 this
-
返回一个函数
-
返回的函数内部调用需要被执行的函数(通过给 thisArg 增加方法属性)
-
调用时将参数传递进去,返回的函数可能能够接收到参数,所以需要将返回函数的参数也传入进去
Function.prototype.myBind = function (thisArg, ...arg) {
// 函数体
const fn = this;
// 获取this指向
const thisArgs =
thisArg !== null && thisArg !== undefined ? Object(thisArg) : Window;
// 先在this上挂载fn。
thisArgs.fn = fn;
// 返回函数
return (...arg1) => {
thisArgs.fn(...arg, ...arg1);
// 执行完毕要删除在函数体的挂载
delete thisArgs.fn;
};
};
call
分析call传入特点:主要传入两种参数:一个是目标this,第二个是需要调用的参数。参数可是一个数组,最后数组里面的参数会依次传入到函数中,并且返回值是改变到目标this的函数。
-
获取需要执行的函数(就是 this,因为 call 的调用都是 fn.call(),fn 是一个函数)
-
对 thisArg 进行转换成对象类型(防止传入的是一个非对象类型),这个 thisArg 就是需要绑定的 this
-
调用需要被执行的函数(通过给 thisArg 增加方法属性)
Function.prototype.myCall = function (thisArg, ...args) {
// 拿到函数体
const fn = this;
//需要的函数指向
const thisArgs =
thisArg !== null && thisArg !== undefined ? Object(thisArg) : Window;
// 模板this上挂载函数
thisArgs.fn = fn;
const res = thisArgs.fn(...args);
delete thisArgs.fn;
return res;
};