Javascript重新定义并覆盖现有的函数体 [英] Javascript redefine and override existing function body

查看:140
本文介绍了Javascript重新定义并覆盖现有的函数体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道一旦它构建完成后我们还能改变它吗?

I am wondering can we still change the function body once it is constructed ?

     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 ,它将会出现类型错误。

The javascript statement O.prototype.hello = function(){....} doesn't override and redefine the hello function behavior. Why is that ? I know it will have a type error if you tried to reuse the parameter someValue.

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

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

I am wondering why It allows to add function during runtime like

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

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

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

but doesn't allow you to change the definition once it's defined. Did i do something wrong ? how do we override and redefine a function within a class ? and is there a way to reuse the parameter that we passed in earlier to create the object ? in this cases how do we re-use someValue if we want to extend more functions to it.

推荐答案

当你使用 new 时,构造函数中的 this 的值指向新的创建对象(有关 new 如何工作的更多信息,请查看这个答案这个答案)。所以你的新实例 i ,有一个 hello 函数。当您尝试访问对象的属性时,它会沿着原型链向上走,直到找到它为止。由于 hello 存在于对象的实例上,因此无需走原型链来访问 hello 返回 hhhhhhhh 。从某种意义上说,您已经覆盖了实例中的默认实现。

When you use new, the value of this inside the constructor points to the newly created object (for more information on how new works, take a look at this answer and this answer). So your new instance i, has a hello function. When you try to access the property of an object, it walks up the prototype chain until it finds it. Since hello exists on the instance of the object, there is no need to walk up the prototype chain to access the version of hello that returns hhhhhhhh. In a sense, you have overridden the default implementation in your instance.

如果不指定 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将开始走向原型链,看看它是否能找到与您正在寻找的匹配的属性。它找到它,它将使用它。否则,它将返回 undefined

What you're doing is kind of backwards. The prototype basically provides the "default" form of something, which you can override on a per-instance basis. The default form is used only if the property you're looking for cannot be found on the object. That is, JavaScript will start walking up the prototype chain to see if it can find a property that matches what you're looking for. It it finds it, it will use that. Otherwise, it will return undefined.

您在第一种情况下基本上具有以下内容:

What you basically have in the first case is as follows:

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

所以当您执行 i.hello 时,JavaScript会发现 i <上有 hello 属性/ code>并使用它。现在,如果您没有明确定义 hello 属性,则基本上具有以下内容:

So when you do i.hello, JavaScript sees that there is a hello property on i and uses that. Now if you didn't explicitly define a hello property, you basically have the following:

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 的版本是一种故障安全和后备。

What this means is that you can provide a default implementation in the prototype, and then override it (in a sense it's like sub-classing). What you can also do is modify the behavior on a per-instance basis by directly modifying the instance. The version of hello that you have on the prototype is kind of a fail-safe and a fall-back.

编辑:您的问题的答案:

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

Overriding on a per-instance basis means you attach a property or a function to a particular instance. For example, you could do:

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

这意味着此行为特定于特定实例(即,只有 i 而不是你可能创建的任何其他实例。

Which means that this behavior is specific to that particular instance (i.e., only to i and not to any other instances that you may have created).

如果你拿出这个,那你基本上有:

If you take out this, then you have basically have:

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

这相当于:

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

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

So in this case, hello is a global reference to that function. What this means is that hello isn't attached to any of your objects.

如果你的构造函数中没有 this.hello = function(){....}; ,那么你好可以是未定义的。我还谈到了JavaScript用来尝试解析对象属性的一般过程。正如我之前提到的,它涉及走原型链。

hello can be undefined if you don't have this.hello = function() { .... }; inside your constructor. I was also talking about the general process that JavaScript uses to try to resolve properties on objects. As I mentioned before, it involves walking up the prototype chain.

这篇关于Javascript重新定义并覆盖现有的函数体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆