手写call

71 阅读1分钟
//call方法要立即执行调用他的函数+改变this
Function.prototype.myCall = function (ctx, ...args) {
  //利用symbol防止传入的函数与自定义的属性重名
  let key = Symbol("context");

  ctx[key] = this; //这里this指向调用call的函数,把这个函数添加到一个属性上,再调用这个属性来执行
  ctx[key](...args);
  //用完这个属性就删掉
  delete ctx[key];
};

测试一下:

function method(a, b) {
  console.log(this, a, b);
  return a + b;
}

打印的结果是这样的,但是我们不希望this展示出这么多东西,期望结果{} image.png

可以通过Object.defineProperty() 根据描述符创建一个新的属性

//call方法要立即执行调用他的函数+改变this
Function.prototype.myCall = function (ctx, ...args) {
   ctx = (ctx === null || ctx === undefined) ? globalThis : Object(ctx) 
  //利用symbol防止传入的函数与自定义的属性重名
  let key = Symbol("context");

  //这里this指向调用call的函数,把这个函数添加到一个属性上,再调用这个属性来执行
  //用defineProperty把key属性加到ctx上,这个属性是不可枚举,可删除的且值为this
  Object.defineProperty(ctx,key,{
    value:this,
    enumerable:false,
    configurable: true,
  })
  //调用
  let result = ctx[key](...args)
  //用完这个属性就删掉
  delete ctx[key];
  return result
};