Есть ли разница между "export default x" и " export {x as default}"?
Я понимаю, что при экспорте модуля ES6 происходит привязка между экспортируемым и импортируемым, так что при изменении экспортируемой переменной импортируемая переменная будет демонстрировать это изменение.
однако я также читал, что импортированная переменная несет привязку к экспортированной переменной только в определенных обстоятельствах.
мой конкретный вопрос заключается в том, есть ли разница в том, как экспортированные переменные связаны в следующих двух вариант развития событий...
// Scenario #1
let a = 5;
export default a;
// Scenario #2
let a = 5;
export { a as default };
2 ответов
они не одинаковы в общем случае, хотя они могут вести себя одинаково в случае функций и классов.
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};
Как говорится в:
Сценарий 1
Он используется для именованного экспорта
// module "my-module.js"
export function cube(x) {
return x * x * x;
}
const foo = Math.PI + Math.SQRT2;
export { cube, foo };
Сценарий 2
Он используется для экспорта одного значения или для резервного значения для модуля
// module "my-module.js"
export default function cube(x) {
return x * x * x;
}
там нет спецификации о разнице в производительности, хотя.