[javascript] JSLint 오류 ‘for in의 본문은 if 문으로 묶어야합니다’는 무엇을 의미합니까?

내 JavaScript 파일에서 JSLint 를 사용했습니다 . 오류가 발생했습니다.

for( ind in evtListeners ) {

41 행의 문제 문자 9 : for의 본문은 if 문에 싸서 프로토 타입에서 원하지 않는 속성을 필터링해야합니다.

이것은 무엇을 의미 하는가?



답변

우선 , 루프를 사용 하여 배열을 열거 하지 마십시오for in . 못. 좋은 오래된 것을 사용하십시오 for(var i = 0; i<arr.length; i++).

그 이유는 다음과 같습니다. JavaScript의 각 객체에는이라는 특수 필드가 prototype있습니다. 해당 필드에 추가 한 모든 항목은 해당 유형의 모든 개체에서 액세스 할 수 있습니다. 모든 배열에 filter_00을 걸러내는 멋진 새 함수를 갖기를 원한다고 가정하십시오 .

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());
//prints [5,3,1]

이것은 객체를 확장하고 새로운 메소드를 추가하는 표준 방법입니다. 많은 라이브러리가이를 수행합니다. 그러나 for in지금 어떻게 작동 하는지 봅시다 :

var listeners = ["a", "b", "c"];
for (o in listeners) {
    console.log(o);
}
//prints:
//  0
//  1
//  2
//  filter_0

당신이 보여요? filter_0이 또 다른 배열 인덱스라고 생각합니다. 물론 실제로는 숫자 인덱스가 아니라 숫자 인덱스뿐만 아니라 for in개체 필드를 통해 열거됩니다. 이제 모든 숫자 인덱스 와를 통해 열거 하고filter_0 있습니다. 그러나 filter_0특정 배열 객체의 필드는 아니며 모든 배열 객체에는이 속성이 있습니다.

운 좋게도 모든 객체에는 hasOwnProperty이 필드가 실제로 객체 자체에 속하는지 또는 단순히 프로토 타입 체인에서 상속되어 해당 유형의 모든 객체에 속하는지 확인 하는 메소드가 있습니다.

for (o in listeners) {
    if (listeners.hasOwnProperty(o)) {
       console.log(o);
    }
}
 //prints:
 //  0
 //  1
 //  2

참고,이 코드는 작동하지만 배열에 대한 예상대로, 당신이해야 결코, 결코 , 사용 for infor each in배열. for in배열 인덱스 나 값이 아니라 객체의 필드 를 열거합니다.

var listeners = ["a", "b", "c"];
listeners.happy = "Happy debugging";

for (o in listeners) {
    if (listeners.hasOwnProperty(o)) {
       console.log(o);
    }
}

 //prints:
 //  0
 //  1
 //  2
 //  happy


답변

jslint의 저자 인 Douglas Crockford는이 문제에 대해 여러 번 글을 썼습니다. 그의 웹 사이트 의이 페이지에는 이것을 다루는 섹션 이 있습니다 :

성명서

문장 클래스의 형식은 다음과 같아야합니다.

for (initialization; condition; update) {
    statements
}

for (variable in object) {
    if (filter) {
        statements
    } 
}

첫 번째 형식은 배열과 미리 결정 가능한 반복 횟수의 루프와 함께 사용해야합니다.

두 번째 양식은 객체와 함께 사용해야합니다. 객체의 프로토 타입에 추가 된 멤버는 열거에 포함됩니다. hasOwnProperty 메소드를 사용하여 객체의 실제 멤버를 구별하여 방어 적으로 프로그래밍하는 것이 좋습니다.

for (variable in object) {
    if (object.hasOwnProperty(variable)) {
        statements
    } 
}

Crockford는 또한 YUI 극장에서 이에 대해 이야기하는 비디오 시리즈를 가지고 있습니다. 자바 스크립트에 대한 Crockford의 일련의 비디오 / 토크는 자바 스크립트에 대해 약간 진지한 지 반드시 확인해야합니다.


답변

나쁨 : (jsHint에서 오류가 발생 함)

for (var name in item) {
    console.log(item[name]);
}

좋은:

for (var name in item) {
  if (item.hasOwnProperty(name)) {
    console.log(item[name]);
  }
}


답변

바바의 대답은 표에있다. jQuery를 사용하면 $.each()함수가이를 처리하므로 사용하는 것이 더 안전합니다.

$.each(evtListeners, function(index, elem) {
    // your code
});


답변

@all-JavaScript의 모든 것은 객체 ()이므로 “객체에서만 사용”과 같은 문장은 약간 오해의 소지가 있습니다. 또한 JavaScript는 강력하게 입력되지 않으므로 1 == “1”은 true입니다 (1 === “1”은 아니지만 Crockford는이 값이 큽니다). JS에서 배열의 progromatic 개념에 관해서는, 정의에서 타이핑이 중요합니다.

@Brenton-용어 독재자가 될 필요는 없습니다. “연관 배열”, “사전”, “해시”, “개체”, 이러한 프로그래밍 개념은 모두 JS에서 하나의 구조에 적용됩니다. 이름 (키, 인덱스) 값 쌍입니다. 여기서 값은 다른 객체 일 수 있습니다 (문자열도 객체 임)

그래서,
new Array()과 동일[]

new Object() 대략 비슷하다 {}

var myarray = [];

모든 인덱스 (일명 키)가 정수 여야한다는 제한이있는 배열 인 구조체를 만듭니다. 또한 .push ()를 통해 새 인덱스를 자동 할당 할 수 있습니다

var myarray = ["one","two","three"];

실제로 비아를 다루는 것이 가장 좋습니다 for(initialization;condition;update){

그러나 어떻습니까 :

var myarray = [];
myarray[100] = "foo";
myarray.push("bar");

이 시도:

var myarray = [], i;
myarray[100] = "foo";
myarray.push("bar");
myarray[150] = "baz";
myarray.push("qux");
alert(myarray.length);
for(i in myarray){
    if(myarray.hasOwnProperty(i)){
        alert(i+" : "+myarray[i]);
    }
}

아마도 배열을 가장 잘 사용하지는 않지만 항상 명확한 것은 아닙니다.

키를 알고 있고 정수가 아닌 경우 구조 옵션과 같은 유일한 배열 옵션은 객체입니다.

var i, myarray= {
   "first":"john",
   "last":"doe",
   100:"foo",
   150:"baz"
};
for(i in myarray){
    if(myarray.hasOwnProperty(i)){
        alert(i+" : "+myarray[i]);
    }
}


답변

확실히 말하기에는 약간 극단적입니다

… for 루프를 사용하여 배열을 열거하지 마십시오. 못. 에 대한 오래된 것을 사용하십시오 (var i = 0; i <arr.length; i ++)

?

Douglas Crockford 추출물의 섹션을 강조 할 가치가 있습니다.

… 두 번째 형태는 객체와 함께 사용해야합니다 …

숫자가 아닌 키 대신 이름이 지정된 연관 배열 (일명 hashtable / dictionary)이 필요한 경우이를 객체로 구현해야합니다 (예 🙂 var myAssocArray = {key1: "value1", key2: "value2"...};.

이 경우 myAssocArray.length(이 객체에는 ‘길이’속성이 없기 때문에) null이 i < myAssocArray.length되며 멀리 가지 않습니다. 배열 키는 유용한 속성 (예 : 배열 멤버의 ID 속성 또는 이름)이 될 수 있기 때문에 더 큰 편의성을 제공하는 것 외에도, 연관 배열은 많은 상황에서 성능 이점을 제공 할 것으로 예상됩니다. 배열을 반복해서 평가하여 원하는 배열 항목을 찾습니다.

어쨌든 JSLint 오류 메시지에 대한 설명 덕분에 무수한 연관 배열을 통해 간섭 할 때 ‘isOwnProperty’확인을 사용합니다!


답변

이는 hasOwnProperty 메소드를 사용하여 evtListeners의 특성을 필터링해야 함을 의미합니다 .