[英]OO JavaScript call parent method
I've been trying to get to grips with OO JavaScript and created a simple example. 我一直试图掌握OO JavaScript并创建了一个简单的例子。
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' 未捕获的TypeError:对象#<Object>
没有方法'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? 我想知道的是如何在超类中调用方法getName()
而不必覆盖并在子类中调用它?
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. 发生该错误是因为即使您将FaqPage
的原型设置为BasePage
的实例,您的下一行也会立即覆盖它。 So FaqPage
is not inheriting from BasePage
. 所以FaqPage
不是从BasePage
继承的。 Add properties/methods to FaqPage
's prototype instead of defining it a second time: 将属性/方法添加到FaqPage
的原型中,而不是第二次定义它:
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;
};
If inheritance is what you are after, it's not very straightforward to accomplish in JavaScript as far as I know. 如果继承是你所追求的,据我所知,在JavaScript中完成它并不是非常简单。 I've used this snippet by John Resig and it works like a charm. 我使用过John Resig的这个片段,它就像一个魅力。 http://ejohn.org/blog/simple-javascript-inheritance/ http://ejohn.org/blog/simple-javascript-inheritance/
In your case this is how it would work, 在你的情况下,它是如何工作的,
BasePage BasePage的
var BasePage = Class.extend({
init: function(name){
this.name = name;
},
getName: function(){
return this.name;
}
});
FaqPage class inheriting BasePage FaqPage类继承BasePage
var FaqPage = BasePage.extend({
init: function(name, faq){
this._super( name );
this.faq = faq;
},
getFaq: function() {
return this.faq;
}
});
And then 然后
var faqPage = new FaqPage('Faq Page', 'Faq');
var text = faqPage.getName() + ' ' + faqPage.getFaq();
$('body').text(text);
Of course, for this to work you'll have to include the implementation code on the page I linked. 当然,要实现这一点,您必须在我链接的页面上包含实现代码。
Here's the fiddle, http://jsfiddle.net/c8yjY/ 这是小提琴, http://jsfiddle.net/c8yjY/
I feel your pain. 我感觉到你的痛苦。 As others have mentioned getName
is undefined
because you override the prototype
of FaqPage
. 正如其他人提到的那样getName
是undefined
因为你覆盖了FaqPage
的prototype
。 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. 话虽如此,我确实同意将prototype
方法封装在一个范围内是好的。 Perhaps you should use a JavaScript library for this purpose. 也许你应该为此目的使用JavaScript库。 The smallest one out there is augment . 最小的那个是增强 。 In fact it's only 17 lines long: 实际上它只有17行:
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
: 如果您使用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. 希望有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.