OO JavaScript调用父方法

时间:2013-05-19 15:51:59

标签: javascript oop

我一直试图掌握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()而不必在子类中重写和调用它?

如果我认为这种做法不好/好的话也是如此。

4 个答案:

答案 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);

当然,要实现这一点,您必须在我链接的页面上包含实现代码。

这是小提琴,http://jsfiddle.net/c8yjY/

答案 3 :(得分:1)

我感觉到你的痛苦。正如其他人提到的那样getNameundefined,因为您覆盖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;
    };
});

希望有所帮助。