2013-03-08 26 views
5

W dowolnej przeglądarce internetowej wykonanie następującego skryptu spowoduje wysłanie 'wee' do konsoli. W węźle wysyła {}.Gdzie są przechowywane vary w Nodejs?

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

Zdaję sobie sprawę, że w węźle this odnosi się do eksportu sprzeciw w tej sprawie. Wiem o zmiennej global i to nie jest to, do czego próbuję uzyskać dostęp. Poza tym powyższy skrypt nie ustawia wartości d na obiekcie globalnym. Gdzie do diabła się dzieje? Mogę uzyskać do niego bezpośredni dostęp przez console.log(d); w powyższym skrypcie, ale wygląda na to, że został ukryty w jakiejś niestandardowej przestrzeni bez żadnego powodu.

ja też sobie sprawę, że usunięcie var uzna d na obiekcie global, co jest oczekiwane zachowanie, chociaż wydaje się głupi, aby mieć var w górnym zakresie poziomu przechowywania jej wartości w innym miejscu niż „gołe” zmiennych. Chodzi mi o to, czy system modułowy nie ma być czymś w rodzaju cyfrowej profilaktyki chroniącej przed globalnym zanieczyszczeniem? Tutaj wydaje się, że tak łatwo złamać wzór i tak trudno zrobić coś standardowego.

d nie jest zadeklarowany na obiekcie module.

Nie muszę uzasadniać, dlaczego zadaję to pytanie, ale odpowiem na pierwszy troll, aby przyszedł z "ale dlaczego chcesz zrobić dur hurr".

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); 

W ten sam sposób, że mogę rozróżnienia między niektórymi państwami obiektowych d, powinienem być w stanie odróżnić stany górnym zakresie poziomu. W przeglądarce jest to obiekt window, określony przez this w zasięgu najwyższego poziomu. Powinienem być w stanie ocenić właściwości środowiska przed i po wykonaniu skryptu, aby określić wiele rzeczy, z których jednym byłaby inspekcja funkcji i zmiennych zadeklarowanych w górnym zakresie dowolnego skryptu, które mogą być następnie zastosowane do obiekt eksportu. W ten sposób ułatwiają programowo wygenerować owijarki moduł dla skryptów, które nie zostały napisane jako moduły z prostym forEach stosowanej do listy najlepszych funkcji poziomu i zmiennych przypisać whateverThisIs['varFunc'] do module.exports['varFunc'] ...

i takie tam ...

To zachowanie wydaje się być podobne do anonimowej funkcji. W anonimowej funkcji może odnosić się do obiektu , ponieważ musiałby on zostać wywołany bezpośrednio (ponieważ znajdują się one w zakresie funkcji anon), a przecieki vars zadeklarowane bez słowa kluczowego var mogły trafić do obiektu window. Nie przeczytałem jeszcze całego podręcznika, może to właśnie się dzieje, ale miałem wrażenie, że każdy moduł został wykonany w jego własnym kontekście (oknie) i że węzeł przekazał wiadomości między kontekstami modułów poprzez użycie global i module.exports ...

Nie wiem. Chcę jednak wiedzieć. Jeśli wiesz, daj mi znać.

+2

To idzie w lokalnej zakresu zmiennej. W module Twój kod jest zawijany w funkcję. Po prostu tego nie widzisz. –

+0

Więc to jest po prostu anonimowa funkcja? Na pewno? – Kastor

+2

Tak ... cóż, nie pamiętam, czy to anonimowe, ale to nie ma znaczenia. To jest funkcja. Pierwszy parametr zdefiniowany dla funkcji to 'exports', a pusty obiekt jest przekazywany do tego parametru. Ten sam obiekt jest ustawiony jako "ta" wartość funkcji. Możesz przetestować to za pomocą 'console.log (argumenty [0] === export, argumenty [0] === this);', a otrzymasz 'true' dla obu. –

Odpowiedz

10

Więc każdy moduł węzeł jest owinięty jako ciało funkcji jak shown here in the node source code

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

więc jeśli zadeklarować zmienną var, to funkcja lokalnego do modułu, w zasadzie prywatna zmienna dla tego modułu . To nie jest właściwością global, module, module.exports lub this. Jeśli zapomnisz var, przejdzie on do obiektu global jako właściwość. Jeśli jawnie utworzysz właściwość na this, będzie ona dostępna pod numerem exports i będzie dostępna dla innych modułów.

Oto mały program, który jest nadzieją pouczające.

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); 

I to wyjście:

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 
+0

Dzięki za link do źródła. : D Nigdy wcześniej nie próbowałam introspekcji lokalnych zmiennych funkcji. Nie wiem, czy jest to hak do zrobienia, czy nie, ale na pewno zachowanie, które widzę, ma sens teraz, gdy znam kontekst. To jak pisanie zakładek. – Kastor

+0

, więc próbowałem uruchomić skrypt kończący opakowanie ...}; Zamierzam znaleźć coś innego do zrobienia. : D – Kastor

+0

Dzięki za wyczyszczenie tego ... pisałem natywne rozszerzenie węzła i zmagałem się z tym przez kilka dni! +1 – jkp

Powiązane problemy