Skip to content

手写 call 函数

call 的使用

javascript
/***
 * 改变函数的this指向
 */
function addOne(...args) {
  console.log(args);
  console.log(this);
  return args.reduce((a, b) => a + b, 0);
}

let obj = {
  name: "zhangsan",
};
addOne(1, 2, 3);
let a = addOne.call(obj, 1, 2, 3); // 1, 2, 3
console.log(a);

call 函数的实现步骤:

  1. 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。
  2. 判断传入上下文对象是否存在,如果不存在,则设置为 window 。
  3. 处理传入的参数,截取第一个参数后的所有参数。
  4. 将函数作为上下文对象的一个属性。
  5. 使用上下文对象来调用这个方法,并保存返回结果。
  6. 删除刚才新增的属性。
  7. 返回结果。
javascript
// call函数实现
Function.prototype.myCall = function (context) {
  // 判断调用对象
  if (typeof this !== "function") {
    console.error("type error");
  }
  // 获取参数
  let args = [...arguments].slice(1),
    result = null;
  // 判断 context 是否传入,如果未传入则设置为 window
  context = context || window;
  // 将调用函数设为对象的方法
  context.fn = this;
  // 调用函数
  result = context.fn(...args);
  // 将属性删除
  delete context.fn;
  return result;
};

// call的实现
Function.prototype.myCall = function (context, ...args) {
  if (typeof this !== "function") {
    return new Error("this is not a function");
  }
  // 1. 处理this指向
  context = context || window; // 如果没有传入context, 默认指向window
  // 2. 处理函数的this指向
  context.fn = this; // 将函数挂载到context上
  // 3. 执行函数
  const result = context.fn(...args); // 执行函数
  // 4. 删除函数
  delete context.fn; // 删除挂载的函数
  // 5. 返回结果
  return result; // 返回结果
};

made with ❤️ by ankang