【问题标题】:Why can't I `export default` a constant inline with its definition?为什么我不能“导出默认值”一个与其定义一致的常量?
【发布时间】:2021-06-16 08:16:49
【问题描述】:

我可以定义一个函数然后导出为默认值,将其定义为内联导出,或者定义它并将其导出为默认内联:

function myFunc() {
    ...
}
export default myFunc;
export function myFunc2() {
    ...
}
export default function myFunc3(param) {
    ...
}

我可以定义一个类然后导出为默认,定义它并内联导出,或者定义它并导出为默认内联:

class MyClass {
    ...
}
export default MyClass;
export class MyClass2 {
    ...
}
export default class MyClass3 {
    ...
}

很酷,所以类和函数是一致的。现在,常量:

定义然后导出为默认值:

const myConst = 42;
export default myConst;

定义和导出内联:

export const myConst = 42;

这些都很好。但我无法定义它并导出为默认内联:

export default const myConst = 42; // nope -- syntax error!

我的问题:为什么在这方面常量与类和函数不同?它们都是可导出的,都可以作为默认值导出。为什么我不能用常量内联?

我在谷歌搜索时找到了Why Is `Export Default Const` invalid?。我相信提问者试图问我同样的问题,但有一个高度赞成、接受的答案不能回答我的问题。我询问编译器拒绝语法的技术原因。我希望了解为什么这种语言是这样设计的。

如果有帮助,答案可能是“如果支持此语法,[事物] 会发生”或“它曾经以这种方式工作,但我们删除它是因为 [事物] 发生了”或“有关将其添加到规范中的公开讨论,请参阅 [此处]。”

如果 TypeScript 和 JavaScript 之间的区别与答案有任何关联,请澄清。

【问题讨论】:

  • I am looking to understand why the language is designed this way. 很少有人设计过这种语言,因此您可能很难获得满意的答案。
  • @NicholasTower 我对此没有意见。 :)
  • 因为你不需要。默认导出不是按定义命名的,您可以只使用export default 42;
  • 也许它可以帮助一点 - stackoverflow.com/questions/36261225/…
  • 我觉得你引用的其他问题讨论了这个问题,讨论的深度与讨论的深度一样。不确定您还在寻找什么答案

标签: javascript typescript es6-modules


【解决方案1】:

看看why JavaScript has default exports。他们被介绍为syntactic sugar

export default function example() {}
// is the same as
function example() {}
export { example as default }
export default class Example {}
// is the same as
class Example {}
export { Example as default }
export default (expression);
// is the same as
let *default* = (expression);
export { *default* as default }

export 不是一个可以加在任何声明上的修饰符,它是一种单独的声明语句。

默认导出/导入旨在简化模块以微不足道的名称导出单个函数或类的常见用例(这就是他们甚至 allow anonymous declarations 的原因) - 为大型实体创建一个整体是有意义的模块(或者只是遵循Java“每个类一个文件”模式)。常量值不是您通常会为其创建自己的模块的东西,因此它没有特殊的语法糖。一起去

const myConst = 42;
export { myConst as default};

或(如果您实际上不需要本地名称)

export default 42;

【讨论】:

  • 42 是一个人为的例子。将更复杂的事物声明为常量是很常见的——例如,匿名函数。 const func = (some args) => { some impl }。为什么我不能export default 那个内联?
  • @JakeRobb 如果你想匿名,你就写export default (some args) => { some impl }。如果你想命名它,你也可以使用函数声明export default function func(some args) { some impl }。在很多情况下,您必须声明 const(在模块中的其他内容旁边)并希望它成为默认导出。至少它是这样设计的——我并不是说它适合所有的编程风格:-)
  • 对,我知道有替代的等效语法。我在问为什么这种特殊的语法似乎从可用于函数和类的语法中自然/逻辑地扩展,但不适用于常量。
【解决方案2】:

我刚刚在 ES Discuss 浏览了Why is "export default var a = 1;" invalid syntax?。这样做之后,在我看来,这与绑定声明和默认导出概念的性质差异有关。

您可以在一个语句中声明多个绑定,如下所示:

const a = 1, b = 2, c = 3;

default 导出必须只是一个 single 表达式。因此,声明和默认导出的概念在逻辑上是不匹配的,因此试图将它们组合在一个单行代码中是无法在语法上完成的。无法确定以下语句中的默认导出应该是什么:

export default const a = 1, b = 2, c = 3;

函数和类没有这些问题。您不能像使用绑定/变量那样在单个语句中声明多个函数或类。因此,函数和类可以在单行中声明为默认导出。

【讨论】:

  • 如果设计人员愿意,这似乎很容易在语言级别上解决。您只需创建一种语法,只允许一个表达式用于export default
猜你喜欢
  • 2015-01-21
  • 2016-07-15
  • 2019-03-23
  • 2016-07-09
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
  • 2018-04-14
  • 1970-01-01
相关资源
最近更新 更多