Javascript redefine and override existing function

2020-02-17 05:35发布

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"

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.

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.

8条回答
姐就是有狂的资本
2楼-- · 2020-02-17 06:11

When you access a property, system first looks for it in the instance. If it is not found, it looks for it in the prototype. This is why this.hello is being used, rather than O.prototype.hello.

If you wish to override the implementation of hello, you will need to use JavaScript inheritance. Here is a basic example:

var A = function(){
    console.log("A is getting constructed");
};

A.prototype.constructor = A;
A.prototype.someValue = 1;
A.prototype.hello = function() {
    console.log("A.hello(): " + this.someValue);
};

var B = function(){
    //Constructor of A is automatically called before B's

    console.log("B is getting constructed");
};
B.prototype = new A; //Inherit from A
B.prototype.constructor = B;
B.prototype.hello = function() {
    console.log("B.hello() called");
    console.log("Calling base class method");
    A.prototype.hello.call(this);
};

var a = new A();
a.hello();

var b = new B();
b.hello();
查看更多
▲ chillily
3楼-- · 2020-02-17 06:18

This is because when you access a property of an Object, JavaScript check the properties of the objects first, before going into its prototype.

This is analogous to Java's derived class overriding the base class functionality.

For a better understanding check the code example in Inheriting properties

Also note that someValue in your case is local to the constructor function. If you need it in other functions, you should assign it to this.someValue inside the constructor.

You'll be able to override the hello function for a particular Object here like the following. But not for the entire Class.

i.hello = function(){ console.log('even here someValue is not accessible');};

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

 var i = new O("chris");
 console.log(i.hello()); // prints hello, chris
 i.hello = function() { 
   return 'Hi there '+ this.someValue;
 }
 console.log(i.hello()); // prints Hi there chris

 var test = new O('Sujay')
 console.log(test.hello()) // this still prints hello, Sujay

Note that here we have not changed the constructor, and hence this will not work with other instances like test in the above example.

The best way to do it would be to define functions only in the prototype & not in the constructor, like the following snippet.

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

 var i = new O("chris");
 console.log(i.hello()); // prints hello, chris
 O.prototype.hello = function() { 
   return 'Hi there '+ this.someValue;
 }
 console.log(i.hello()); // prints Hi there chris

 var test = new O('Sujay')
 console.log(test.hello()) // prints Hi there Sujay
查看更多
登录 后发表回答