2017-08-01 5 views
5

私はNode.jsでいくつかのオンラインチュートリアルを行っています。私が理解することはrequire(./file-path)機能を使用して、ノードは、そのファイルの内容を取得し、すぐに呼び出す機能モジュールをパラメータとして渡しているので、なぜmodule.exportsをパラメータとして渡す必要があるのですか?

(function(exports, require, module, __filename, __dirname) { 
    // content 
}()) 

の内側にラップし、私はexportsmodule.exports間の違いを理解し、ということです。それは私が上記の質問を検索してインターネット上で見ることができるすべてです。しかし私の質問は、module.exportsmoduleをラッピングIIFEに渡す必要がある理由は何ですか?私たちはモジュールだけを渡してからmodule.exportsを得ることができました。このようにすることに利点はありますか?通常、オブジェクトを関数に渡すときには、さらにobject.propertyを渡す必要はありません。

答えて

3

答えは:歴史的理由。

あなたは正しく、moduleexportsしか必要ないでしょうが、下位互換性のためにまだそこにあります。

これまでのところ、ほぼすべてのパッチリリースでモジュールラッパーが変更された時代でした。

は、ノード0.1.11ではモジュールのラッパーは:

var wrapper = "function (__filename) { "+ 
       " var onLoad; "+ 
       " var onExit; "+ 
       " var exports = this; "+ 
       content+ 
       "\n"+ 
       " this.__onLoad = onLoad;\n"+ 
       " this.__onExit = onExit;\n"+ 
       "};\n"; 

参照:https://github.com/nodejs/node/blob/v0.1.11/src/node.js#L167#L177

あなたがexportsを見ることができるようにラッパー関数を使って呼び出されたthisと同じでした。あなたは新しいオブジェクトとそれを交換することはできませんでした。あなたはそれにいくつかの予約キーを追加することさえできませんでした。 __onExitという名前のプロパティを安全にエクスポートできませんでした。

は、次に0.1.12にそれはあった。

var wrapper = "function (__filename, exports) { " + content + "\n};"; 

を参照してください:ここでhttps://github.com/nodejs/node/blob/v0.1.12/src/node.js#L243-L245

exportsは、引数の1つとして提供されたオブジェクトだったが、あなたは新しいオブジェクトとそれを交換しませんでしたあなたは、あなたが持っているオブジェクトからプロパティを追加または削除することしかできませんでした。

は、その後0.1.13はすなわちrequireinclude、これを持っていることが第一号だった:

var wrapper = "function (__filename, exports, require, include) { " + content + "\n};"; 

参照:次にhttps://github.com/nodejs/node/blob/v0.1.13/src/node.js#L225-L227

0.1.14がで(アンダースコア)__moduleを持っていた最初のラッパー(それはincludeを落とした):

var wrapper = "var __wrap__ = function (__module, __filename, exports, require) { " 
      + content 
      + "\n}; __wrap__;"; 

参照:https://github.com/nodejs/node/blob/v0.1.14/src/node.js#L280-L284

そして0.1。16ラッパーで(下線なしで)module引数を持っていた最初:

var wrapper = "var __wrap__ = function (exports, require, module, __filename) { " 
      + content 
      + "\n}; __wrap__;"; 

参照:https://github.com/nodejs/node/blob/v0.1.16/src/node.js#L444-L448

は、それはそれ以降何度も変更されていますが、これはmoduleが意思を導入してしまっている時間でありますexportsないあなたが使用できるように、任意のより多くが、それでも便利なショートカット必要:

exports.a = 1; 
exports.b = 2; 
exports.c = 3; 

の代わり:

実際に
module.exports.a = 1; 
module.exports.b = 2; 
module.exports.c = 3; 

しかし何exportsがなかったならば、1が通常記述します

const exports = module.exports; 
exports.a = 1; 
exports.b = 2; 
exports.c = 3; 

以上の可能性を:

module.exports = { 
    a: 1, 
    b: 2, 
    c: 3, 
}; 

や、静的解析ツールでいくつかのチェックを持っている:

const a = 1; 
const b = 2; 
const c = 3; 
module.exports = { a, b, c }; 

これを行う方法はたくさんありますが、それはかなりです柔軟なメカニズム。

+0

私にそれを打つ。私が記憶していたよりも早かった。 – OrangeDog

2

元はexportsrequireでした。 その後、moduleが下位互換性のある方法で追加され、エクスポートオブジェクトを完全にオーバーライドできるようになりました(とりわけ)。

+0

私が変更を見つけることができるかどうか見てみましょう。私はそれがv0.6のどこかにあると思う。 – OrangeDog

+0

後でモジュールを追加したときに、なぜmodule.exportsを削除しなかったのですか?とにかくモジュールオブジェクトから取得できます。 –

+0

@MELWINVINCENTは、新しいプラットフォームを使用する古いモジュールと古いプラットフォームを使用する新しいモジュールの両方を壊してしまったからです。 – OrangeDog

関連する問題