我知道这个问题可能在其他的问答中被触及过(比如JavaScript .prototype是如何工作的?问题),但是(我希望!)这是一个更具体的问题,为什么有些使用.prototype的“重写”在某些场景中有效,而有些则不工作。为了帮助说明(从ejohn.org的一个例子):
function Ninja() {
this.swingSword = function() { return true; };
};
Ninja.prototype.swingSword = function() { return false; };
var my_ninja = new Ninja();
alert(my_ninja.swingSword());上面的示例将提醒"true",根据ejohn.org网站的示例和解释,这是有意义的,但随后这也起了作用,完全违背了基于上述代码我认为不可能的内容:
var _send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(){
alert("Overridden!");
_send.apply(this, arguments);
};这两件事怎么可能都成立?一个是准确地没有被覆盖,另一个是?据我所知,它们都是对象,而swingSword和send函数都是函数吗?那么,我们如何才能覆盖XMLHttpRequest的send函数,而不是Ninja的swingSword函数呢?
感谢您的任何洞察力和帮助!
发布于 2016-02-02 11:38:22
在JavaScript中没有真正的覆盖概念。当您使用new实例化时,原型对象只是在新对象中引用(作为__proto__),而对对象中不存在的属性的任何访问都将被路由到prototype对象。尽管如此,“构造函数”函数还是会被调用,因此在调用者使用新对象之前,您有机会修改它。
如您所知,在构造函数中,新对象被引用为this。在您的示例中,您将实际上将swingSword函数添加到以前不存在的新对象中。如果没有,那么对swingSword属性(函数)的所有访问都会回到原型。换句话说,您“覆盖”了原型函数,而不是反过来!
确保你明白执行的顺序。仅仅因为在定义构造函数之后在原型上设置了函数,并不意味着它优先。实际上,构造函数是在使用new时执行的。
现在应该清楚第二个场景为什么工作了;XHR的构造函数没有创建send函数,因此将始终使用prototype对象上的函数。因为您在原始原型上替换了它,实际上您已经“重写”了它。顺便说一句,这就是为什么原始文件保存在_send变量中的原因;否则您将无法引用它或恢复它!
https://stackoverflow.com/questions/35152212
复制相似问题