如何在module.exports声明中的另一个函数中调用函数?

app.js

var bla = require('./bla.js');
console.log(bla.bar());


bla.js

module.exports = {

  foo: function (req, res, next) {
    return ('foo');
  },

  bar: function(req, res, next) {
    this.foo();
  }

}


我正在尝试从函数foo中访问函数bar,并且得到:


TypeError:对象#没有方法'foo'


如果将this.foo()更改为foo(),我得到:


ReferenceError:未定义foo


评论

我测试了您的代码,没有错误。 bar函数返回undefined,因为没有return语句。您确定测试正确吗?

在节点版本v8.12.0中进行了测试,并且不再引发错误。 bar没有返回语句,因此运行console.log(bla.bar())只会返回undefined

@Ferchi谢谢,我错过了同样简单的事情。

#1 楼

this.foo()更改为module.exports.foo()

评论


@NamNguyen调用exports.foo()似乎有点尴尬且难以阅读。

–阿夫申·梅赫拉巴尼(Afshin Mehrabani)
2014年7月19日在12:20

我认为这比公认的答案更好。如果您在导出范围之外定义函数,则会增加一个间接级别,尽管有时可能需要这样做,但重构起来会更加复杂,例如重命名功能,查找功能用法等。

–皮埃尔·亨利(Pierre Henry)
2015年9月21日14:48在

问题的直接答案

–Kermit_ice_tea
16-3-3在23:24



对于Node.js v5.8.0,module.exports.foo()和export.foo()不适用于我。

–脑间
16年7月15日在15:35

exports.foo()不起作用,但是module.exports.foo()与NodeJS v6.9.1一起工作

– R. Canser Yanbakan
16-11-22在14:04

#2 楼

您可以在module.exports块外部声明函数。

var foo = function (req, res, next) {
  return ('foo');
}

var bar = function (req, res, next) {
  return foo();
}


然后:

module.exports = {
  foo: foo,
  bar: bar
}


评论


如果我想从方法访问对象的属性怎么办?

– Rockstar5645
16年7月11日在15:12

我收到TypeError:当我这样做时,yourClass.youMethod不是函数。我正在使用6.9.1版的节点。您需要退货声明吗?我没有return语句,因为我的所有代码在这些函数中都是异步的。

–布雷特·马特(Brett Mathe)
16年12月12日在22:12

不同样式的不错比较-gist.github.com/kimmobrunfeldt/10848413

– Tadas V.
17-09-10 17:59



非常好的实现! +1

– realnsleo
18-09-14在6:34

或者,更简洁地使用ES6,module.exports = {foo,bar,}

–让我考虑一下
19/12/15在9:21

#3 楼

您也可以这样做以使其更简洁易读。这是我在几个编写良好的开源模块中所看到的:

var self = module.exports = {

  foo: function (req, res, next) {
    return ('foo');
  },

  bar: function(req, res, next) {
    self.foo();
  }

}


评论


这个Node.js版本特定吗?我正在尝试使用v5.8.0,它正在记录未定义。

–脑间
16年7月15日在15:38

@doublejosh难道...您读过这个问题吗?它询问您如何调用另一个导出的函数。它与访问限制无关。

–莫妮卡基金的诉讼
18年5月16日在19:14

是的,我阅读了,请重新阅读。此答案使foo()与模块一起导出,这与仅在模块内调用的“本地”函数的观点背道而驰。

– doublejosh
18年5月18日在19:34



#4 楼

您还可以在(module。)exports.somemodule定义之外保存对模块全局范围的引用:

var _this = this;

exports.somefunction = function() {
   console.log('hello');
}

exports.someotherfunction = function() {
   _this.somefunction();
}


评论


这是更清洁的解决方案!

– IvanZh
2014年12月18日上午8:13

不需要_this,您可以在需要的地方使用它

–结城
18年7月4日在13:30

直接使用此,无需声明_this

– Darius
18-10-12在10:34

一旦不再是正确的建议,该建议将很有用。 (承诺和回调)

–安德鲁·麦克奥拉什(Andrew McOlash)
19年3月14日在21:21

我最喜欢此解决方案,因为它还提供了NodeJS模块范围界定的示例。

–miguelmorin
20-4-3在18:21

#5 楼

另一个更接近OP原始样式的选择是将要导出的对象放入变量中,并引用该变量以调用该对象中的其他方法。然后可以导出该变量,您就可以开始使用了。

var self = {
  foo: function (req, res, next) {
    return ('foo');
  },
  bar: function (req, res, next) {
    return self.foo();
  }
};
module.exports = self;


#6 楼

const Service = {
  foo: (a, b) => a + b,
  bar: (a, b) => Service.foo(a, b) * b
}

module.exports = Service


评论


这特别有用,因为您的代码在那里调用Service.foo(),而您的客户端代码也将以相同的名称调用Service.foo()。

–文斯·鲍德伦(Vince Bowdren)
18年1月31日,11:57

这是一个完美的答案!

–贾安·瓦什尼(Jayant Varshney)
18年8月30日在23:18

#7 楼

从Node.js版本13开始,您可以利用ES6模块。

export function foo() {
    return 'foo';
}

export function bar() {
    return foo();
}



遵循类的方法:

class MyClass {

    foo() {
        return 'foo';
    }

    bar() {
        return this.foo();
    }
}

module.exports = new MyClass();


由于Node的模块缓存,该类仅实例化一次:https://nodejs.org/api/modules.html#modules_caching

评论


如何用这种方法调用静态方法?

– Plixxer
18年6月7日在20:55

@CodeofGod就像调用其他任何静态方法一样调用它。在这种情况下,如果foo是静态的,则可以从内部栏中调用它,例如:MyClass.foo()。

–m.spyratos
18年6月7日在21:08

是的,我知道了,但是如何从导入它的控制器中调用它呢?const oAccounts = require(“ ...”);

– Plixxer
18年6月7日在21:11

您可以导出实际的类,而不是该类的实例。这样,您可以使用其静态方法。但是,如果您随后需要使用其实例方法,则必须在控制器中实例化该类。

–m.spyratos
18年6月8日在0:44



#8 楼

为了解决您的问题,我对bla.js进行了几处更改,并且可以正常运行。 >
var foo= function (req, res, next) {
  console.log('inside foo');
  return ("foo");
}

var  bar= function(req, res, next) {
  this.foo();
}
module.exports = {bar,foo};


评论


在功能栏中,this.foo()不起作用...它必须是foo()

–山猫
19年5月17日下午5:26