Javascript重新定义并覆盖现有的功能体

我想知道一旦构建函数体,我们还能改变函数体吗?

     var O = function(someValue){
           this.hello = function(){
                return "hello, " + someValue;
           }
     }

     O.prototype.hello = function(){
           return "hhhhhhh";
     }

     var i = new O("chris");
     i.hello();   // -> this still returns the old definition "hello, chris"

JavaScript语句O.prototype.hello = function(){….}不会覆盖并重新定义hello函数行为。这是为什么 ?我知道如果您尝试重用参数someValue,它将会出现类型错误。

      // this will fail since it can't find the parameter 'someValue'
      O.prototype.hello = function(){
             return "aloha, " + someValue;
      } 

我想知道为什么它允许在运行时添加功能

      O.prototype.newFunction = function(){
           return "this is a new function";
      }

      i.newFunction();   //  print 'this is a new function' with no problem.

但不允许您在定义后更改定义。
我做错什么了吗 ?我们如何覆盖和重新定义一个类中的函数?并且有一种方法来重用先前传递的参数来创建对象?在这种情况下,如果我们想要扩展更多的功能,我们如何重新使用someValue。

当您使用new时,构造函数中的值指向新创建的对象(有关新功能的更多信息,请参阅this answerthis answer)。所以你的新实例我有一个hello功能。当您尝试访问对象的属性时,它会沿着原型链移动,直到它找到它。由于hello存在于该对象的实例上,因此不需要走出原型链来访问返回hhhhhhhhh的hello版本。在某种意义上,您已经覆盖了实例中的默认实现。

你可以看到这样的行为,如果你没有在你的构造函数中给你打个招呼:

var O = function(someValue) {

 }

 O.prototype.hello = function(){
       return "hhhhhhh";
 }

 var i = new O("chris");
 console.log(i.hello()); //this prints out hhhhhhh

你在做什么是倒退的。原型基本上提供了“默认”形式的东西,您可以在每个实例的基础上进行覆盖。只有在对象上找不到要查找的属性时,才使用默认表单。也就是说,JavaScript将开始走上原型链,看看它是否可以找到与您要查找的属性相匹配的属性。它找到它,它会使用它。否则,它将返回未定义。

在第一种情况下你基本上拥有的如下:

Object.prototype.hello (not defined; returns "undefined")
|
+----O.prototype.hello (returns "hhhhhhhh")
     |
     +----i.hello (returns "hello, chris")

所以当你做了i.hello,JavaScript看到我有一个hello属性,并使用它。现在,如果没有明确定义一个hello属性,你基本上有以下的一些:

Object.prototype.hello (not defined; returns "undefined")
|
+----O.prototype.hello (returns "hhhhhhhh")
     |
     +----i.hello (is "undefined", so JavaScript will walk up the chain until 
                   it sees O.prototype.hello, which does have a defined value 
                   it can use.)

这意味着您可以在原型中提供默认实现,然后重写它(在某种意义上,它类似于子类)。您还可以通过直接修改实例来修改每个实例的行为。你在原型上的hello版本是一种故障安全和倒退。

编辑:你的问题的答案:

在每个实例的基础上覆盖意味着你附加一个属性或函数到一个特定的实例。例如,你可以做:

i.goodbye = function() {
    return "Goodbye, cruel world!";
};

这意味着这种行为特定于该特定实例(即仅对我而不是您可能已创建的任何其他实例)。

如果你拿出来,那么你基本上有:

hello = function() {
    return "hello, " + someValue;
}

这相当于做:

window.hello = function() {
    return "hello, " + someValue;
}

所以在这种情况下,hello是对该函数的全局引用。这意味着你没有附加任何你的对象。

如果你没有this.hello = function(){….},你可以不定义。在你的构造函数里面我也在谈论JavaScript用来尝试解决对象上的属性的一般过程。正如我之前提到的,它涉及到原型链的走向。

http://stackoverflow.com/questions/12183011/javascript-redefine-and-override-existing-function-body

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:Javascript重新定义并覆盖现有的功能体