前端积累 | 手写Function.prototype.call和apply()

296 阅读1分钟

这是函数对象原型上的两个方法,可以修改对象绑定的this。两个方法接受的第一个参数都是需要绑定的对象,apply后续只再接受一个参数作为函数原本需要传的参数数组,而call则后续接受若干个参数来实现同样的功能。

function add(a,b){
    return `${this},${a+b}`;
}
let obj={};
add(1,2);// [object global],3
add.call(obj,3,4);// [object Object],7
add.apply(obj,[3,4]);// [object Object],7

实现思路

  1. 把函数作为一个新属性添加到想绑定的对象上
  2. 让对象运行一下添加的新属性
  3. 删除对应的属性

代码示例

function add(a,b){
    return `${this},${a+b}`;
}
let obj={};
// context便是你想绑定的对象,...params就是参数数组
Function.prototype.myCall = function(context,...params){
    context.newFunction = this;
    const result = context.newFunction(...params);
    delete context.newFunction;
    return result;
}
Function.prototype.myApply = function(context, params){
    context.newFunction = this;
    const result = context.newFunction(...params);
    delete context.newFunction;
    return result
}
add(1,2);// [object global],3
add.myCall(obj,3,4);// [object Object],7
add.myApply(obj,[3,4]);// [object Object],7

可能存在的问题

  • 如果需要绑定的context本身存在newFunction属性,那么绑定的结果就会占用之前的属性,就会造成问题。
  • 如果我们传的contextnull的话,函数便不会被执行。
  • 如果context是基本类型的话,也需要特别判断。