考虑示例 html 代码:
<head>
....
<script src="/js/MyClass.js"></script>
<script src="/js/extend.js"></script>
<script>
$(document).ready(function($) {
var $obj=new MyClass();
$obj.run();
});
</script>
</head>
<body>
MyClass.js 文件:
var MyClass=function()
{
this.run=function() {
alert("MyClass");
}
}
扩展.js文件:
MyClass.prototype.run=function() {
alert("Extend");
}
为什么此代码提示“MyClass”而不是“Extend”?如何正确重写(重载)类方法?
最佳答案
这都与 如何 JS 解析像 <object>.<property/function>
这样的表达式有关.我之前已经对此进行了详细解释,但这里是适用于您的案例的示意图:
[ MyClass.run ]<=========================================================\ \
MyClass[run] ===> JS checks instance for property run | |
/\ || | |
|| || --> property found @instance, resolve value------------------------------| |
|| || | |
|| ===========> MyClass.prototype.run could not be found? check prototype | |
|| || | |
|| ||--> OR property found @MyClass.prototype, return---------------------| |
|| || | |
|| ==========> Object.prototype.run: not found check prototype? | |
|| || | |
|| ||--> property found @Object.prototype, return---------------------|-|
|| || |=|
|| =======> chech prototype of Object.prototype -> undefined~~~~~~~~~~|X|
|| \ /
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< TypeError can't read property run of undefined
这是 JS 可以检查 run
的所有地方属性(property)。因为你的构造函数定义了一个 run
实例上的属性 ( this.run = function(){};
),查找永远不会超过第一步:“JS 检查实例中的属性 run
”。
原型(prototype)链从不发挥作用。
您问是否以及如何重载 JS 方法。简短的回答是:不是,不是真的。重载是一种有效的 OOP 技术,在传统的基于类的 OO 模型中非常方便。 JS 不是这么玩的,而是使用原型(prototype)模型。试图强制原型(prototype)系统像传统的 OO 语言一样工作是是可能的(由于原型(prototype)系统的灵 active ),但它需要太多的努力才能跟上,而且通常是不值得的它。
您可以将其比作使用普通轿车/轿车耕地。一开始,您可能能够,但很快就会卡住,不得不叫来拖拉机将您拖出田地。
如果您还想尝试一下,方法如下:
function MyClass()
{
this.run = function()
{
console.log('child method');
var backup = this.run;//store reference to instance property
delete this.run;//delete instance property
this.run();//call again
//but now, the instance property is missing, JS will use the prototype
this.run = backup;//restore instance property
};
}
MyClass.prototype.run = function()
{
console.log('prototype run method');
};
var foo = new MyClass;
foo.run();
//logs:
//child method
//prototype run method
您可能会发现它很有用 to take a look here ,这是我之前的回答,其中我更详细地解释了JS解析表达式的方式。在我的答案底部,我还添加了一些关于此事的链接,也可能值得一看......
关于javascript - JavaScript 中的方法重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19269596/