2016-06-01 4 views
0

私は、次を含むファイルがあります:別のファイルではモジュールのエクスポートを使用すると、クラス自体の代わりにインスタンスがエクスポートされるのはなぜですか? (コンストラクタをエクスポートする方法)

var Foo = function() {}; 
Foo.prototype.bar = function() { return "hello world" } 
export default function() { 
    return new Foo(); 
} 

を、私はそのようにようにこれをインポートすることができます。

import Foo from "./my_other_file.js"; 
var foo = new Foo(); 
console.log(foo.bar()); 
// => "hello world" 

それが私にしばらく時間がかかりましたこれを稼働させる。私が混乱させた特定の事はexport default function() { return new Foo() }です。私の最初の傾向はreturn Fooでした(つまり、インスタンスの代わりにクラス自体を返します)。

クラスを2回初期化する必要はありません(エクスポート時とインポート後に1回)。私はこのタイプのものに出くわすのは初めてではありません - 継承を使うときにも見ました。

私の質問は - なぜこの場合ですか?それは私には直感的ではないようですので、それには正当な理由があることを期待しています。

+0

最初に2つの機能がある理由はわかりません。 – zeroflagL

+0

@zeroflagL私はあなたの混乱を本当に理解していません。どちらの機能は?どうして? –

+0

'Foo'とエクスポートする関数です。後者はこの例では無意味です。 – zeroflagL

答えて

2

なぜこの場合ですか?

モジュールは、直接Fooコンストラクタをエクスポートしますが、新しいFooインスタンスを作成するだけで、工場機能しません。インスタンス自体をエクスポートしないことに注意してください(あなたの質問のタイトルが示唆しているように)。

この方法の利点は、あなたがnewキーワードを省略しても欠点は、あなたが簡単にクラスのサブクラスを作成または拡張することができないのは勿論である

import Foo from "./my_other_file.js"; 
var foo = Foo(); // <== 
console.log(foo.bar()); 

を行うことができるということです。

私の初期の傾きは、クラス(コンストラクタ関数)を返す関数をエクスポートしてはならない、return Foo

Noにしました。あなたは、単に(もちろんES6、またはexport default class Foo {…}export {Foo as default}または

export default function Foo() {}; 
Foo.prototype.bar = function() { return "hello world" }; 

を使用して、直接クラス自体をエクスポートする必要があります。

+0

あなたは「もちろん」という言い方は数回はしますが、私は同じ自明感を感じません。おそらくあなたはこれらの点をもう少し徹底的に説明することができます。 –

+1

@maxpleaner:最初の "もちろん":モジュールの外から 'Foo'クラスに直接アクセスすることなく、それをサブクラス化またはいくつかの方法でミックスする必要があるコードはもっと複雑です。単にそれが必要ではないかもしれませんが、もしそうであれば、デフォルトのエクスポートの次にクラスをエクスポートするのは簡単です。 2番目の「もちろん」:ES6モジュールを使用している場合は、クラスにもES6構文を使用することを期待していました。それはまだ私が言及した他の2つのオプションと同等です。 – Bergi

1

私は通常、自分のEMCAScript6クラスをC#Apiのクラスファイルのように定義したファイルを表示します。あなたのケースでは

は、あなたのクラスを定義するには、Fooのクラスファイルでこれを行うだろう:

export default class Foo { 
    bar() { 
     return "hello world" 
    } 
} 

他のファイルは同じままです。

このように、クラスのインスタンスを2つ作成する必要はありません。使用するインスタンスを作成するだけです。

あなただけの「Hello World」を返す関数を返すことはFooファイルをしたい場合は、この

export default function() { 
    return "hello world"; 
} 

を行い、その後、機能などの他のファイルにはFooを使用すると思います。

1

このコードは、上記のコンストラクタの代わりにファクトリ関数を期待輸入(例えばフレームワークアプリケーション)があることを前提としている:

import fooFactory from from "./my_other_file.js"; 

// launches a function and throws on constructors 
fooConsumer(fooFactory); 

任意の方法は、それがdefault(手元の輸出の両方を維持するために常に良いアイデア)と名付けられた輸出。

export var Foo = function() {}; 
Foo.prototype.bar = function() { return "hello world" } 
export default function() { 
    return new Foo(); 
} 

名前付きエクスポートが現在アプリで使用されていなくても、後で(テスト用に)役立つ場合があります。