0

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?

3 Answers 3

2

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>

Sign up to request clarification or add additional context in comments.

Comments

1

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();

Comments

1

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.