Do you really understand export default?

Time:2022-5-5

export default Aandexport { A as default }At first glance, it looks the same, but there are some subtle differences. It is easier to leave a hole. This paper introduces the differences between the two writing methods.

importStatement imports a reference, not a value

If there is an export, there must be an import. Let’s make it clear firstimportHow statements work.

import { A } from './module.js';

Obviously, in the above code,Aand./module.jsA in is the same. Look at this Code:

const module = await import('./module.js');
const { A: destructuredA } = await import('./module.js');

In this code,module.AAndAIt’s the same, but becausedestructuredAIt is a structure assignment, so there are some differences.

Let’s take a look./module.js

// module.js
export let A = 'initial';

setTimeout(() => {
  A = 'changed';
}, 500);

Import./module.jsThe code for is./main.js

// main.js
import { A as importedA } from './module.js';
const module = await import('./module.js');
let { A } = await import('./module.js');

setTimeout(() => {
  console.log(importedA); // "changed"
  console.log(module.A); // "changed"
  console.log(A); // "initial"
}, 1000);

importThe statement imports a reference, that is, when./module.jsinAWhen the value of changes,./main.jsWill also change. Obtained by deconstruction assignmentAIt will not change because the value used in the deconstruction process is assigned to the new variable instead of reference.

It is worth noting that static statementsimport { A } ...Although it looks like deconstruction assignment, it is actually different from deconstruction assignment.

To summarize:

//The following code is a reference
import { A } from './module.js';
import { A as otherName } from './module.js';
import * as module from './module.js';
const module = await import('./module.js');
//The following code gets the value
let { A } = await import('./module.js');

export defaultsentence

Let’s revise it./module.js

// module.js
let A = 'initial';

export { A };
export default A;

setTimeout(() => {
  A = 'changed';
}, 500);

Also modify./main.js

// main.js
import { A, default as defaultA } from './module.js';
import anotherDefaultA from './module.js';

setTimeout(() => {
  console.log(A); // "changed"
  console.log(defaultA); // "initial"
  console.log(anotherDefaultA); // "initial"
}, 1000);

The output is"initial", why?

We know that we can directlyexport default 'hello';But I can’texport { 'hello' as A }。 The specification is a little different between the two grammars.export defaultThe following will be treated as expressions. So we canexport default 'hello';, evenexport default 1 + 2;。 Therefore, inexport default AIn,AIs used as an expression statement, so the value of a is used. Therefore, whenAThe value of issetTimeoutWhen it’s changed,export defaultThe value of going out has not changed.

To summarize:

//Quote
import { A } from './module.js';
import { A as otherName } from './module.js';
import * as module from './module.js';
const module = await import('./module.js');
//Value
let { A } = await import('./module.js');

//Export reference
export { A };
export { A as otherName };
//Export value
export default A;
export default 'hello!';

export { A as default }sentence

export {}The exported is always a reference, so:

// module.js
let A = 'initial';

export { A, A as default };

setTimeout(() => {
  A = 'changed';
}, 500);

Similarly, in the previous./main.jsMedium:

// main.js
import { A, default as defaultA } from './module.js';
import anotherDefaultA from './module.js';

setTimeout(() => {
  console.log(A); // "changed"
  console.log(defaultA); // "changed"
  console.log(anotherDefaultA); // "changed"
}, 1000);

Summary:

//Import reference
import { A } from './module.js';
import { A as otherName } from './module.js';
import * as module from './module.js';
const module = await import('./module.js');
//Import value
let { A } = await import('./module.js');

//Export reference
export { A };
export { A as otherName };
export { A as default };
//Export value
export default A;
export default 'hello!';

export default functionsentence

Although, as I said beforeexport defaultThe following will be used as expressions. However, there are some exceptions:

// module.js
export default function A() {}

setTimeout(() => {
  A = 'changed';
}, 500);
// main.js
import A from './module.js';

setTimeout(() => {
  console.log(A); // "changed"
}, 1000);

output"changed"Becauseexport default functionThere is a special syntax in which functions are passed as references.

Let’s make a slight modification:

// module.js
function A() {}

export default A;

setTimeout(() => {
  A = 'changed';
}, 500);

Console outputƒ A() {}exportStatement no longer matchesexport default functionGrammatical form,AValue passing is used.

Not onlyexport default functionexport default classThe same performance.

Why?

The reason is related to the performance of these statements when used as expressions.

function someFunction() {}
class SomeClass {}

console.log(typeof someFunction); // "function"
console.log(typeof SomeClass); // "function"

If we turn them into expressions:

(function someFunction() {});
(class SomeClass {});

console.log(typeof someFunction); // "undefined"
console.log(typeof SomeClass); // "undefined"

functionandclassStatement creates an identifier in the scope / block, andfunctionandclassStatements do not, although their function and class names can be used.

Therefore, in the following code:

export default function someFunction() {}
console.log(typeof someFunction); // "function"

Without special processing, the output will be"undefined"

The summary is as follows:

//Import reference
import { A } from './module.js';
import { A as otherName } from './module.js';
import * as module from './module.js';
const module = await import('./module.js');
//Import value
let { A } = await import('./module.js');

//Export reference
export { A };
export { A as otherName };
export { A as default };
export default function A() {}
//Export value
export default A;
export default 'hello!';

Earlier, the default export in the module was like thisexport default = A, so,AIt’s more obvious to be treated as an expression.

Welcome to follow the official account “Zhongli Qianxun” or in mywebsiteBrowse for more systematic information.