Jas
Jas

Reputation: 15133

how to override called function in javascript

I tried this with no success:

<!DOCTYPE html>
<html>
<title>Web Page Design</title>
<head>
<script>
    function MyClass() {
        function someFunc() { calledFunc(); }
        function calledFunc() { document.writeln('orig called'); }
        return {
            someFunc: someFunc,
            calledFunc: calledFunc
        }
    }
    
    var obj = new MyClass();
    obj.someFunc();
    obj.calledFunc = function() { document.writeln("not orig called"); }
    obj.someFunc();
    
</script>
</head>
<body>
</body>
</html>

I see that only orig called is called and not the not orig called how can i override the calledFunc so that the not orig called would get called?

Upvotes: 0

Views: 66

Answers (3)

Pinke Helga
Pinke Helga

Reputation: 6702

You should not define methods directly in an instantiated object (by a constructor function), since on every new instance you get a new copy in the memory. Use JavaScript's prototype concept. You can override the prototype's methods in an object. It will be invoked by a call to obj.myFunction() or this.myFunction() from inside. If it not not found in the instance, it will be looked up in the prototype chain. You can build multiple prototypes in a chain and so you can build an inheritance model. When you use the Object.defineProperties method, you further can control whether a property (methods are executable properties as well) is writable or not and other settings.

What you are trying in your example and some other answers illustrate, is not overriding, but overwriting methods. When overwriting, the original method is lost.

MyClassPrototype = {};

Object.defineProperties(MyClassPrototype,
{
  'someFunc':
    {
      value: function()
             {
               this.calledFunc();
             }
    },

  'calledFunc':
    {
      value: function()
             {
               document.writeln('orig called<br>\n');
             },
      writable: true
    }

});


function MyClass()
{

}
MyClass.prototype = MyClassPrototype;


var obj = new MyClass();
obj.someFunc();

obj.calledFunc = function()
{
  document.writeln("not orig called AND...");
  // call original method with proper this-context (instantiated object)
  Object.getPrototypeOf(this).calledFunc.call(this);
}
obj.someFunc();
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Titel</title>
</head>
<body>
</body>
</html>

Upvotes: 1

user3297291
user3297291

Reputation: 23397

The obj.calledFunc isn't the one you're calling inside someFunc.

You're replacing what obj.calledFunc refers to, but in someFunc, you're calling the one defined in the closure of MyClass.

You'll have to do something like:

function MyClass() {
  var self = this;
  this.calledFunc = function() {
    document.writeln('orig called');
  };
  this.someFunc = function() {
    self.calledFunc(); // This refers to the same function you've exposed
  };
}

var obj = new MyClass();
obj.someFunc();
obj.calledFunc = function() {
  document.writeln("not orig called");
}
obj.someFunc();

Upvotes: 1

Christian Zosel
Christian Zosel

Reputation: 1424

You have to prepend this. to your call to the calledFunc method, because otherwise you're referencing the private function calledFunc():

<!DOCTYPE html>
<html>
<title>Web Page Design</title>
<head>
<script>
    function MyClass() {
        function someFunc() { this.calledFunc(); }
        function calledFunc() { document.writeln('orig called'); }
        return {
            someFunc: someFunc,
            calledFunc: calledFunc
        }
    }
    
    var obj = new MyClass();
    obj.someFunc();
    obj.calledFunc = function() { document.writeln("not orig called"); }
    obj.someFunc();
    
</script>
</head>
<body>
</body>
</html>

Upvotes: 2

Related Questions