2012-05-07 43 views
5

此腳本具有不同的行爲,具體取決於它是從節點js shell運行還是存儲在傳遞給節點的腳本文件中。爲什麼函數在全局對象中不可用?

腳本:

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

在殼輸出(僅最後4行相關IMO每個3行是複製/粘貼順次放置在Mac OS X在終端上運行的節點REPL實例。):

ArrayBuffer 
Int8Array 
Uint8Array 
Int16Array 
Uint16Array 
Int32Array 
Uint32Array 
Float32Array 
Float64Array 
DataView 
global 
process 
GLOBAL 
root 
Buffer 
setTimeout 
setInterval 
clearTimeout 
clearInterval 
console 
:當作爲保存的腳本(bash中,從Mac OS X上稱爲 node myscript.js)運行
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 

輸出

爲什麼它們有什麼不同,爲什麼不能我的腳本看到globalab

編輯:添加一個附加語句C = 2發生變化的輸出。 c在運行腳本的兩種方法中都可見。儘管如此,這仍然不能解釋a和b的存在。

+1

您可以添加到您的實驗:1)一個變量賦值沒有'var':所以只是做一個'C = 3'; 2)'console.log(this === global)' –

+0

您還可以詳細說明如何將這些文件傳遞給Node? (確切的命令行) –

+0

完成。還有其他什麼? – Trindaz

回答

4

基本上是因爲節點的REPL使用「全球」範圍內,因爲它是「本」(你可以測試與global === this)。

然而,常規模塊在其自己單獨的封閉運行。所以,你可以把它想象爲東西這樣的:

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

所以,當你在你的定義var並執行它作爲一個劇本,你真的只是它定義一個函數閉包裏面。但是在REPL中,您正在全球範圍內定義var。

+0

謝謝@TooTallNate。當用'(for var k in this)'代替'(for var k in global)''時,它不會打印任何東西。有關我如何遍歷腳本創建的符號的任何提示? – Trindaz

+0

在模塊內部,'this'指向模塊的'exports',而不是全局上下文。但是,我相信無法迭代關閉變量。這只是JavaScript的限制。 – TooTallNate

+0

@TooTallNate您可以使用蠻力來遍歷所有變量名稱組合:P –

相關問題