10

ES6 モジュールのエクスポートでは、エクスポートされたものとインポートされたものの間でバインドが行われるため、エクスポートされた変数が変更されると、インポートされた変数がその変更を示すことを理解しています。

ただし、インポートされた変数は、特定の状況でエクスポートされた変数へのバインディングのみを運ぶことも読みました。

私の具体的な質問は、エクスポートされた変数が次の 2 つのシナリオでバインドされる方法に違いがあるかどうかです...

// Scenario #1
let a = 5;
export default a;

// Scenario #2
let a = 5;
export { a as default };
4

2 に答える 2

11

関数とクラスの場合は同じように動作しますが、一般的なケースでは同じではありません。

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れたとしても、エクスポートされた値のままになりますが、エクスポートされた値は になります。aexport {a as default};5

ECMAScript 仕様では、次の表http://www.ecma-international.org/ecma-262/7.0/#table-42とエクスポートの主な構文宣言にexport defaultいくつかの例を含む、 3 つの異なる形式の を定義しています: 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ここでは、値として渡された関数またはクラスの名前を返すため、最初の 2 つのケースでは

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};
于 2016-09-01T16:56:43.090 に答える
0

で述べたように:

Mozilla ドキュメント

シナリオ 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;
}

ただし、パフォーマンスの違いに関する仕様はありません。

于 2016-09-01T16:48:20.467 に答える