ES6导出默认值,其中包含多个相互引用的函数

在 es6中,您可以像这样定义一个函数模块

export default {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { foo(); bar() }
}

上面的代码看起来是有效的,但是如果我调用 baz(),它会抛出一个错误:

ReferenceError: foo is not defined

如何从另一个函数调用 foo? 在本例中为 baz

剪辑

下面的代码实际上不能工作。我已经简化了代码,所以它只是需要的核心

const tokenManager =  {
revokeToken(headers) {
...
},
expireToken(headers) {
...
},
verifyToken(req, res, next) {
jwt.verify(... => {
if (err) {
expireToken(req.headers)
}
})
}
}


export default tokenManager

错误是

expireToken(req.headers);
^
ReferenceError: expireToken is not defined

编辑2

我只是试着在 expireToken之前加入 tokenManager,它终于起作用了

153981 次浏览

医生: baz() { this.foo(); this.bar() }

在 ES2015中,这种结构是:

var obj = {
foo() { console.log('foo') }
}

is equal to this ES5 code:

var obj = {
foo : function foo() { console.log('foo') }
}

exports.default = {} is like creating an object, your default export translates to ES5 code like this:

exports['default'] = {
foo: function foo() {
console.log('foo');
},
bar: function bar() {
console.log('bar');
},
baz: function baz() {
foo();bar();
}
};

现在很明显(我希望) ,baz尝试调用在外部作用域某处定义的 foobar,它们是未定义的。但是 this.foothis.bar将解析为在 exports['default']对象中定义的键。因此,引用自己方法的默认导出应该如下所示:

export default {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { this.foo(); this.bar() }
}

参见 翻译代码

export default {...}结构只是这样的东西的一个捷径:

const funcs = {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { foo(); bar() }
}


export default funcs

现在必须明白,在模块的作用域中没有 foobarbaz函数。但是有一个名为 funcs的对象(尽管实际上它没有名称) ,它包含这些函数作为其属性,并且这些函数将成为模块的默认导出。

因此,要修复代码,不使用快捷方式重写代码,并将 foobar作为 funcs的属性:

const funcs = {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { funcs.foo(); funcs.bar() } // here is the fix
}


export default funcs

另一种选择是使用 this关键字引用 funcs对象,而不必显式地声明它,即 正如@pawel 所指出的

还有一种选择(我通常更喜欢这种选择)是在模块作用域中声明这些函数。这样就可以直接提到它们:

function foo() { console.log('foo') }
function bar() { console.log('bar') }
function baz() { foo(); bar() }


export default {foo, bar, baz}

如果你想方便的默认导出 还有能力导入项目单独,你也可以导出所有的功能单独:

// util.js


export function foo() { console.log('foo') }
export function bar() { console.log('bar') }
export function baz() { foo(); bar() }


export default {foo, bar, baz}


// a.js, using default export


import util from './util'
util.foo()


// b.js, using named exports


import {bar} from './util'
bar()

或者,正如@loganfsmyth 建议的那样,您可以不使用默认导出,只使用 import * as util from './util'获取一个对象中的所有命名导出。

一种替代方法是更改模块。一般来说,如果你导出的对象上有一堆函数,导出一堆命名的函数会更容易,例如。

export function foo() { console.log('foo') },
export function bar() { console.log('bar') },
export function baz() { foo(); bar() }

在这种情况下,可以导出所有带名称的函数,因此可以这样做

import * as fns from './foo';

为每个函数获取一个具有属性的对象,而不是您在第一个示例中使用的导入:

import fns from './foo';