为什么一些原型函数覆盖工作而另一些则没有?

时间:2016-02-02 11:29:11

标签: javascript

我理解这个问题可能已在其他Q& A(例如How does JavaScript .prototype work?问题)中被触及,但(我希望!)这是一个更具体的问题围绕为什么有些& #34;覆盖"在某些情况下使用.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);
};

两者如何才能成立?一个是准确没有被覆盖,另一个是?据我所知,它们都是对象,swingSwordsend函数都是函数?那么我们如何覆盖XMLHttpRequest send函数,而不是Ninja swingSword函数呢?

提前感谢您的任何见解和帮助!

1 个答案:

答案 0 :(得分:1)

JavaScript中没有真正的覆盖概念。使用new进行实例化时,只需在新对象中引用原型对象(如__proto__),对对象中不存在的属性的任何访问都将路由到原型对象。仍然是"构造函数"函数被调用,因此您可以在调用者使用之前修改新对象。

在构造函数中,新对象被引用为this,如您所知。在您的情况下,您实际上会将swingSword函数添加到之前不存在的新对象中。如果你没有,那么对swingSword属性(函数)的所有访问都将回退到原型。换句话说,你"覆盖"原型功能,而不是相反!

确保您了解执行顺序。仅仅因为在定义构造函数之后在原型上设置函数并不意味着它优先。实际上,使用new时会执行构造函数。

现在应该清楚为什么第二种情况有效; XHR的构造函数不会创建发送函数,因此将始终使用原型对象上的函数。由于您在原始原型上更换它,您基本上已经覆盖了#34;它。顺便说一句,这就是原件保存在_send变量中的原因;你不会引用它或以其他方式恢复它!