Node.js继承

时间:2015-05-07 20:51:09

标签: javascript node.js

我正在使用带有hapijs的节点进行REST API。所以,我必须使用继承,我没有成功访问父的功能。我有这个:

controller.js

var __ = require('underscore');

var Controller = function(){
    var Validator = require('../validators/'+this.controller);
    Controller.prototype.validate = new Validator();
}

Controller.prototype.returnErrors = function(err){
    var errors = [];
    __.each(err, function(error){
        errors.push(error.message);
    });
    return errors;
}

module.exports = Controller;

reckon.js

var __ = require('underscore'),
    reckon = require('../components/reckon'),
    inherits = require('util').inherits,
    Controller = require('./controller'),
    Reckon = require('../models/reckon').Reckon;

var ReckonCtr = function() {
    this.controller = "reckon";
    ReckonCtr.super_.call(this);
}

inherits(ReckonCtr, Controller);

ReckonCtr.prototype.get = function (request, reply, server, callback) {
   this.validate.get(__.extend({company:request.params.company}, request.query), function(validation, value){
       if(validation.error){
          return callback(this.returnErrors(validation.error.details));
       }
       reckon.getReckon(request.params.company, request.query, function(error, success){
           if(error) return callback(error);

           return callback(null, success);
       });
   });
}
module.exports = new ReckonCtr();

为什么我可以访问“this.validate”而不能“this.returnErrors”? (TypeError:未捕获错误:对象#没有方法'returnErrors')。

如何将我的returnErrors变为私有?

提前致谢

2 个答案:

答案 0 :(得分:3)

这是一个范围问题。

您可以访问this.validate,因为您处于ReckonCtr.prototype.get引用该实例的this方法的上下文中。但是,当您尝试访问this.returnErrors时,您处于this.validate.get回调的上下文中,其中this不再指向该实例。

解决此问题的最简单,最常见的方法是将this作为局部变量引用,并直接引用变量而不是this

ReckonCtr.prototype.get = function (request, reply, server, callback) {
    var self = this;
    self.validate.get(__.extend({company:request.params.company}, request.query), function(validation, value){
       if(validation.error){
           return callback(self.returnErrors(validation.error.details));
       }
       reckon.getReckon(request.params.company, request.query, function(error, success){
           if(error) return callback(error);

           return callback(null, success);
       });
   });
}

答案 1 :(得分:2)

this.validate正在this引用ReckonCtr对象的上下文中使用,因此它可以正常工作。在回调中,this未引用ReckonCtr

what exactly this refers to in a given context的混淆是JavaScript中的一个大问题。有几种解决方案。这个清单无疑是不完整的:

  • 在包含回调函数的函数中,使用this之类的内容保存对var self = this;的引用,然后在回调中使用self而不是this
  • 如果您使用的是最新版本的Node,则可以使用胖箭头语法使this更具可预测性。
  • 使用bind()call()apply()明确设置this的值。
  • 如果您想要的对象是单身,只需明确使用该对象而不是this