ES6模块:导入的常量首先未定义;他们以后可以使用 [英] ES6 modules: imported constants are undefined at first; they become available later
问题描述
export const JUST_FORM = 0;
export const AS_PAGE = 1;
console.log(AS_PAGE); // **
导出默认功能doSomething(mode = AS_PAGE){
console.log(mode);
console.log(JUST_FORM);
}
我按照您的预期使用此功能。
从'./doSomething'
console.log(AS_PAGE)中导入doSomething {AS_PAGE};
doSomething();
当我运行应用程序时,它打印三次 undefined
,只有一次 AS_PAGE
,这是 console.log
标有 **
。但是,这是最后打印的!它显示:
- 将
AS_PAGE
常量用作 c $ c $ function $,在定义函数时没有定义。 -
JUST_FORM $
doSomething
被调用时不定义c $ c>常量。 -
AS_PAGE
常量在被明确导入时没有定义。
显然,这里发生的是只有 / code> export被解析和评估,文件的其余部分将被忽略。我在我的应用程序的几个不同的地方导入这个文件(这个时候很大),在某些时候这些值实际上是可用的。从控制台输出判断,这是时间的问题,但是有可能是有其他原因。显然,我在所有地方都做了完全一样的导入。
无论如何,我写了我的整个应用程序,假设一旦我导入了一些东西,就立即可用,我可以在我的代码中使用它。我阅读(简要地)了解ES6模块应该如何工作,我没有发现任何证明这个假设是错误的。而且一直工作到现在为止。
另请注意,当我使用 webpack-dev-server
或将其编译为单个包。
这个行为是否正确?
正如在评论中所建议的,这里的答案是循环依赖性。
问题中提供的代码实际上没有循环依赖关系(因为它只是一个简化的代码段),但症状非常清楚。 p>
循环依赖的最简单的例子是文件A导入文件B和文件B导入A.不幸的是,有时候这个问题难以检测的是,圆可以是任意的大量的,跨越大量的文件。
ES6中支持循环依赖关系,当您足够小心时,可以使用它们。然而,我在这里的外卖是循环依赖通常是错误的设计决定的标志。这正是我的情况。
I use ES6 modules in my JavaScript application. The sources are compiled with webpack and babel. This is a shortened version of the file that causes me trouble:
export const JUST_FORM = 0;
export const AS_PAGE = 1;
console.log(AS_PAGE); // **
export default function doSomething(mode = AS_PAGE) {
console.log(mode);
console.log(JUST_FORM);
}
I use this functionality just as you would expect.
import doSomething, { AS_PAGE } from './doSomething'
console.log(AS_PAGE);
doSomething();
When I run the app, it prints three times undefined
and only once the expected value AS_PAGE
which is the console.log
marked with **
. However, this is printed last! It shows that:
- The
AS_PAGE
constant, when used as default parameter for thedoSomething
function`, is not defined at the moment of defining the function. - The
JUST_FORM
constant is not defined whendoSomething
is called. - The
AS_PAGE
constant is not defined when explicitly imported.
Apparently, what's happening here is that only the default
export gets parsed and evaluated and the rest of the file is ignored until later. I import this file on several different places in my app (which is quite large at this moment) and at some point those values become actually available. Judging from the console output, it's matter of time, but it is possible that it has a different reason. Obviously, I do the importing exactly the same way in all places.
Anyway, I've written my whole application with the assumption that once I import something, it is immediately available and I can use it in my code. I read (briefly) about how ES6 modules should work and I haven't found anything that would prove this assumption wrong. And it has been working until now.
Also note, that the behavior is the same when I run it with webpack-dev-server
or compile it to a single bundle.
Is this behavior really correct? What might be responsible for it?
As suggested in the comments, the answer here are circular dependencies.
There is actually no circular dependency present in the code provided in the question (because it's just a simplified snippet of code) but the symptoms are very clear.
The simplest example of a circular dependency is when file A imports file B and file B imports A. Unfortunately, what makes this issue hard to detect sometimes is that the circle can be arbitrarily large, spanning over a huge amount of files.
Circular dependencies are supported in ES6 and they can be used when one is careful enough. However, my takeaway here is that circular dependencies are very often a sign of bad design decisions. Which was exactly my case.
这篇关于ES6模块:导入的常量首先未定义;他们以后可以使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!