李万金 发表于 2022-10-21 17:39:57

JavaScript手写绑定

      Function.prototype.myCall = function (ctx,...args) {
      ctx = ctx || window;
      let fn = Symbol();//下面有一个函数fn,这里的使用重复的fn有什么特殊意义吗?
      ctx = this;//函数fn调用,this指向fn
      let result = ctx(...args);//这里fn函数的this怎么指向obj了?
      delete ctx;//为什么要删除呢?
      return result;
      };

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

      let obj = {
      name: '111',
      };

      fn.myCall(obj, 23, '男');

问题在代码的第三第五第六行,各位大佬看一看,没想明白

李万金 发表于 2022-10-21 21:14:09

第一个问题:没什么特殊意义,一个函数名叫什么都行
第二个问题:ctx是obj,这个问题实质上是对象调用方法,this指向对象
第三个问题:留着似乎没什么意义

不二如是 发表于 2023-6-15 17:31:24

来进一步解释一下:


[*]1. fn 这个名字本身没有特殊意义,只是作为一个函数名使用。重要的是其作为 ctx 的一个属性,使得 fn 函数的 this 被绑定到 ctx(obj)上。所以名字可以任意,这里使用 fn 只是出于方便。
[*]2. 当以 obj 的形式调用 fn 时,fn 相当于 obj 的一个方法。所以其中的 this 自然指向 obj。这是 JavaScript 中函数调用和 this 绑定的规则。
[*]3. 如果不删除 ctx,则 ctx 对象会保留这个 fn 属性。由于 fn 仅用于临时改变 this,调用完毕就无用了。所以删除可以防止 ctx 对象有太多无意义的属性,保持其“整洁”。


所以,你的理解是完全正确的:


[*]1) 这里使用 fn 作为名字没有特殊意义,只是出于方便。重要的是它作为ctx的属性使用。
[*]2) obj 等同于 obj.fn,所以 fn 中的 this 指向 obj。这是 JS 的函数调用规则。
[*]3) 删除 ctx 的目的仅是为了保持 ctx 对象的“整洁”。如果不删除也不会对结果产生影响。


除此之外,这个 myCall 的实现还依赖了 Symbol() 来生成一个唯一的属性名,以避免命名冲突。这也是实现这个方法的关键。

总之,你对这个 myCall 方法的理解是完全正确的。如果有任何其他疑问,欢迎在评论或私信中提出。
页: [1]
查看完整版本: JavaScript手写绑定