【问题标题】:Destructuring a default export object解构默认导出对象
【发布时间】:2017-05-05 22:54:43
【问题描述】:

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

鉴于以下导出语法 (export default)

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

export default { foo, bar };

以下导入语法是有效的 JS 吗?

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

我问是因为它在我的系统上工作,但我被告知它不应该根据规范工作。

【问题讨论】:

  • 好问题我看那里但他们也使用export default { a, b}exploringjs.com/es6/ch_modules.html
  • 谁说它不应该工作?但我同意他们的观点,它不应该工作。你能提供你的环境设置或在某处分享一个演示项目吗?
  • @Bergi:你做到了 :) 但我没有看到规范中详细说明了这个语法约束......
  • 要在导入时解构,您可以通过定义中间对象const obj = {foo, bar} 然后export const { foo, bar } = obj 来导出

标签: javascript es6-modules


【解决方案1】:

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

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

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

下面的导入语法是合法的JS吗?

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

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

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

这意味着“声明一个绑定foo并让它引用从export-file以名称foo导出的变量,并声明一个绑定bar并让它引用在名称 bar 来自 export-file"。

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

export default { foo, bar };

上述导入是否适用于此?

否。它的作用是声明一个不可见的变量,用对象{ foo: foo, bar: bar }对其进行初始化,然后以default的名称导出它。
当这个模块被导入为export-file 时,名称default 将不会被使用并且名称foobar 将不会被找到,这会导致一个SyntaxError。。 p>

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

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() { ... }

【讨论】:

  • 我已经读过无数次“默认导出受青睐”并提供更简单的语法。但是不需要导入默认对象然后解构内容,与该声明背道而驰吗?
  • @sfletche 是的,这种说法是错误的。当您有多个变量时,首选命名导出。只有当只有一个主要值要导出(例如一个类)时,才会使用默认导出。默认导出具有更简单的语法,因为它们经常被需要,而不是因为它们通常受到青睐。
  • 他的默认导出语句是使用速记语法创建对象字面量,他导出单个对象,就像导出命名导出添加属性到对象一样。导入语句是正确的。你的答案是错误的。
  • ImportEntries 由导出决定。从而导入创建另一个List 来容纳条目。您不能导入尚未导出的内容,这种关系是由导出而不是导入语句定义的。
  • 名字无所谓。数据结构是唯一相关的东西。该符号表示返回 List。正如我所说,你反对。
【解决方案2】:

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

是的,使用动态导入

要添加解决静态导入的 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');

【讨论】:

  • 您能否再解释一下这是如何工作的?
  • 更新了我的答案
  • 谢谢!现在更有意义了!
猜你喜欢
  • 1970-01-01
  • 2021-06-28
  • 1970-01-01
  • 2020-04-09
  • 2019-04-03
  • 1970-01-01
  • 2021-09-13
  • 2020-11-24
  • 1970-01-01
相关资源
最近更新 更多