解构默认导出对象

sfl*_*che 31 javascript es6-modules

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

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

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

export default { foo, bar };
Run Code Online (Sandbox Code Playgroud)

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

import { foo, bar } from './export-file';
Run Code Online (Sandbox Code Playgroud)

我问,因为它在我的系统上工作,但我被告知它不应该按照规范工作.

Ber*_*rgi 58

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

不可以.您只能在将对象导入变量后对其进行解构.

请注意,导入/导出的语法和语义与对象文字/对象模式的语法和语义完全不同.唯一常见的是,它们都使用花括号,而它们的简写表示(只有标识符名称和逗号)是无法区分的.

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

import { foo, bar } from './export-file';
Run Code Online (Sandbox Code Playgroud)

是.它确实从模块导入两个命名导出.这是一个简写符号

import { foo as foo, bar as bar } from './export-file';
Run Code Online (Sandbox Code Playgroud)

这意味着"声明一个绑定foo并让它引用foo从名称中导出的变量export-file,并声明一个绑定,bar并让它引用bar从名称中导出的变量export-file".

给定以下导出语法(导出默认值)

export default { foo, bar };
Run Code Online (Sandbox Code Playgroud)

以上导入是否适用于此?

.它的作用是声明一个不可见的变量,用对象初始化它{ foo: foo, bar: bar },然后在名称下导出它default.
导入此模块时export-file,default将不使用该名称,foo并且bar将找不到导致a的名称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;
Run Code Online (Sandbox Code Playgroud)

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

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

  • @sfletche是的,这个说法是错误的.如果有多个变量,则优先使用命名导出.当只有一个主要值要导出时(例如一个类),仅支持默认导出.默认导出具有更简单的语法,因为它们经常需要,而不是因为它们通常受到青睐. (4认同)
  • 我读过无数次“默认导出受青睐”并且提供了更简单的语法。但是,不是需要导入默认对象然后对内容进行解构,与该主张背道而驰吗? (2认同)

Ste*_*eve 6

是的,使用动态导入

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

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

为什么这有效

import在不同的环境中运作方式大不相同。当在模块的开头使用时,在 format 中import ... from ... ,它是一个静态 import,它具有在 Bergi 的回答中讨论的限制。

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

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

{
  default: {
    foo: ...,
    bar: function bar() {...}
  }
}
Run Code Online (Sandbox Code Playgroud)

从这里开始,您可以使用嵌套解构直接分配foo, 和bar

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