2016-08-16 6 views
0

私はこのblogからCommonJSについて学習し、コードに関しては、以下のunderstanindトラブルを抱えています。この例ではcommonjsはエクスポート中に2つのコピーを作成し、プロセスを必要としますか?

、我々は基本的にモジュールの2つのコピーを作る:1とき 私たちは、それをエクスポートし、私たちがそれを必要とするときに1つ。さらに、 main.jsのコピーが元のモジュールから切断されました。だから でもカウンタをインクリメントすると-1を返します。カウンタ のインポートされた変数はモジュールからの変数 の変数の切断コピーです。

// lib/counter.js 

var counter = 1; 

function increment() { 
    counter++; 
} 

function decrement() { 
    counter--; 
} 

module.exports = { 
    counter: counter, 
    increment: increment, 
    decrement: decrement 
}; 


// src/main.js 

var counter = require('../../lib/counter'); 

counter.increment(); 
console.log(counter.counter); // 1 

2つのコピーが作成されるのであれば、その後、各コピーは、counterincrementの独自のバージョンを持っていないでしょうか?したがって、それぞれがincrementという独自の機能に接続されますか?著者は1つのcounterのコピー、increment、およびmodule.exportsはであるdecrementのでcounter.incrementがコピーを必要としconsole.log(counter.counter)に接続されたカウンタを返すでincrement関数を呼び出すべきではありませんvar counter = require('../../lib/counter')内の別のコピーがあることを言っています必要なコピー?

答えて

1

私は、ES6モジュールとNodeJs CommonJSモジュールとの間の対比を引き起こすと述べました。完全には正しくありません。

ここにモジュールが必要な場合は、理解しておく必要があります。

どのようにrequireがバックグラウンドで機能しますか?

要するに、requireを呼び出すのに必要なモジュールコードが実行され、キャッシュされます。 モジュールコードが実行される前に、Node.jsは関数ラッパー(module wrapping)でラップします。これにより、グローバルオブジェクトではなくトップレベルの変数(カウンタなど)がモジュールにスコープされます。これは、モジュール内で宣言された変数に関して、closureとして振舞うことができます。最後に、module.exportsの内容が返されます。

プリミティブとオブジェクトの型の値割り当てはどのように行われますか?

module.exportslib/counter.jsを見てみましょう。
プリミティブ値(counter)と2つの関数(incrementdecrement)をエクスポートしていることがわかります。 counterは、その値によってコピーされます。つまり、数字1はmodule.exports.counterの値として設定されますが、インクリメントとデクリメント(どちらもファーストクラスのオブジェクト)は参照によってコピーされます。module.exports.incrementmodule.exports.decrementの両方が体内で使用される変数はcounterです。 this投稿でプリミティブとオブジェクトの割り当てについて詳しく読むことができます。

最後にmain.jscounter変数(これはcounterからmodule.exportsの内容が割り当てられます)は、次のキーを持つオブジェクトです。

  1. counter - 型numberのプリミティブな値です。
  2. increment - クロージャへのポインタです。
  3. decrement - クロージャへのポインタでもあります。

したがって、あなたは関数内部カウンタ変数はカウンタ内module.And counter.counter値をその上に任意の操作が元のモジュールの変数に影響を及ぼさない、単にその値によってエクスポートされたので、定義されたものを意味することがわかります。