I build some base PopupBuilder class and want to implement it in some different usecases. For each case I create a class extends the base class.
So:
function PopupBuilder () {
var _this = this;
this.buildPopup = function () {
var popup = $('<div>', {
id: "popup",
class: "full-page",
click: clickHandler});
} //works fine
function acceptChanges () {}
function clickHandler (event) { // works fine
console.log(_this); // _this doesn't overrides by child class _this. Should it?
acceptChanges(event); // doesn't overrides by child class function as well
}
}
function ToServerSender (text) {
var _this = this;
function acceptChanges (event) {
// send data to server
}
}
ToServerSender.prototype = new PopupBuilder();
var updateFile = new ToServerSender();
updateFile.buildPopup();
I create an instance of child class, why I can't get to child class code and override/extend the base class? How should I rewrite the code it will works?
You need to attach the functions to the object.
Look at the above code to see how it works.
When in
PopupBuilder
console.log prints_this
it uses a reference tothis
in that scope (which contained the oldacceptChanges
. However inToServerSender
the scope has changed. This instance has other properties and is referred to by thethis
object in that scope. This example show the difference between using a reference to this and the object this.On a side note: when using more than 1 instance of an object use function references to avoid memory issues.
example
You need to bear in mind that the way OOP works in JavaScript is vastly different from class-style OOP.
So let's break it down a bit:
This assignment takes place when the
new PopupBuilder()
constructor is called toward the end of the code you posted there. Thethis
here refers to an object of typePopupBuilder
, and through inheritance is essentially "shared" among all instances ofToServerSender
. EachToServerSender
does not get its own copy of this_this
.This is just a function that exists inside your
PopupBuilder
constructor. It's not a method. It can't be overridden by defining a new one in theToServerSender
constructor:As explained above, the
_this
here is referring to the one instance of_this
that was created the one time you called thePopupBuilder
constructor and it is shared among all instances ofToServerSender
.This is simply a closure to the
acceptChanges
function inside thePopupBuilder
constructor. It can't be overridden.So what can you do?
1. Use overridable methods.
One thing you need to do is assign methods to
this
so that child objects can override them:Here, we have the constructor assigning functions to properties of
this
so that they can be inherited via the prototype chain and overridden as needed:2. Create the child type's prototype using
Object.create()
, not a constructor.Using a constructor to create a prototype on a child type is a bit outdated. The new way to do this is to use
Object.create
, to create a copy of the parent object's prototype:But this leaves the
ToServerSender
prototype without all the stuff that was initialized in thePopupBuilder
constructor. This is actually a good thing, because thePopupBuilder
constructor was creating one copy of its private variables that were going to be shared between all of theToServerSenders
in existence, potentially wreaking havok.The solution to this is to...
3. Call the parent constructor from the child constructor:
What happens here is that
ToServerSender
calls thePopupBuilder
constructor on itself, so that when_this
is created inside that constructor, it is referring to theToServerSender
, and not some sharedPopupBuilder
. This allows you to use it in closures and clear up some of the problems you were experiencing.So those are the main things to keep in mind. I know this is a ton of stuff, but the more you use it, the easier it will become.