I've been trying to get to grips with OO JavaScript and created a simple example.
function BasePage(name) {
this.init(name);
}
BasePage.prototype = {
init: function(name) {
this.name = name;
},
getName: function() {
return this.name;
}
}
function FaqPage (name, faq) {
this.init(name, faq);
}
FaqPage.prototype = new BasePage();
FaqPage.prototype = {
init: function(name, faq) {
BasePage.prototype.init.call(this, name);
this.faq = faq;
},
getFaq: function() {
return this.faq;
}
}
var faqPage = new FaqPage('Faq Page', 'Faq');
var text = faqPage.getName() + ' ' + faqPage.getFaq();
$('body').text(text);
The result of running this results in the following message:
Uncaught TypeError: Object
#<Object>has no method 'getName'
What I would like to know is how can I call the method getName() in the super class without having to override and call it in the sub class?
Also if my if you think this approach is bad/good.
That error occurs because even though you've set FaqPage's prototype to be an instance of BasePage, your next line immediately overwrites that. So FaqPage is not inheriting from BasePage. Add properties/methods to FaqPage's prototype instead of defining it a second time:
FaqPage.prototype.init = function(name, faq) {
BasePage.prototype.init.call(this, name);
this.faq = faq;
}
FaqPage.prototype.getFaq = function() {
return this.faq;
}
The first line is right, you create a prototype from the base object.
FaqPage.prototype = new BasePage();
But then you override it, so is does not inherit the base object anymore
FaqPage.prototype = {
init: function(name, faq) {
BasePage.prototype.init.call(this, name);
this.faq = faq;
},
getFaq: function() {
return this.faq;
}
}
Instead of defining the entire prototype, override just individual functions:
FaqPage.prototype.init = function(name, faq) {
BasePage.prototype.init.call(this, name);
this.faq = faq;
};
FaqPage.prototype.getFaq = function() {
return this.faq;
};
I feel your pain. As others have mentioned getName is undefined because you override the prototype of FaqPage. Hence I'll not reiterate that explanation.
That being said I do agree that it's good to encapsulate prototype methods in a single scope. Perhaps you should use a JavaScript library for this purpose. The smallest one out there is augment. In fact it's only 17 lines long:
Function.prototype.augment = function (body) {
var base = this.prototype;
var prototype = Object.create(base);
body.apply(prototype, Array.from(arguments, 1).concat(base));
if (!Object.ownPropertyOf(prototype, "constructor")) return prototype;
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
};
(function funct() {
var bind = funct.bind;
var bindable = Function.bindable = bind.bind(bind);
var callable = Function.callable = bindable(funct.call);
Object.ownPropertyOf = callable(funct.hasOwnProperty);
Array.from = callable([].slice);
}());
Here's how your code would look if you used augment:
var BasePage = Object.augment(function () {
this.constructor = function (name) {
this.name = name;
};
this.getName = function () {
return this.name;
};
});
var FaqPage = BasePage.augment(function (base) {
this.constructor = function (name, faq) {
base.constructor.call(this, name);
this.faq = faq;
};
this.getFaq = function () {
return this.faq;
};
});
Then you may use it as you normally would:
var faqPage = new FaqPage("Faq Page", "Faq");
var text = faqPage.getName() + " " + faqPage.getFaq();
$("body").text(text);
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With