从module.exports中的另一个函数调用module.exports中的“本地”函数?


326

如何在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


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

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

Answers:


350

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


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

4
我认为这比公认的答案更好。如果出口范围之外定义函数,它增加了额外的间接水平,同时可以期望有时,这使得它更复杂,重构,如重命名功能,该功能的发现功能,等等
皮埃尔·亨利(Pierre Henry)

1
问题的直接答案
Kermit_ice_tea

8
module.exports.foo()并且exports.foo()不适用于Node.js v5.8.0。
–weenbrain

14
exports.foo()不起作用,但module.exports.foo()与NodeJS v6.9.1
R. Canser Yanbakan

191

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

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

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

然后:

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

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

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

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

非常好的实现!+1
realnsleo

2
或者,更简洁地使用ES6,module.exports = { foo, bar, }
让我审视一下

118

您也可以这样做以使其更加简洁和可读。这是我在几个写得很好的开源模块中看到的:

var self = module.exports = {

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

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

}

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

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

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

66

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

var _this = this;

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

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

这是更清洁的解决方案!
IvanZh 2014年

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

this直接使用,无需声明_this
Darius

1
一旦this不再正确,该建议将是有用的this。(承诺和回拨)
Andrew McOlash '19

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

40

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

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

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

module.exports = Service

3
这特别有用,因为您的代码正在调用Service.foo(),并且客户代码也将以Service.foo()相同的名称进行调用。
文斯·鲍德伦

这是一个完美的答案!
Jayant Varshney

16

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

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

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

遵循Class方法:

class MyClass {

    foo() {
        return 'foo';
    }

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

module.exports = new MyClass();

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


以及如何用这种方法调用静态方法?
Plixxer

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

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

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

6

为了解决您的问题,我对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};

并且在app.js中没有修改

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

1
在功能栏中,this.foo()不起作用...它必须是foo()
Falcoa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.