Reputation: 15133
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
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
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
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