如何使用ES2015语法从文件中导入所有导出的内容?是否有通配符?
如何使用ES2015语法从文件中导入所有导出的内容?是否有通配符?
在ES2015语法中,我们有新的import语法,我一直在尝试弄清楚如何将一个文件中导出的所有内容导入到另一个文件中,而不需要将其包装在一个对象中,即使它们在同一个文件中定义的一样可用。\n因此,本质上是这样的:\n
// constants.js const MYAPP_BAR = 'bar' const MYAPP_FOO = 'foo'
\n
// reducers.js import * from './constants' console.log(MYAPP_FOO)
\n这种写法是无效的,至少根据我的Babel/Webpack设置,这种语法是无效的。\n
替代方案
\n以下写法可以工作(但如果需要导入多个内容,会变得冗长和繁琐):\n
// reducers.js import { MYAPP_BAR, MYAPP_FOO } from './constants' console.log(MYAPP_FOO)
\n以下写法也可以工作(但它将常量包装在一个对象中):\n
// reducers.js import * as consts from './constants' console.log(consts.MYAPP_FOO)
\n是否有适用于第一种变体的语法,或者您必须通过名称逐个导入每个内容,或者使用包装对象?
ES2015语法中,我们可以使用import关键字来导入一个文件中导出的内容。但是,如果想要一次性导入文件中的所有内容,就需要使用通配符(wildcard)。然而,ES2015语法并不支持通配符导入。
上述问题中,问到了如何使用ES2015语法导入一个文件中的所有导出内容,是否有通配符可用。对于这个问题,作者提出了一个解决方案:首先,导入整个对象,然后迭代该对象的属性,并使用eval动态地生成常量。作者给出了一个示例代码,如下所示:
import constants from './constants.js' for (const c in constants) { eval(`const ${c} = ${constants[c]}`) }
然而,这个解决方案存在一个问题,就是在作者的IDE中无法使用智能提示(intellisense),因为这些常量是在执行期间动态生成的。但是,从一般情况来看,这个解决方案应该是可行的。
总结起来,问题是如何使用ES2015语法一次性导入一个文件中的所有内容,并且是否存在通配符来实现这一目标。作者给出的解决方案是先导入整个对象,然后使用eval动态生成常量。然而,这个解决方案在某些IDE中可能无法使用智能提示功能。
在ES2015语法中,不能使用通配符导入文件中的所有变量,因为如果在不同的文件中具有相同名称的变量,会导致变量冲突。如下所示的代码示例:
//a.js export const MY_VAR = 1; //b.js export const MY_VAR = 2; //index.js import * from './a.js'; import * from './b.js'; console.log(MY_VAR); // 这里应该有哪个值呢?
因为我们无法解析MY_VAR
的实际值,所以这种导入方式是不可能的。
对于这种情况,如果您有很多值需要导入,最好将它们全部导出为一个对象:
// reducers.js import * as constants from './constants' console.log(constants.MYAPP_FOO)
在Python中,通配符导入是可以工作的:引用a.js
被销毁,而b.js
被使用。那为什么在JavaScript中不能这样做呢?
我认为这也是危险的。假设您从几个第三方库中import *
。LibA有一个您需要的foo
,而LibB没有任何foo
。几个月或几年后,LibB添加了一个foo
组件,覆盖了LibA的foo
。突然间,您的代码就出错了。LibB甚至可能不认为添加foo
是一个主要的语义版本更改,因为它之前不存在。
因为很可能您无法控制a.js
或b.js
的实现,所以无法阻止名称冲突的发生。特别是在未来,正如上面所指出的。
无法理解这个问题。导入是一个定义。在JavaScript中,重新定义一个变量为另一个值是完全有效的。如果您导入相同的东西两次,第二次导入会覆盖第一次。问题出在哪里?