简体   繁体   English

OO JavaScript调用父方法

[英]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 . 正如其他人提到的那样getNameundefined因为你覆盖了FaqPageprototype 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM