Javascript ES6 导出默认,多个函数相互引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33178843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:44:48  来源:igfitidea点击:

ES6 export default with multiple functions referring to each other

javascriptecmascript-6

提问by chrs

in es6 there you can define a module of functions like this

在 es6 中,您可以定义这样的功能模块

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

the above seems to be valid code, but if I call baz()it throws an error:

以上似乎是有效的代码,但如果我调用baz()它会引发错误:

ReferenceError: foo is not defined

ReferenceError: foo is not defined

How do you call foofrom another function? in this case baz

你如何foo从另一个函数调用?在这种情况下baz

Edit

编辑

Here's the code that actually doesn't work. I have simplified the code so it's only the core as needed

这是实际上不起作用的代码。我已经简化了代码,所以它只是需要的核心

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

export default tokenManager 

and the error is

错误是

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

Edit 2

编辑 2

I just tried adding tokenManagerbefore expireTokenand it finally works

tokenManager之前只是尝试添加expireToken,它终于起作用了

回答by skozin

The export default {...}construction is just a shortcut for something like this:

export default {...}建筑是只是像这样的快捷方式:

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

export default funcs

It must become obvious now that there are no foo, baror bazfunctions in the module's scope. But there is an object named funcs(though in reality it has no name) that contains these functions as its properties and which will become the module's default export.

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

So, to fix your code, re-write it without using the shortcut and refer to fooand baras properties of 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

Another option is to use thiskeyword to refer to funcsobject without having to declare it explicitly, as @pawel has pointed out.

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

Yet another option (and the one which I generally prefer) is to declare these functions in the module scope. This allows to refer to them directly:

另一种选择(也是我通常更喜欢的选择)是在模块范围内声明这些函数。这允许直接引用它们:

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

export default {foo, bar, baz}

And if you want the convenience of default export andability to import items individually, you can also export all functions individually:

如果您想要默认导出的便利性单独导入项目的能力,您还可以单独导出所有功能:

// 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()

Or, as @loganfsmyth suggested, you can do without default export and just use import?*?as?util?from?'./util'to get all named exports in one object.

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

回答by loganfsmyth

One alternative is to change up your module. Generally if you are exporting an object with a bunch of functions on it, it's easier to export a bunch of named functions, e.g.

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

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

In this case you are export all of the functions with names, so you could do

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

import * as fns from './foo';

to get an object with properties for each function instead of the import you'd use for your first example:

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

import fns from './foo';

回答by pawel

tl;dr: baz() { this.foo(); this.bar() }

tl;博士: baz() { this.foo(); this.bar() }

In ES2015 this construct:

在 ES2015 中,这个构造:

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

is equal to this ES5 code:

等于这个 ES5 代码:

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 = {}就像创建一个对象一样,您的默认导出转换为 ES5 代码,如下所示:

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

now it's kind of obvious (I hope) that baztries to call fooand bardefined somewhere in the outer scope, which are undefined. But this.fooand this.barwill resolve to the keys defined in exports['default']object. So the default export referencing its own methods shold look like this:

现在很明显(我希望)baz尝试在未定义的外部范围内的某处调用foobar定义。但是this.fooandthis.bar将解析为exports['default']object 中定义的键。因此,引用其自己的方法的默认导出看起来像这样:

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

See babel repl transpiled code.

请参阅babel repl 转译代码