The answer is of course, they are different because they do different things, and only happen to have similarities in syntax.
But maybe there is a better reason why they were designed that way? I experimented with Node.JS modules in the following way:
// origin.js
export let specialNumber = 2;
setInterval(() => {
specialNumber = Math.random();
}, 400)
// importer.js
import { specialNumber as aliasAttempt } from './origin.js'
import * as StarImport from './origin.js'
let { specialNumber: destructuringAttempt } = StarImport;
setInterval(() => {
console.log(aliasAttempt, destructuringAttempt);
}, 400)
Here, destructuringAttempt
will always give "2" (the value it got when it was destructured), whereas aliasAttempt
will be keep getting changed. For example:
0.3600619094195876 2
0.33268826082163194 2
0.20684912705131553 2
0.8665522020482055 2
0.9349778920742413 2
It looks like destructuringAttempt
copied by value during destructuring, whereas aliasAttempt
keeps the reference to the let specialNumber
variable.
(this behavior of destructuringAttempt
is expected as let { specialNumber: destructuringAttempt } = StarImport;
is just the same as let destructuringAttempt = StarImport.specialNumber;
i.e. just copied the number)
So, maybe the reason was that, if the export is a non-const value, 'aliasing' gives a different result ("keep reference to the other variable") from typical destructuring behavior ("copy once"), therefore it's better to distinguish the syntaxes.