2013-03-08 24 views
5

In jedem Webbrowser wird das folgende Skript dazu führen, dass 'wee' an die Konsole gesendet wird. Im Knoten sendet es {}.Wo sind Variablen in Nodejs gespeichert?

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

Ich weiß, dass in Knoten this bezieht sich auf die Exporte in diesem Fall widersprechen. Ich weiß über die Variable global, und darauf möchte ich nicht zugreifen. Außerdem setzt das obige Skript d nicht auf das globale Objekt. Wo zum Teufel geht es? Ich kann es explizit durch console.log(d); in dem obigen Skript zugreifen, aber es scheint, in irgendeinem nicht standardmäßigen Raum ohne guten Grund verstaut zu werden.

Mir ist auch klar, dass die var Entfernen d auf dem global Objekt erklären wird, die das erwartete Verhalten ist, obwohl es dumm scheint var auf der obersten Ebene Umfang haben ihre Werte in einem anderen Ort als „nackte“ Variablen zu speichern. Ich meine, ist nicht der Sinn des Modulsystems eine Art digitale Prophylaxe gegen die globale Umweltverschmutzung? Hier scheint es so leicht zu sein, das Muster zu durchbrechen und es ist so schwierig, etwas Standardmäßiges zu tun.

d ist nicht auf dem Objekt module entweder deklariert.

Ich muss nicht rechtfertigen, warum ich diese Frage stelle, aber ich werde dem ersten Troll antworten, um mit einem "aber warum willst du tun hurr durrrr" zu kommen.

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

In der gleichen Weise, die ich zwischen bestimmten Objektzuständen von d unterscheiden kann, soll ich in der Lage sein, die Zustände des Top-Level-Rahmen zu unterscheiden. In einem Browser ist dies das Objekt window, auf das sich this im oberen Bereich bezieht. Ich sollte in der Lage sein, die Eigenschaften der Umgebung vor und nach der Skriptausführung zu beurteilen, um eine Vielzahl von Dingen zu bestimmen, von denen eine Inspektion von Funktionen und Variablen, die im oberen Bereich eines beliebigen Skripts deklariert sind, auf die sie angewendet werden kann exportiert Objekt. Dies würde es einfach programmatisch zu Modul Wrapper für Skripte zu erzeugen, die als Module mit einer einfachen forEach in der Liste der Top-Level-Funktionen und Variablen angewandt nicht geschrieben wurden whateverThisIs['varFunc'] zu module.exports['varFunc'] ...

und Sachen zuzuweisen ...

Dieses Verhalten ähnelt dem einer anonymen Funktion. In einer anonymen Funktion könnte this auf das window Objekt verweisen, var s müssten direkt aufgerufen werden (da sie im Bereich der anon func liegen), und leaked vars deklariert ohne das var Schlüsselwort könnte am window Objekt enden. Ich habe noch nicht das gesamte Handbuch gelesen, vielleicht ist genau das, was vor sich geht, aber ich hatte den Eindruck, dass jedes Modul in seinem eigenen Kontext (Fenster) ausgeführt wurde und dass der Knoten Nachrichten zwischen Modulkontexten durch die Verwendung von global und module.exports ...

Ich weiß es nicht. Ich möchte es aber wissen. Wenn Sie es wissen, lassen Sie es mich wissen.

+2

Es geht in der lokalen Variablen. In einem Modul ist Ihr Code in eine Funktion eingebunden. Du siehst es einfach nicht. –

+0

Also ist es nur eine anonyme Funktion? Sicher? – Kastor

+2

Ja ... nun, ich erinnere mich nicht, ob es anonym ist, aber das ist egal. Es ist eine Funktion. Der erste für die Funktion definierte Parameter ist 'exports', und an diesen Parameter wird ein leeres Objekt übergeben. Das gleiche Objekt wird als der 'this'-Wert der Funktion gesetzt. Sie können dies mit 'console.log (arguments [0] === exports, arguments [0] === dies);' testen, und Sie erhalten 'true' für beide. –

Antwort

10

So wird jeder Knotenmodul wie der Körper einer Funktion als shown here in the node source code

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

So gewickelt, wenn Sie eine Variable mit var erklären, es funktions lokal auf das Modul ist im Grunde eine private Variable für das Modul . Es ist keine Eigenschaft von global, module, module.exports oder this. Wenn Sie var vergessen, geht es in das global Objekt als eine Eigenschaft. Wenn Sie explizit eine Eigenschaft unter this erstellen, geht das in exports und ist für andere Module verfügbar.

Hier ist ein kleines Programm, das hoffentlich aufschlussreich ist.

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

Und es ist Ausgabe:

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

Danke für den Link zur Quelle. : D Ich habe nie versucht, die lokalen Variablen einer Funktion zu untersuchen. Ich weiß nicht, ob es einen Hack gibt oder nicht, aber das Verhalten, das ich sehe, macht jetzt Sinn, da ich den Kontext kenne. Es ist wie das Schreiben von Bookmarklets. – Kastor

+0

Also habe ich versucht, ein Skript auszuführen, das den Wrapper beenden würde ...}; Ich werde etwas anderes finden. : D – Kastor

+0

Danke für die Klärung dieses Problems ... schrieb eine native Knotenerweiterung und kämpfte damit für ein paar Tage! +1 – jkp

Verwandte Themen