프로토타입에서 원하지 않는 속성을 필터링하려면 for-in의 본문을 if 문으로 래핑해야 합니다.
로 번역할 수 있다.
원하지 않는 속성이란? 스택오버플로에 좋은 예시가 있었다. 간략하게 설명하면 프로토타입에 어떤 메서드를 추가시켜주었더니 그 메서드를 상속받는 바람에 객체를 순회할 때 그 메서드도 같이 열거되어지는 문제다.
Array.prototype.filter_0 = function() {
var res = [];
for (var i = 0; i < this.length; i++) {
if (this[i] != 0) {
res.push(this[i]);
}
}return res;
};console.log([0, 5, 0, 3, 0, 1, 0].filter_0());
JavaScript
복사
var listeners = ["a", "b", "c"];
for (o in listeners) {
console.log(o);
}//prints:
// 0
// 1
// 2
// filter_0
JavaScript
복사
숫자 인덱스뿐만 아니라 for in개체 필드를 통해 열거합니다. 그래서 우리는 이제 모든 숫자 인덱스 와 filter_0 . 그러나 filter_0특정 배열 객체의 필드가 아니며 모든 배열 객체에는 이제 이 속성이 있습니다.
운 좋게도 모든 개체에는 hasOwnProperty이 필드가 실제로 개체 자체에 속하는지 또는 단순히 프로토타입 체인에서 상속되어 해당 유형의 모든 개체에 속하는지 확인 하는 메서드가 있습니다.
for (o in listeners) {
if (listeners.hasOwnProperty(o)) {
console.log(o);
}
}//prints:
// 0
// 1
// 2
JavaScript
복사
⇒ for ... in 문을 사용할 때는 이것이 배열의 인덱스나 값을 열거한다는 생각을 하지말고 객체의 필드를 열거한다는 것을 명심해야 한다.
추가로 이 처럼 숫자 키라고 보장되지 않는 상황에서 순서도 보장받지 못한다는 문제가 있다고 한다.
for in배열을 열거 하는 순서를 보장하지 않기 때문에 배열을 반복 하는 데 를 사용 하면 안 됩니다. 숫자 순서가 아닐 수 있습니다. 또한 `for(i=0;i<array.length;i++) 스타일 구성을 사용하면 숫자 인덱스 만 순서대로 반복하고 영숫자 속성은 사용하지 않는다는 것을 확신할 수 있습니다 .
또한 더글라스 크락포드가 jslint 창시자인지는 몰랐지만 아래와 같이 설명해주고 있다.
성명을 위해
for class 문의 형식은 다음과 같아야 합니다.
for (initialization; condition; update) {
statements
}for (variable in object) {
if (filter) {
statements
}
}
Plain Text
복사
첫 번째 형식은 배열 및 미리 결정된 반복 횟수의 루프와 함께 사용해야 합니다.
두 번째 형식은 개체와 함께 사용해야 합니다. 개체의 프로토타입에 추가된 멤버는 열거형에 포함됩니다. 객체의 실제 구성원을 구별하기 위해 hasOwnProperty 메소드를 사용하여 방어적으로 프로그래밍하는 것이 현명합니다.
for (variable in object) {
if (object.hasOwnProperty(variable)) {
statements
}
}
Plain Text
복사
⇒ 이 경우 문제가 또 생긴다. 내가 적용해야할 케이스는 아래와 같다.
Graph.prototype.print = function () {
for (const vertex in this.edge) {
if (this.edge.hasOwnProperty(vertex)) {
const neighbors = this.edge[vertex];
if (neighbors.length > 0) {
process.stdout.write(`${vertex} -> `);
for (let j = 0; j < neighbors.length; j++) {
process.stdout.write(`${neighbors[j]} `);
}
console.log('');
}
}
}
};
JavaScript
복사
this.edge.hasOwnProperty(vertex)로 객체 자리에 this.edge를 넣어주었더니
Do not access Object.prototype method 'hasOwnProperty' from target object. 라는 에러가 난다.
•
모든 개체가 다음에서 상속되는 것은 아닙니다. Object.prototype
•
심지어에서 상속 개체에 대한 Object.prototypehasOwnProperty
의
방법은 뭔가에 의해 그림자가 될 수있다.
You can access it via Object.prototype:
Object.prototype.hasOwnProperty.call(obj, prop);
JavaScript
복사
이를 적용시켜 에러를 모두 해결시켰다. (콘솔은 룰을 경고로 유지했다.)
Graph.prototype.print = function () {
for (const vertex in this.edge) {
if (Object.prototype.hasOwnProperty.call(this.edge, vertex)) {
const neighbors = this.edge[vertex];
if (neighbors.length > 0) {
process.stdout.write(`${vertex} -> `);
for (let j = 0; j < neighbors.length; j++) {
process.stdout.write(`${neighbors[j]} `);
}
console.log(''); // Unexpected console statemnt
}
}
}
};
JavaScript
복사