Javascript(Node.js)中的原型继承问题

时间:2014-03-12 12:43:58

标签: javascript node.js inheritance

我有两个文件:BaseController.js和EventRecordController.js。 EventRecord需要从BaseController继承一些方法。

BaseController

var Q = require('q'),
    util = require('../util');

exports.BaseController = function(req, res) {
    this.req = res;
    this.res = res;
    this.fields = {};
    this.error = {
        code: 200,
        message: 'BAD REQUEST: The parameters provided were invalid. See response body for error messages.',
        specific_message: ''
    };
};

// Utility method to handle returning errors that are thrown.
exports.BaseController.prototype.handle_errors = function(error) {
    if(this.error.code === 500) {
        util.internal_error(this.res, this.response_type);
    } else {
        var response = util.build_error_response(this.response_type, this.error.code, this.error.message, this.error.specific_message);
        util.send_response(this.res, this.response_type, this.error.code, response);
    }
};

// Check to see if a user is authenticated and whether they are using a correct response type.
exports.BaseController.prototype.validate_response_type_and_authenticate = function() {
    var deferred = Q.defer();
    util.validate_response_type_and_authenticate(this.req, this.res, function(auth_data, response_type) {

        this.auth_data = auth_data;
        this.company_user_uid = this.auth_data.data.company.uid;
        this.response_type = response_type;
        this.v3_token = this.auth_data.data.token;

        deferred.resolve();
    });
    return deferred.promise;
};

EventRecordController

var base_controller = require("./BaseController"),
    Q = require('q'),
    util = require('../util'),
    validator = require('validator');


exports.EventRecordController = function(req, res) {

    function EventRecord(req, res) {
        base_controller.BaseController.apply(this, arguments);
    }

    // Inherit from BaseController, then fix constructor.
    EventRecord.prototype = new base_controller.BaseController();
    EventRecord.prototype.constructor = EventRecord;

    EventRecord.run = function() {
        console.log(this.error);
    };

    return EventRecord;
};

当我运行以下代码时,this.error在run()方法中记录为undefined。

var event_record_controller = require("./controllers/EventRecordController"),
    util = require('./util'),
    validator = require('validator');

exports.record = function(req, res) {
    var controller = new event_record_controller.EventRecordController(req, res);
    controller.run();
};

我想我在这里遗漏了一些明显的东西,但我对基于原型的继承的经验是有限的。

1 个答案:

答案 0 :(得分:1)

this.errorundefined,因为run是直接在构造函数上调用的,构造函数没有error,而不是其中一个实例。

不会继承直接附加到构造函数的方法。为此,它们应附加到prototype

// "static" method available only through the constructor itself
EventRecord.run = function() {
    console.log(this.error);
};

// "class" method inherited by instances of `EventRecord`
EventRecord.prototype.run = function () {
    console.log(this.error);
};

但是,您还没有EventRecord的实例来呼叫.run()

当构造函数return是对象时,使用new创建的实例将被丢弃。因此,调用new EventRecordController()只是返回function EventRecord

var controller = new event_record_controller.EventRecordController(req, res);
console.log(typeof controller);     // function
console.log(controller.name);       // "EventRecord"

controller = new controller(req, res);
console.log(typeof controller);     // object

您可以将EventRecordController修改为return EventRecord的实例:

// ...

return new EventRecord(req, res);

尽管如此,您可能会考虑合并2个构造函数而不是生成另一个构造函数:

exports.EventRecordController = function(req, res) {
    base_controller.BaseController.apply(this, arguments);
};

util.inherits(exports.EventRecordController, base_controller.BaseController);

exports.EventRecordController.prototype.run = function () {
    console.log(this.error);
};