解构默认导出对象

Destructuring a default export object

我可以在导入时解构默认导出对象吗?

给定以下导出语法 (export default)

const foo = ...
function bar() { ... }

export default { foo, bar };

以下导入语法是否有效 JS?

import { foo, bar } from './export-file';

我问是因为它确实可以在我的系统上运行,但我被告知它不应该根据规范运行。

Can I destructure a default export object on import?

没有。您只能在将对象导入变量后对其进行解构。

请注意,imports/exports 具有与对象字面量/对象模式完全不同的语法和语义。唯一的共同点是两者都使用花括号,并且它们的 shorthand 表示(仅标识符名称和逗号)无法区分。

Is the following import syntax valid JS?

import { foo, bar } from './export-file';

是的。它确实从模块中导入了两个命名导出。这是

的 shorthand 符号
import { foo as foo, bar as bar } from './export-file';

表示"declare a binding foo and let it reference the variable that was exported under the name foo from export-file, and declare a binding bar and let it reference the variable that was exported under the name bar from export-file".

Given the following export syntax (export default)

export default { foo, bar };

does the above import work with this?

No.它所做的是声明一个不可见的变量,用对象{ foo: foo, bar: bar }初始化它,并以名称default导出它。
当此模块作为 export-file 导入时,将不会使用名称 default,并且不会找到名称 foobar,这会导致 SyntaxError.

要解决此问题,您需要导入默认导出的对象:

import { default as obj } from './export-file';
const {foo: foo, bar: bar} = obj;
// or abbreviated:
import obj from './export-file';
const {foo, bar} = obj;

或者您保留导入语法,而是使用命名导出:

export { foo as foo, bar as bar };
// or abbreviated:
export { foo, bar };
// or right in the respective declarations:
export const foo = …;
export function bar() { ... }

Can I destructure a default export object on import?

是的,使用动态导入

要添加 Bergi 解决静态导入的答案,请注意在动态导入的情况下,由于返回的模块是一个对象,您 可以 使用解构赋值来导入它:

(async function () {
  const { default: { foo, bar } } = await import('./export-file.js');
  console.log(foo, bar);
})();

为什么这有效

import 在不同的上下文中有很大不同。当在模块的开头使用 import ... from ... 格式时,它是 static import,它具有 Bergi 的回答中讨论的限制。

在程序中以 import('./filename.js') 形式使用时,它被认为是 dynamic import。动态导入的操作非常类似于解析为对象的函数(作为命名导出和默认导出的组合,分配给 default 属性),并且可以这样被解构。

以提问者为例,await import('./export-file.js')将解析为:

{
  default: {
    foo: ...,
    bar: function bar() {...}
  }
}

从这里开始,你可以直接用nested destructuring赋值foobar:

const { default: { foo, bar } } = await import('./export-file.js');