这一切都与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
属性的所有地方。因为您的构造函数run
在实例 ( this.run = function(){};
) 上定义了一个属性,所以查找永远不会超过第一步:“JS 检查实例的属性run
”。
原型链永远不会发挥作用。
你问是否以及如何重载JS 方法。简短的回答是:不是,不是真的。重载是一种有效的 OOP 技术,在传统的基于类的 OO 模型中非常方便。JS 不是这样玩的,而是使用原型模型。尝试强制原型系统像传统的 OO 语言一样工作是可能的(由于原型系统的灵活性),但它需要付出太多努力才能跟上,而且通常不值得。
您可以将其与使用普通轿车/轿车耕种田地进行比较。起初,您也许可以,但用不了多久您就会陷入困境,并且不得不使用拖拉机将您拖出田野。
如果您仍然想尝试一下,方法如下:
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
您可能会发现看这里很有用,这是我在前面的答案中更详细地解释了 JS 解析表达式的方式。在我的答案的底部,我还添加了一些关于此事的更多链接,可能也值得一看......