2017-12-18 6 views
1

betrachten den folgenden Code:Warum erscheint die Express-Eigenschaft ip nicht in Object.keys (request)?

const express = require('express'); 
const app = express(); 
app.get('/', function(request, response) { 
    console.log(Object.keys(request)); 
    console.log(request.ip); 
}); 
app.listen(1337); 

Im ersten Protokoll können wir sehen, dass ip keine Eigenschaft von request ist, aber in dem zweiten Protokoll ip gedruckt wird. Warum passiert das?

+5

['Object.keys'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) gibt ein Array des Objekts zurück ** eigene Enumerable * * Eigenschaften. Wenn die IP-Adresse also irgendwo in der Prototypkette liegt (nicht ** im Besitz **) oder als ** nicht aufzählbar ** gekennzeichnet ist, wird sie nicht aufgelistet. –

+1

.. das gleiche passiert mit Arrays: 'Object.keys (someArray);' wird nicht die 'Länge'-Eigenschaft enthalten. –

+1

Es scheint, dass es als "enumerable: true" markiert ist und als eigene Eigenschaft festgelegt ist. –

Antwort

1

Nach dem Quellcode Express

In this particular line

Zeigt an, dass die ip Index hat in der Standardeinstellung nicht im Request-Objekt, Express ist diesen Index als eine Funktion, wo es zurückgibt die Werte von vertrauen Proxy fn und gibt es zurück, indem es eine proxyaddr übergibt.

Object.keys(Object) <- This only returns the indices that appear in the object. 

Wie ist der dynamische und automatisch generiert Indizes Express Object.keys (Anfrage) nicht in der Lage, es zu finden.

+0

Dies, weil der "ip" -Index im Prototyp des Anfrageobjekts steht. –

1

Ich denke, es ist wegen this line. Es erstellt tatsächlich eine neue Instanz und verwendet das Modul req als Prototyp.

Wenn Sie dies tun werden Sie die IP-Eigenschaft sehen:

var express = require('express') 
Object.keys(express.request) 

Die Schlüssel Sie bekommen zurück ist für die Instanz nicht alle Eigenschaften in der Prototypkette. In der Tat seine verschachtelten zwei Ebenen tief:

var p1 = Object.getPrototypeOf(req) 
var p2 = Object.getPrototypeOf(p1) 
console.log(Object.keys(p1)) // ['app'] 
console.log(Object.keys(p2)) // [..., 'ip', ...] 
+0

Wo kann ich mich mehr auf Prototypen und all das Zeug stützen? –

+0

Gustavo, in diesem Link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain –

1

Object.keys() ein Array eines bestimmten Objekts eigenen enumerable Eigenschaften zurückgibt (zählbare bedeutet nur, dass, wenn Sie versucht haben, durch das Objekt iterieren, nur jene Eigenschaften, deren enumerable Eigenschaft auf true sind angeschaltet - siehe Object.getOwnPropertyDescriptor).

bedeutet Dies könnte, dass die ip Eigenschaft nicht vom request Objekt und das Objekt request die ip Eigenschaft erbt auf der Prototypkette irgendwo gehört.

Um wirklich zu beweisen, dass dies der Fall ist, können Sie Object.getPrototypeOf() Methode verwenden.

Zuerst versuchte ich einfach Object.getPrototypeOf(req), aber ich fand die Eigenschaft ip auf das zurückgegebene Objekt nicht. Also grub ich weiter in die Prototyp-Kette.

console.log(Object.getPrototypeOf(Object.getPrototypeOf(req)));

dies ergab ein Objekt mit ip als Eigenschaft

IncomingMessage { 
    ... 
    acceptsEncodings: [Function] 
    ip: [Getter], 
    ips: [Getter], 
    ... 
} 

Wie bereits erwähnt, weil ip Adresse Eigenschaft von der Prototypkette geerbt wird, Object.keys() nicht ip listet als Eigenschaft der req Objekt.

Es hebt auch eine weitere nette Funktion in JS verfügbar: Getters, aka berechnete Eigenschaftswerte.

Manchmal ist es wünschenswert, den Zugriff auf eine Eigenschaft zu ermöglichen, die eine dynamisch berechneten Wert zurückgibt, oder Sie können, ohne dass die Verwendung von expliziten Methode den Status eine interne Variable reflektieren wollen nennt. Lesen Sie über Getters auf MDN.

Genau das passiert hier. Express verfügt über eine interne Logik zum Auswählen der IP-Adresse aus den Nutzdaten der HTTP-Anforderung und statt wie folgt auf die IP-Adresse zuzugreifen: req.ip(), Express-Entwickler haben die Eigenschaft ip an eine Funktion gebunden, die beim Zugriff auf die IP-Adresse aufgerufen wird ip Eigenschaft und Sie können einfach über req.ip auf die IP-Adresse zugreifen.