2016-09-01 13 views
8

ES6モジュールのエクスポートでは、エクスポートされる変数とインポートされる変数の間でバインドが行われるため、エクスポートされた変数が変更されたときに、インポートされた変数がその変更を示すようになります。`export default x`と` export {x as default} `の違いはありますか?

しかし、インポートされた変数は、特定の状況でエクスポートされた変数へのバインディングのみを保持することも読んでいます。

で述べたように私の具体的な質問が

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

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

R elated:[ES6モジュールから関数式や関数宣言をインポートするのとは何ですか?](http://stackoverflow.com/q/35223111/1048572) – Bergi

答えて

8

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

let a = 4; 
export default a; 

export {a as default};は、エクスポート値になるだろう一方

let a = 4; 
export default a; 

a = 5; 

は、モジュール内部のaが変更されているにもかかわらず、エクスポートされた値として4を残すことを意味

let a = 4; 
let *default* = a; 
export {*default* as default}; 

に相当します5

のECMAScript仕様は、このテーブルhttp://www.ecma-international.org/ecma-262/7.0/#table-42で、輸出のための主要な構文宣言のいくつかの例で、export defaultの三つの異なる形態を定義する:HoistableDeclarationhttp://www.ecma-international.org/ecma-262/7.0/#sec-exports

export default HoistableDeclaration 
export default ClassDeclaration 
export default [lookahead ∉ { function, class }] AssignmentExpression; 

この場合のマッピングにします関数宣言とジェネレータ宣言が含まれます。我々はそれがエクスポートされた名前に、イン・ファイルの変数名のマッピングを定義する仕様を見れば

、ここ

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. 

BoundNameshttp://www.ecma-international.org/ecma-262/7.0/#sec-exports-static-semantics-exportentries

として渡された関数やクラスの名前を返します。値、最初の2つのケースで

export default function fn(){} 
// or 
export default function* fn(){} 
// or 
export default class cls {} 

が変数fnまたはのためのライブバインディングをエクスポートしますので、。あなたはまた、その場合に

export default function(){} 
// or 
export default function*(){} 
// or 
export default class {} 

を行うことができ

彼らは名前を持っていないので、これらはライブのバインディングせずに値をエクスポートします。

export default AssignmentExpression ;の最後のケースでは、この例はexport default a;の例を満たしています。他のように[[LocalName]]: localNameではなく、[[LocalName]]: *default*であることに気付くことができます。これは、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}; 
+0

OK、 'let a = 4; export default a'は 'export default 4'と同じです。 '' [[LocalName]]:localName'/'[[LocalName]]:* default *'はどんな人間的な違いにもなります(読み込み時、読み込み専用ライブビューなど)? – ftor

+0

あなたは正しいです、その違いが重要であることを示す例を加えました。 – loganfsmyth

0

...エクスポートの変数は、以下の2つのシナリオにバインドされている方法に違いがあるかどうかです:

Mozilla Docs

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

のフォールバック値を持つように使われています。

+2

OPが構文について質問しているとは思わない名前付きのエクスポートではなく、むしろ 'export default X'と' export {X as default}; – loganfsmyth

関連する問題