鱼C论坛

 找回密码
 立即注册
查看: 1804|回复: 2

JavaScript手写绑定

[复制链接]
发表于 2022-10-21 17:39:57 | 显示全部楼层 |阅读模式
30鱼币
      Function.prototype.myCall = function (ctx,...args) {
        ctx = ctx || window;
        let fn = Symbol();//下面有一个函数fn,这里的使用重复的fn有什么特殊意义吗?
        ctx[fn] = this;//函数fn调用,this指向fn
        let result = ctx[fn](...args);//这里fn函数的this怎么指向obj了?
        delete ctx[fn];//为什么要删除呢?
        return result;
      };

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

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

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

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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-10-21 21:14:09 | 显示全部楼层
第一个问题:没什么特殊意义,一个函数名叫什么都行
第二个问题:ctx是obj,这个问题实质上是对象调用方法,this指向对象
第三个问题:留着似乎没什么意义
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-6-15 17:31:24 | 显示全部楼层
来进一步解释一下:

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


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

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


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

总之,你对这个 myCall 方法的理解是完全正确的。如果有任何其他疑问,欢迎在评论或私信中提出。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 20:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表