在关于JavaScript继承的一系列讨论中,我详细的介绍和比较了四种继承方式,其中第四种"附加继承法"是一种对重载支持的最好的方法。并且也在我的实际开发中广泛的使用了,不过近来我发现在多层次的重载中,又出现了一个非常严重的bug。
我们使用原来重载一文中的那个grandpa、father & son的示例:
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334110/20241017/7bff2bc0788c45e6bd9afd135d4971cd.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334110/20241017/50d82d63dbf8423f9f5f0fdf50eea3d0.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/829f67b1a25747deb42f19d353c5843b.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/d621c77f6c2a4f4fbb16e4ebcedf9cc8.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334109/20241017/1704810d4b354992a5ec34f4e687ceda.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
// 在此参考: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;,修改后的源代码为:
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
Function.prototype.Call = function(that)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
![](https://ucc.alicdn.com/as2av5j4oozzu/developer-article334100/20241017/3c66f1adff364bbb86945be5cbbbd21c.gif)
这样一来,我们就可以通过重载调用任意级别基类的方法了。
本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。