我一直试图掌握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);
运行此结果会产生以下消息:
未捕获的TypeError:对象
#<Object>
没有方法'getName'
我想知道的是如何在超类中调用方法getName()
而不必在子类中重写和调用它?
如果我认为这种做法不好/好的话也是如此。
答案 0 :(得分:6)
发生该错误是因为即使您将FaqPage
的原型设置为BasePage
的实例,您的下一行也会立即覆盖它。因此FaqPage
不会继承自BasePage
。向FaqPage
的原型添加属性/方法,而不是第二次定义它:
FaqPage.prototype.init = function(name, faq) {
BasePage.prototype.init.call(this, name);
this.faq = faq;
}
FaqPage.prototype.getFaq = function() {
return this.faq;
}
答案 1 :(得分:2)
第一行是正确的,您可以从基础对象创建原型。
FaqPage.prototype = new BasePage();
但是你重写它,所以不再继承基础对象
FaqPage.prototype = {
init: function(name, faq) {
BasePage.prototype.init.call(this, name);
this.faq = faq;
},
getFaq: function() {
return this.faq;
}
}
不是定义整个原型,而是仅覆盖单个函数:
FaqPage.prototype.init = function(name, faq) {
BasePage.prototype.init.call(this, name);
this.faq = faq;
};
FaqPage.prototype.getFaq = function() {
return this.faq;
};
答案 2 :(得分:1)
如果继承是你所追求的,据我所知,在JavaScript中完成并不是非常简单。我使用过John Resig的这个片段,它就像一个魅力。 http://ejohn.org/blog/simple-javascript-inheritance/
在你的情况下,这是它的工作方式,
的BasePage
var BasePage = Class.extend({
init: function(name){
this.name = name;
},
getName: function(){
return this.name;
}
});
继承BasePage的FaqPage类
var FaqPage = BasePage.extend({
init: function(name, faq){
this._super( 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);
当然,要实现这一点,您必须在我链接的页面上包含实现代码。
答案 3 :(得分:1)
我感觉到你的痛苦。正如其他人提到的那样getName
是undefined
,因为您覆盖prototype
的{{1}}。因此,我不会重申这一解释。
话虽如此,我确实同意将FaqPage
方法封装在一个范围内是件好事。也许你应该为此目的使用JavaScript库。最小的一个是augment。实际上它只有17行:
prototype
以下是使用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);
}());
时代码的外观:
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;
};
});
希望有所帮助。