基础学习: 手撕源码之手写call、渡一

手撕源码之手写call【渡一教育】
更新于: 2023-09-15 07:50:56

题目

手撕源码之手写 call,学习中。

考点

  • 实现功能
  • 不能从 console 里看出异常(使用 Object.definePropery, enumtuble: false)
  • 使用 symbol
  • 处理 number/string/null/undefined 等异常情况
  • 不能使用 apply/bind 等方法

代码

基本实现逻辑是 context.fn(args) 直接调用。

Function.prototype.myCall = function () {
  const fn = this;
  const args = [...arguments];
  let context = args.shift();
  context = context == null ? globalThis : Object(context);
  
  // 使用 Symbol 防止重名
  const fnName = Symbol('fn');
  Object.defineProperty(context, fnName, {
    value: fn,
    enumerable: false,
  });
  return context[fnName](...args);
};


const obj = { name: 'obj' };

function fn() {
  console.log(this);
  console.log(this.name);
}

fn.myCall(obj, 1, 2); // obj

参考