在一般情况下它们并不相同,尽管它们在函数和类的情况下可以表现相同。
let a = 4;
export default a;
等价于
let a = 4;
let *default* = a;
export {*default* as default};
意思是
let a = 4;
export default a;
a = 5;
将保留4 作为导出值,即使模块内的a 已更改,而export {a as default}; 将使导出值5。
ECMAScript 规范定义了 export default 的三种不同形式,此表中有一些示例 http://www.ecma-international.org/ecma-262/7.0/#table-42 和导出的主要语法声明:http://www.ecma-international.org/ecma-262/7.0/#sec-exports
export default HoistableDeclaration
export default ClassDeclaration
export default [lookahead ∉ { function, class }] AssignmentExpression;
HoistableDeclaration 在这种情况下映射到函数声明和生成器声明。
如果我们查看定义文件内变量名称映射到导出名称的规范,http://www.ecma-international.org/ecma-262/7.0/#sec-exports-static-semantics-exportentries
ExportDeclaration: export default HoistableDeclaration
Let names be BoundNames of HoistableDeclaration.
Let localName be the sole element of names.
Return a new List containing the Record {[[ModuleRequest]]: null,
[[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default"}.
ExportDeclaration: export default ClassDeclaration
Let names be BoundNames of ClassDeclaration.
Let localName be the sole element of names.
Return a new List containing the Record {[[ModuleRequest]]: null,
[[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default"}.
ExportDeclaration: export default AssignmentExpression;
Let entry be the Record {[[ModuleRequest]]: null, [[ImportName]]: null,
[[LocalName]]: "*default*", [[ExportName]]: "default"}.
Return a new List containing entry.
NOTE
"*default*" is used within this specification as a synthetic name for anonymous default export values.
BoundNames这里返回作为值传递的函数或类的名称,所以在前两种情况下
export default function fn(){}
// or
export default function* fn(){}
// or
export default class cls {}
将为变量 fn 或 cls 导出实时绑定。
你也可以
export default function(){}
// or
export default function*(){}
// or
export default class {}
在这种情况下,它们将导出没有实时绑定的值,因为它们没有名称。
在export default AssignmentExpression ; 的最后一种情况下,这就是您的export default a; 示例所满足的。你可以注意到它有[[LocalName]]: *default* 而不是[[LocalName]]: localName 像其他人一样。这是因为export default a; 无法将a 识别为要导出的名称,它会将其处理为a 的当前值,即导出值。这与export default 4; 没有什么不同,从规范的角度来看,它没有名字。
基本上
export default function fn(){}
等价于
function fn(){}
export {fn as default};
但是
let a = 4;
export default a;
不等于:
let a = 4;
export {a as default};