2017-12-18 2 views
1

는 다음 코드를 고려하십시오Express 속성 ip가 Object.keys (요청)에 나타나지 않는 이유는 무엇입니까?

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

첫 번째 로그에서 우리가 iprequest의 속성 아니라고 볼 수 있지만, 두 번째 로그 ip에 인쇄됩니다. 왜 이런 일이 생길까요?

+5

['Object.keys'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) 개체의 배열을 반환 ** 자신의 열거 가능 * * 속성. 그래서'ip'가 프로토 타입 체인 (** 소유하지 않음 **)에 있거나 ** enumerable ** 속성으로 표시되어 있으면 나열되지 않습니다. –

+1

.. 같은 일이 배열에서 발생합니다 :'Object.keys (someArray);'는'length' 속성을 포함하지 않을 것입니다. –

+1

그것은 'enumerable : true'로 표시되고 자체 속성으로 설정되어있는 것으로 보입니다. –

답변

1

익스프레스의 소스 코드에 따르면

In this particular line

IP 지수는 요청 객체 내에서 기본적으로 명시 없음을 나타냅니다가 반환하는 함수로서 그 인덱스가 신뢰 프록시 fn의 값을 proxyaddr으로 전달하여 반환합니다.

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

를 찾을 수 없습니다 익스프레스 Object.keys (요청)의 그 역동적이고 자동 생성 된 인덱스는 어떻게.

+0

"ip"인덱스가 요청 객체의 프로토 타입에 있기 때문에 –

1

나는 그것 때문에 this line라고 생각합니다. 실제로 새로운 인스턴스를 만들고 req 모듈을 프로토 타입으로 사용하고 있습니다. 이렇게하면

당신은 IP 속성을 볼 수 있습니다 :

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

다시 받고있어 키는 인스턴스 프로토 타입 체인에서 속성의 모든입니다. 깊은 중첩 된 두 가지 수준의 사실 :

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

프로토 타입과 그 모든 것들에 대해 더 자세히 알고 싶습니까? –

+0

Gustavo,이 링크 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain –

1

Object.keys()이 열거 지정된 객체의 자신의 열거 속성의 배열을 (반환 단지 즉, 당신은 객체를 통해 누구 열거 재산 true로 설정 한 경우에만 해당 속성을 반복하려고하는 경우 반복됩니다 - Object.getOwnPropertyDescriptor 참조).

이것은 ip 속성이 request 객체로하고 request 객체가 프로토 타입 체인에 어딘가에 ip 속성을 상속하는 것을 소유하지 않은 것을 의미 할 수있다.

실제적인 경우임을 입증하려면 Object.getPrototypeOf() 메서드를 사용할 수 있습니다.

처음에는 단순히 Object.getPrototypeOf(req)을 시도했지만 반환 된 객체에 ip 속성을 찾지 못했습니다. 그래서 나는 프로토 타입 체인을 더 깊이 파고 들었다. ip 주소 속성은 프로토 타입 체인에서 상속되기 때문에

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

Object.keys()이의 속성으로 ip을 나열하지 않습니다, 속성 앞서 언급 한 바와 같이

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

으로 IP와 객체를 반환 req 개체.

또한 JS : Getters에서 사용할 수있는 또 다른 멋진 기능, 즉 계산 된 속성 값을 강조 표시합니다.

은 때로는 동적으로 계산 된 값을 반환하는 재산에 대한 액세스를 허용하는 것이 바람직하다, 또는 호출 명시 적 방법의 사용을 요구하지 않고 내부 변수의 상태를 반영 할 수 있습니다. MDN에서 Getters에 대해 읽어보십시오.

여기 정확히 무슨 일이 일어 났습니까? Express에는 http 요청의 페이로드에서 IP 주소를 추출하기위한 내부 논리가 있으며 IP 주소에 액세스하는 대신 req.ip(), Express 개발자는 ip 속성에 액세스 할 때 호출되는 함수를 바인딩하도록 선택했습니다. ip 속성을 사용하면 req.ip을 통해 IP 주소에 액세스 할 수 있습니다.

관련 문제