0

In JavaScript I can rename and imported module this way

import { original_name as alias_name } from 'my_module'

Is there a good explanation for the need of as keyword and nod just follow the excellent destructuring standard?

Why not something like this:

import { original_name: alias_name } from 'my_module'

Just a curiosity always come to my mind

Fabiano Taioli
  • 5,270
  • 1
  • 35
  • 49
  • 2
    I guess because `import { original_name } ... ` isn't intended to be destructuring - destructuring would create a new value in the module that you're using import in, whereas an import actually creates a binding/alias (so if the value of `original_name` was changed in `my_module` after being imported that changed would also refect in `original_name`). So while the two syntaxes looks similar, the behaviour between the two are different, and I think adding more similarities would lead to further confusion. – Nick Parsons Apr 05 '22 at 13:47
  • destructuring not always create a new var. Only if you place var/const/let before it. If you write `{ name: exisitng_name } = something` without var/const/let you are not declaring a new var but assign to something existing. – Fabiano Taioli Apr 05 '22 at 13:56
  • Possible duplicate of [Relation between import and destructing es6 syntax?](https://stackoverflow.com/q/63199743/1048572) – Bergi Apr 05 '22 at 14:48

2 Answers2

3

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.

qrsngky
  • 2,263
  • 2
  • 13
  • 10
2

They do different things:

  • Destructuring is a form of property access, usually combined with a variable declaration like const, and possibly even a default initialiser
  • Importing a variable does declare an alias for a binding in the module scope

The important difference is that destructuring does run code (test object coercability, execute getters) while import declarations are fully declarative (setting up dependencies between modules, enabling cross-module hoisting even before the variables are initialised). This makes the latter statically analysable. Import aliases also have no concept of nested objects.

Both do allow "renaming", but they use different syntax for different things - it would've been too confusing otherwise. That their shorthand forms are similar to each other is mostly coincidental, caused by both using braces.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375