JavaScript의 "for-in"루프에 "var"또는 "var"없음?


99

for-inJavaScript 에서 루프 를 작성하는 올바른 방법은 무엇입니까 ? 브라우저는 내가 여기에서 보여주는 두 가지 접근 방식 중 하나에 대해 불만을 제기하지 않습니다. 첫째, 반복 변수 x가 명시 적으로 선언 되는 다음 접근 방식이 있습니다 .

for (var x in set) {
    ...
}

그리고 대안으로 더 자연스럽게 읽지 만 나에게 맞지 않는이 접근 방식 :

for (x in set) {
    ...
}

번들 파일 생성 웹팩가 for 루프에서 오류를 일으키는 이유를 해결할 때 그냥이 게시물에 건너 온 var반복자를 선언하는 데 사용되지 않았습니다 i: Uncaught ReferenceError: i is not defined. 그래서 지금부터 사용하겠습니다 : / webpack은 "전역"변수를 이상하게 취급합니다. 자세한 내용은 다음을 참조하십시오. stackoverflow.com/a/40416826
user1063287

답변:


103

를 사용 var하면 변수의 범위가 줄어 듭니다. 그렇지 않으면 변수가 var문을 검색하는 가장 가까운 클로저를 찾습니다 . 를 찾을 수 없으면 var전역입니다 (엄격 모드에있는 using strict경우 전역 변수에서 오류가 발생 함). 이로 인해 다음과 같은 문제가 발생할 수 있습니다.

function f (){
    for (i=0; i<5; i++);
}
var i = 2;
f ();
alert (i); //i == 5. i should be 2

당신이 작성하는 경우 var i루프에 대한 경고 쇼에 2.

자바 스크립트 범위 지정 및 호이 스팅


4
질문에 대답하지 않습니다. 이것은 in을위한 것이 아니라 정상적인 for 루프를위한 것입니다.
IllidanS4는 Monica가

i == 5 이유는 for 루프의 var 부족보다 호이 스팅 때문이 아닙니까?
Snekse 2013

1
이것에 대한 또 다른 중요한 측면은 엄격 모드가 gobal 속성의 암시 적 생성을 금지하므로 var 문없이 표준 "for in"루프를 사용하면 실제로 실패하고 ReferenceError를 반환한다는 것입니다.
dkugappi

2
그러나 Java에서 왔을 때 머리 var안쪽에 넣는 for것은 for 루프에서 로컬처럼 보이지만 그렇지 않습니다. 따라서 아래 user422039의 스타일을 선호합니다.
njlarsson

2
하나의 범위에 둘 이상의 for 루프가있는 경우 어떻게됩니까? 인덱스를 재사용해야하거나 (var 없음) 다시는 사용하지 않을 새 변수 (j, k, l, m,…)를 많이 선언해야합니다.
armin

40

첫 번째 버전 :

for (var x in set) {
    ...
}

라는 지역 변수를 선언합니다 x. 두 번째 버전 :

for (x in set) {
    ...
}

하지 않습니다.

경우 x(당신이 가지고 즉, 이미 지역 변수 var x;또는 var x = ...;어딘가에 이전 현재 범위 (즉, 현재 함수)) 그들은 동등 할 것이다. x가 아직 지역 변수가 아닌 경우 두 번째를 사용하면 암시 적으로 전역 변수를 선언합니다 x. 이 코드를 고려하십시오.

var obj1 = {hey: 10, there: 15};
var obj2 = {heli: 99, copter: 10};
function loop1() {
    for (x in obj1) alert(x);
}
function loop2() {
    for (x in obj2) {
        loop1(); 
        alert(x);
    }
}
loop2();

당신이 경고에이를 기대할 수 hey, there, heli, hey, there, copter,하지만 이후 x하나가 알려드립니다 동일 hey, there, there, hey, there, there. 당신은 그것을 원하지 않습니다! 루프 var x에서 사용하십시오 for.

무엇보다도 for루프가 전역 범위 (즉, 함수가 아님)에있는 경우 로컬 범위 ( x를 사용하는 경우 범위 가 선언 됨 var x)는 전역 범위와 동일합니다 (범위 x는에서 암시 적으로 선언 됨). xvar없이 사용 하는 경우 ) 두 버전이 동일합니다.


3
마지막으로 설명과 좋은 예가 담긴 완전한 대답. 그리고 그것은 정말로 질문에 답합니다.
IllidanS4는 Monica가

22

항상var ,로 지역 변수를 선언해야합니다 .

당신이하고 싶은 일이 확실하지 않다면 "for ... in"루프를 사용해서는 안됩니다. 실제 배열 (매우 일반적 임)을 반복하려면 항상 숫자 인덱스가있는 루프를 사용해야합니다.

for (var i = 0; i < array.length; ++i) {
  var element = array[i];
  // ...
}

"for ... in"을 사용하여 일반 배열을 반복하면 루프가 숫자 인덱스 외에 배열의 속성을 선택할 수 있으므로 예기치 않은 결과가 발생할 수 있습니다.

편집 — 2015 년 .forEach()에는 배열을 반복하는 데 사용 하는 것도 좋습니다 .

array.forEach(function(arrayElement, index, array) {
  // first parameter is an element of the array
  // second parameter is the index of the element in the array
  // third parameter is the array itself
  ...
});

.forEach()메서드는 IE9부터 Array 프로토 타입에 있습니다.


12

실제로 for제목 내 선언이 마음에 들지 않으면 다음을 수행 할 수 있습니다.

var x;
for (x in set) {
    ...
}

이 질문에 대한 다른 답변에서 언급했듯이 전혀 사용하지 않으면 var전역 속성 할당과 같은 불필요한 부작용이 발생합니다.


9

로 루프 변수를 선언하는 곳을 사용하십시오 var. 암시 적으로 선언 된 변수에는 의도 한 것과 다른 범위가 있습니다.


9
for(var i = 0; ...)

일반적으로 보이는 패턴이지만

for(int i; ...)

변수가 for블록으로 범위가 지정되지 않는다는 점에서 C ++에서 . 실제로 루프가 시작 되기 전 (현재 스코프 / 기능이 시작된 후)과 그 후에 var로컬 i이 효과적으로 사용 가능 하도록 둘러싸는 스코프 (함수)의 맨 위로 올라갑니다 for.

즉, 다음을 수행합니다.

(function(){ //beginning of your current scope;
 //...
 for(var i in obj) { ... };
})();

와 같다:

(function(){ //beginning of your current scope;
 var i;
 //...
 for(i in obj) { ... };
})();

ES6에는 범위를 for 블록으로 제한 하는 let키워드 (대신 var)가 있습니다.

물론 암시 적 전역 변수보다는 지역 변수 ( var또는 let또는 const(ES6에서)로 선언 된 변수)를 사용해야 합니다.

for(i=0; ...)또는 (필요한대로) 사용하고 선언 for(i in ...)하지 않으면 실패합니다 ."use strict";i



4

나는 var가 성능상의 이유로 좋다고 생각합니다.

Javascript는 x가 이미 다른 곳에 있는지 확인하기 위해 전체 전역 범위를 조사하지 않습니다.


3

일반적인 관점에서 첫 번째 버전은 루프의 범위 내에 있어야하는 인덱스에 대한 것이고 다른 하나는 루프의 생성자가 호출 된 범위의 모든 변수 일 것입니다.

for 루프 내에서 루프의 인덱스를 사용하고 다음 줄에서 다른 사용자에게 필요하지 않은 경우 "var"로 변수를 선언하는 것이 좋습니다. 그러면 "x"가 for 루프의 인덱스가 0으로 초기화되었는지 확인합니다. 반면 다른 하나는이 컨텍스트에서 다른 "x"변수를 사용할 수있는 경우 루프의 인덱스로 덮어 쓰게됩니다. 즉, 논리적 오류가 발생합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.