2014-03-12 73 views
0

我有兩個文件:BaseController.js和EventRecordController.js。 EventRecord需要從BaseController繼承幾個方法。Javascript中的原型繼承問題(Node.js)

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()方法內。

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

如果構造函數'return'是一個對象,'new'創建的對象將被丟棄。因此,新的EventRecordController()會返回函數EventRecord而不是實例。 –

+0

您是否想爲'EventRecordController'使用揭示模塊模式?那麼你錯過了IEFE電話 – Bergi

+0

爲什麼'運行'不是'EventRecord'原型的函數,而是一個「靜態」的函數? – Bergi

回答

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 

你可以修改EventRecordControllerreturnEventRecord一個實例:

// ... 

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); 
}; 
+0

這解決了我的問題,並讓我更好地理解如何使用原型繼承。謝謝! –