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

Posted

技术标签:

【中文标题】使用导出函数时无法读取未定义的属性【英文标题】:Cannot read property of undefined when using exported function 【发布时间】:2018-01-14 09:01:39 【问题描述】:

我有以下 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;

exch.js

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 [as handle_request] (/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 [as handle_request] (/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_params (/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)

为什么会出现这个错误,我该如何解决?

【问题讨论】:

【参考方案1】:

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

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 用于构造函数的前一种方法总是

【讨论】:

【参考方案2】:

require("../exchanges/exch")()调用函数而不是创建一个新实例,使用new进行实例化以便使用prototype。你得到undefined 的原因是Exchange 什么都不返回。你以为它是constructor,但你称它为function

改用代码:

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

【讨论】:

【参考方案3】:

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

exports.exchange = Exchange;

现在在 router.js 中修改

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

var exchObject= new exch();

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

【讨论】:

感谢您强调它,我不知道它。

以上是关于使用导出函数时无法读取未定义的属性的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:无法读取未定义的属性“标题”

卡在“无法读取未定义的属性映射”

ReferenceError:导出函数时未定义req

无法从 nodejs 模块导出数据库属性

导出时返回未定义的函数

未捕获的类型错误:在开关函数开始时无法读取未定义的属性“类型”