5

次のスクリプトを実行するWebブラウザで'wee'は、コンソールに送信されます。ノードでは、を送信します{}

var d = 'wee';
console.log(this.d);

thisこの場合、Nodeはexportsオブジェクトを参照していることに気付きました。私は変数について知っていglobalます、そしてそれは私がアクセスしようとしているものではありません。dまた、上記のスクリプトはグローバルオブジェクトにも設定されていません。一体どこに行くの?上記のスクリプトで明示的にアクセスできますconsole.log(d);が、正当な理由がまったくないため、非標準のスペースに隠されているようです。

また、オブジェクトのvarwill宣言を削除すると、予想される動作になりますが、トップレベルのスコープで「裸の」変数とは異なる場所に値を格納するのはばかげているようです。つまり、モジュールシステムのポイントは、地球規模の汚染を防ぐためのある種のデジタル予防策であると考えられているのではないでしょうか。ここでは、パターンを壊すのはとても簡単で、標準的なことをするのはとても難しいようです。dglobalvar

dmoduleオブジェクトでも宣言されていません。

なぜこの質問をしているのかを正当化する必要はありませんが、最初のトロールに「しかし、なぜあなたはtahthurrdurrrrをやりたいのですか」と答えます。

var d = {};
d.bleep = 'y';
var a = Object.keys(d);

d.bloop = 'y';
d.blop = 'y';

var b = Object.keys(d);

// c = b - a;
var c = b.filter(function (item) {
    if(a.indexOf(item) === -1) {
        return true;
    }
    return false;
});

console.log(a,b,c);

の特定のオブジェクト状態を区別できるのと同じようdに、最上位スコープの状態を区別できるはずです。ブラウザでは、これはwindowオブジェクトでthisあり、トップレベルスコープで参照されます。スクリプトの実行前後の環境のプロパティを評価して、非常に多くのことを判断できるはずです。そのうちの1つは、任意のスクリプトの最上位スコープで宣言された関数と変数の検査であり、それらを適用することができます。オブジェクトをエクスポートします。これにより、モジュールとして記述されていないスクリプトのモジュールラッパーをプログラムで簡単に生成でき、割り当て先forEachのトップレベルの関数と変数のリストに単純に適用されます...whateverThisIs['varFunc']module.exports['varFunc']

ともの...

この動作は無名関数の動作のように見えます。匿名関数ではオブジェクトthisを参照できますが、 sは直接呼び出される必要があり(anon funcのスコープ内にあるため)、キーワードなしで宣言されたリークされた変数がオブジェクトに到達する可能性があります。マニュアル全体をまだ読んでいません。これがまさに起こっていることかもしれませんが、各モジュールが独自のコンテキスト(ウィンドウ)で実行され、ノードがとを使用してモジュールコンテキスト間でメッセージを渡したという印象を受けました。 ..windowvarvarwindowglobalmodule.exports

知らない。でも知りたいです。あなたが知っているなら、私に知らせてください。

4

1 に答える 1

12

したがって、ノードのソースコードに示されているように、すべてのノードモジュールは関数の本体としてラップされます。

NativeModule.wrapper = [
  '(function (exports, require, module, __filename, __dirname) { ',
  '\n});'
];

したがって、で変数を宣言するとvar、それはモジュールに対して関数ローカルであり、基本的にはそのモジュールのプライベート変数です。、、、、またはのプロパティではありませglobalん。を忘れると、プロパティとしてオブジェクトに入ります。にプロパティを明示的に作成すると、他のモジュールに入り、他のモジュールで使用できるようになります。modulemodule.exportsthisvarglobalthisexports

これが、うまくいけば啓発的な小さなプログラムです。

var aDeclaredVar = '*aDeclaredVar*';
undeclaredVar = '*undeclaredVar*';
this.aThisProperty = '*aThisProperty*';
module.aModuleProperty = '*aModuleProperty*';
module.exports.anExportProperty = '*anExportProperty*';

console.log('this', this);
console.log('this === exports', this === exports);
console.log('this === module', this === module);
console.log('this === module.exports', this === module.exports);
console.log('aDeclaredVar', aDeclaredVar);
console.log('undeclaredVar', undeclaredVar);
console.log('this.aThisProperty', this.aThisProperty);
console.log('module.aModuleProperty', module.aModuleProperty);
console.log('module.exports.anExportProperty', module.exports.anExportProperty);
console.log('global.undeclaredVar', global.undeclaredVar);
console.log('global.aDeclaredVar', global.aDeclaredVar);

そしてそれは出力です:

this { aThisProperty: '*aThisProperty*',
  anExportProperty: '*anExportProperty*' }
this === exports true
this === module false
this === module.exports true
aDeclaredVar *aDeclaredVar*
undeclaredVar *undeclaredVar*
this.aThisProperty *aThisProperty*
module.aModuleProperty *aModuleProperty*
module.exports.anExportProperty *anExportProperty*
global.undeclaredVar *undeclaredVar*
global.aDeclaredVar undefined
于 2013-03-08T05:51:51.080 に答える