修复附加继承法中模拟重载的一缺陷
在关于JavaScript继承的一系列讨论中,我详细的介绍和比较了四种继承方式,其中第四种"附加继承法"是一种对重载支持的最好的方法。并且也在我的实际开发中广泛的使用了,不过近来我发现在多层次的重载中,又出现了一个非常严重的bug。
我们使用原来重载一文中的那个grandpa、father & son的示例:


















// 在此参考:Extends、Call方法
运行结果是三个期望的alert窗口:
No.1 alert:
grandpa's name: Michael
No.2 alert:
grandpa's name: John
father's name: John
No.3 alert:
grandpa's name: Tom
father's name: Tom
son's name: Tom
这时如果我们修改上面的示例,把son对象的getName()方法注释掉,再次运行上面的代码,这时IE就Stack Overflow并立即crash掉了。为什么会这样呢?
在重载(续)一文中,我们详细的介绍了Call的实现原理,以及它是怎么样去查找base类中的方法的。而问题就出在这个查找方法所属的类实例的这个过程中,当son对象没有getName()方法时,我们调用s.getName()实际已经就是调用的father的getName()方法,这时在Call方法的检索循环中出现如下值:
由于我们没有给son类实现getName()方法,在调用s.getName()的时候,执行查找方法的所在类的时候。如果条件: thatBase[key] == arguments.callee.caller 为true,那么会出现:thatBase.getName和thatBase.base.getName实际是同一个方法的引用的情况,这是因为son没有实现getName(),thatBase.getName就是father的getName,然后thatBase.base实际是father的实例,所以thatBase.getName和thatBase.base.getName是同一个方法的引用。从上图的wathc 1窗口中也可以看到使用toString()输出的是同一个方法的内容。
修复这个bug的方法需要继续读取继承树,即:target[key] == target.base[key] 时,让target = target.base;,修改后的源代码为:

















Function.prototype.Call = function(that)



































这样一来,我们就可以通过重载调用任意级别基类的方法了

posted on 2005-04-14 23:39 birdshome 阅读(2183) 评论(4) 编辑 收藏 举报
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库