Разница между export default xxx и export {xxx as default}
export default xxx
и export { xxx as default }
в JavaScript может показаться малозаметной, но может повлиять на поведение кода.Основы модулей JavaScript
Модули — автономные фрагменты кода, позволяющие импортировать и использовать их в других модулях. Они помогают разработчикам сохранять код организованным, удобным для сопровождения и понятным.
Для работы с модулями необходимо понимать синтаксис импорта и экспорта.
import
: Используется для импорта именованных экспортов или экспортов по умолчанию из других модулей.export
: Используется для экспорта значений, функций или классов из модуля, делая их доступными для импорта другими модулями.
Существует два вида экспорта:
- Именованные экспорты: В модуле может быть несколько именованных экспортов. Они импортируются явно, используя свои имена.
- Экспорт по умолчанию: В каждом модуле может быть только один экспорт по умолчанию. Они импортируются без указания имени.
Поведение export { xxx as default }
В JavaScript импорт — это живая привязка, или ссылка, а не значение. Это означает, что при импорте переменной из другого модуля импортируется ссылка на эту переменную, а не копия её значения.
Рассмотрим пример:
// math.js
let value = 1;
setTimeout(() => {
value = 888;
}, 500);
export { value as default };
// app.js
import value from './math.js';
setTimeout(() => {
console.log(value); // ?
}, 1000);
Угадайте, какое значение value
будет выведено в этом случае?
Ответ: 888
, а не 1
. Это связано с тем, что export
экспортирует ссылки.
Поведение export default xxx
Синтаксис export default
используется для экспорта значения по умолчанию из модуля. Однако при использовании синтаксиса export default value
экспортируется текущее значение, а не живая ссылка.
// math.js
let value = 1;
setTimeout(() => {
value = 888;
}, 500);
export default value;
// app.js
import value from './math.js';
setTimeout(() => {
console.log(value); // 1
}, 1000);
В этом случае, когда переменная value
в math.js
меняется, переменная value
в app.js
не меняется. Это происходит потому, что value
хранит текущее значение на момент импорта, а не живую ссылку.
Экспорт ссылочных типов данных
Как видите, ранее экспортировались примитивные типы данных, но что если экспортировать ссылочные типы данных?
// math.js
const value = {
current: 1,
};
setTimeout(() => {
value.current = 888;
}, 500);
export default value;
// ИЛИ
// export { value as default };
// app.js
import value from './math.js';
setTimeout(() => {
console.log(value.current);
}, 1000);
Как видите, нет разницы между export default xxx
и export { xxx as default }
при работе со ссылочными типами данных. Можно понять, что в JavaScript они всегда являются ссылочными типами, и при экспорте не произойдёт их глубокое копирование.
Лучшие практики и рекомендации
Хотя и export default xxx
, и export { xxx as default }
могут использоваться для экспорта значений по умолчанию, в некоторых сценариях их поведение различается. Для выбора правильного синтаксиса можно воспользоваться следующими рекомендациями:
- Используйте
export default xxx
, если необходимо экспортировать значение, например строку или число, и не требуется живая привязка. - Используйте
export { xxx по умолчанию }
, если требуется живая привязка, особенно если экспортируемое значение может меняться со временем (не рекомендуется). - Для ссылочных типов данных можно использовать любой синтаксис, поскольку они всегда экспортируют ссылку.
- И ещё одно предложение: Для удобства чтения и сопровождения кода рекомендуется использовать именованные экспорты вместо экспортов по умолчанию.
Заключение
Хотя на первый взгляд разница между export default xxx
и export {xxx as default}
в JavaScript может показаться незначительной, она может существенно повлиять на работу вашего кода.