2012-05-07 8 views
5

このスクリプトは、ノードjsシェルから実行されるのか、ノードに渡されるスクリプトファイル内に格納されるのかによって、異なる動作をします。グローバルオブジェクトで機能が使用できないのはなぜですか?

スクリプト:シェルで

var a = 1; 
function b(){return 1;} 
for(var k in global) console.log(k); 

出力(最後の4行が3行の各々はコピー/のMac OS Xのターミナルで実行しているノードREPLインスタンスに順次貼り付けられたIMO関連している。):

ArrayBuffer 
Int8Array 
Uint8Array 
Int16Array 
Uint16Array 
Int32Array 
Uint32Array 
Float32Array 
Float64Array 
DataView 
global 
process 
GLOBAL 
root 
Buffer 
setTimeout 
setInterval 
clearTimeout 
clearInterval 
console 
module 
require 
a 
_ 
b 
k 

出力する(Mac OS X上のbashからnode myscript.jsと呼ばれる)保存したスクリプトとして実行:

ArrayBuffer 
Int8Array 
Uint8Array 
Int16Array 
Uint16Array 
Int32Array 
Uint32Array 
Float32Array 
Float64Array 
DataView 
global 
process 
GLOBAL 
root 
Buffer 
setTimeout 
setInterval 
clearTimeout 
clearInterval 
console 

なぜ異なるのですか?とbglobalに表示されないのはなぜですか?

EDIT:追加ステートメントc = 2を追加すると、出力が変更されました。スクリプトを実行する両方の方法でcが表示されました。しかしこれはまだシェルからスクリプトを実行するときにaとbの存在を説明していません。

+1

実験に追加することはできますか?1) 'var'を使わない変数の代入:' c = 3'を実行します。 2) 'console.log(this === global)' –

+0

これらのファイルをどのようにNodeに渡すかを詳しく説明できますか? (正確なコマンドライン) –

+0

完了。他の何かAtes? – Trindaz

答えて

4

基本的に、ノードのREPLは "グローバル"コンテキストを "this"として使用しています(global === thisでテストできます)。

しかし、通常のモジュールは、独自の別のクロージャで実行されます。あなたにvarを定義し、スクリプトとして、それを実行するとき

function (module, exports, global) { 
    // your module code 
} 

だから、あなたが本当に単なる関数クロージャの内部でそれを定義している:だから、それがこのような何かことを想像することができます。しかし、REPLでは、グローバルレベルでvarを定義しています。

+0

ありがとう@TooTallNate。 '(for var k in global)'を '(for this var k)'に置き換えると、何も出力されません。スクリプトによって作成されたシンボルをどのように反復できるかについてのヒント – Trindaz

+0

モジュールの中で、 'this'はグローバルコンテキストではなく、モジュールの' exports'を指します。しかし、クロージャ変数を反復する方法はないと私は信じています。 JavaScriptの単なる限界です。 – TooTallNate

+0

@TooTallNateブルートフォースを使用すると、すべての変数名の組み合わせを反復することができます。P –

関連する問題