2012-05-07 3 views
5

Этот сценарий имеет другое поведение, основанное на том, запущен ли он из оболочки js узла или сохранен в файле сценария, переданном узлу.Почему функции недоступны в глобальном объекте?

Сценарий:

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

Выход в оболочке (только последние 4 строки актуальны IMO Каждый из 3-х строк были копировать/вставить последовательно в экземпляр узла REPL работает в терминале на Mac OS X.):

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 

Вывод при запуске в качестве сохраненного сценария (так называемый node myscript.js от Баш на Mac OS X):

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

Почему они разные, и почему мой сценарий не видит a и b в global?

EDIT: добавление дополнительной инструкции c = 2 изменило выход. c был видимым в обоих методах запуска скрипта. Это все еще не объясняет присутствие a и b при запуске скрипта из оболочки.

+1

Можете ли вы добавить в свой эксперимент: 1) Назначение переменной без 'var': Так что просто сделайте' c = 3'; 2) 'console.log (this === global)' –

+0

Можете ли вы также подробно описать, как вы передаете эти файлы в узел? (Точные командные строки) –

+0

Выполнено. Что-нибудь еще? – Trindaz

ответ

4

В основном это потому, что Node REPL использует «глобальный» контекст, поскольку он «это» (вы можете проверить это с помощью global === this).

Однако обычные модули работают в своем отдельном закрытии. Таким образом, вы можете себе это быть что-то так:

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

Так что, когда вы определяете var в вашем и выполнить его как сценарий, вы на самом деле просто определяя его внутри замыканию функции. Но в REPL вы определяете var на глобальном уровне.

+0

Спасибо @TooTallNate. При замене '(для var k в глобальном)' на '(для var k в этом)' он ничего не печатает. Любые намеки на то, как я могу перебирать символы, созданные моим скриптом? – Trindaz

+0

Внутри модуля «это» указывает на «экспорт» модуля, а не на глобальный контекст. Тем не менее, я считаю, что просто нет возможности перебирать переменные замыкания. Это просто ограничение JavaScript. – TooTallNate

+0

@TooTallNate Вы можете использовать грубую силу для перебора всех комбинаций имен переменных: P –

Смежные вопросы