Javascript 使用导出函数时无法读取未定义的属性

Javascript 使用导出函数时无法读取未定义的属性,javascript,node.js,ecmascript-5,Javascript,Node.js,Ecmascript 5,我有以下Express应用程序: router.js var express = require('express'); var router = express.Router(); var exch = require("../exchanges/exch")(); router.get('/', function(req, res, next) { exch .getTicker((tick) => { res.send('get ticker exch:

我有以下Express应用程序:

router.js

var express = require('express');
var router = express.Router();
var exch = require("../exchanges/exch")();

router.get('/', function(req, res, next) {

    exch .getTicker((tick) => {
        res.send('get ticker exch: ' + JSON.stringify(tick));
    });

});

module.exports = router;
var Kraken = require('kraken-api');
var moment = require('moment');
var _ = require('lodash');

/**
...code
**/

var Exchange = function(config) {
  _.bindAll(this);

  if(_.isObject(config)) {
    this.key = config.key;
    this.secret = config.secret;
    this.currency = config.currency.toUpperCase()
    this.asset = config.asset.toUpperCase();
  }

  this.pair = addPrefix(this.asset) + addPrefix(this.currency);
  this.name = 'kraken';
  this.since = null;

  this.kraken = new Kraken(this.key, this.secret);
}

Exchange.prototype.getTicker = function(callback) {
  var set = function(err, data) {
    if(!err && _.isEmpty(data))
      err = 'no data';

    else if(!err && !_.isEmpty(data.error))
      err = data.error;

    if (err)
      return console.log('unable to get ticker' + JSON.stringify(err));

    var result = data.result[this.pair];
    var ticker = {
      ask: result.a[0],
      bid: result.b[0]
    };
    callback(err, ticker);
  };

  this.kraken.api('Ticker', {pair: this.pair}, _.bind(set, this));
};

}

module.exports = Exchange;
exch.js

var express = require('express');
var router = express.Router();
var exch = require("../exchanges/exch")();

router.get('/', function(req, res, next) {

    exch .getTicker((tick) => {
        res.send('get ticker exch: ' + JSON.stringify(tick));
    });

});

module.exports = router;
var Kraken = require('kraken-api');
var moment = require('moment');
var _ = require('lodash');

/**
...code
**/

var Exchange = function(config) {
  _.bindAll(this);

  if(_.isObject(config)) {
    this.key = config.key;
    this.secret = config.secret;
    this.currency = config.currency.toUpperCase()
    this.asset = config.asset.toUpperCase();
  }

  this.pair = addPrefix(this.asset) + addPrefix(this.currency);
  this.name = 'kraken';
  this.since = null;

  this.kraken = new Kraken(this.key, this.secret);
}

Exchange.prototype.getTicker = function(callback) {
  var set = function(err, data) {
    if(!err && _.isEmpty(data))
      err = 'no data';

    else if(!err && !_.isEmpty(data.error))
      err = data.error;

    if (err)
      return console.log('unable to get ticker' + JSON.stringify(err));

    var result = data.result[this.pair];
    var ticker = {
      ask: result.a[0],
      bid: result.b[0]
    };
    callback(err, ticker);
  };

  this.kraken.api('Ticker', {pair: this.pair}, _.bind(set, this));
};

}

module.exports = Exchange;
正如您所看到的,我通过
require(“…”)
包含对象。但是,我仍然得到以下错误:

无法读取未定义的属性“getTicker”

TypeError:无法读取未定义的属性“getTicker” 在/home/ubuntu/workspace/routes/ticker.js:20:9 在Layer.handle[作为handle_请求](/home/ubuntu/workspace/node_modules/express/lib/router/Layer.js:95:5) 下一步(/home/ubuntu/workspace/node_modules/express/lib/router/route.js:137:13) 在Route.dispatch(/home/ubuntu/workspace/node_modules/express/lib/router/Route.js:112:3) 在Layer.handle[作为handle_请求](/home/ubuntu/workspace/node_modules/express/lib/router/Layer.js:95:5) 在/home/ubuntu/workspace/node_modules/express/lib/router/index.js:281:22 在Function.process_参数(/home/ubuntu/workspace/node_modules/express/lib/router/index.js:335:12) 下一步(/home/ubuntu/workspace/node_modules/express/lib/router/index.js:275:10) 在Function.handle(/home/ubuntu/workspace/node_modules/express/lib/router/index.js:174:3) 在路由器上(/home/ubuntu/workspace/node_modules/express/lib/router/index.js:47:12)


为什么会发生此错误?我如何修复它?

您没有创建实例,因此无法访问原型上的方法。实际上,您只是调用了由
exch.js
导出的构造函数
Exchange
。由于直接调用构造函数时不返回任何内容(隐式
未定义
),因此会出现以下错误:

var exch = require("../exchanges/exch")(); //exch is undefined because Exchange as a function returns nothing
这不会设置原型,因为您没有构造对象,只是调用了函数。相反,使用
new
构建一个新的
Exchange
对象:

var Exchange = require("../exchanges/exch");
var exch = new Exchange();
这将创建一个新的
Exchange
对象,您可以在其中从原型调用
getTicker
。注意:确保将
config
传递给构造函数


如果没有
new
,您可以在
Exchange
中进行检查,查看是否在没有
new
的情况下意外调用了它,并返回一个新实例:

var Exchange = function(config) {
  if(!(this instanceof Exchange)) {
    return new Exchange(config);
  }
  //...
}
这样做的目的是返回
Exchange
的新实例,即使您直接调用了该函数。现在您可以使用:

var exch = require("../exchanges/exch")();
但是我总是更喜欢前一种方法,即总是为构造函数使用
new

require(“../exchanges/exch”)()
调用函数而不是创建新实例,使用
new
实例化以使用
原型。您得到
未定义
的原因是
交换
不返回任何内容。您假设它是一个
构造函数
,但您将其称为
函数

请改用代码:

var exchModule = require("../exchanges/exch")
var exch=new exchModule()

更改exch.js中代码的最后一行

exports.exchange = Exchange;
现在在router.js中进行修改

var exch = require("../exchanges/exch").exchange;

var exchObject= new exch();

现在您可以使用exchObject对象来调用方法

,感谢您突出显示它,我不知道它。