[javascript] JavaScript 변수는 외부 또는 내부 루프를 선언합니까?

AS3에서는 성능 향상을 위해 루프 외부의 모든 변수를 초기화해야한다고 생각합니다. JavaScript에서도 마찬가지입니까? 어느 쪽이 더 좋고 / 빠른 / 가장 좋은 방법입니까?

var value = 0;

for (var i = 0; i < 100; i++)
{
    value = somearray[i];
}

또는

for (var i = 0 ; i < 100; i++)
{
    var value = somearray[i];
}



답변

없습니다 차이 절대적으로 자바 스크립트 또는 ActionScript의 의미 나 성능은.

var파서에 대한 지시문이며 런타임에 실행되는 명령이 아닙니다 . var함수 식별자 (*)에서 특정 식별자가 한 번 이상 선언 된 경우 블록에서 해당 식별자의 모든 사용은 로컬 변수를 참조합니다. 루프 내부, 루프 외부 또는 둘 다에 value선언 되는지 여부 는 차이가 없습니다 var.

결과적으로 가장 읽기 쉬운 것을 작성해야합니다. Crockford에 동의하지 않습니다. 모든 변수를 함수의 맨 위에 두는 것이 항상 가장 좋은 것입니다. 변수가 코드 섹션에서 임시로 사용되는 경우 var해당 섹션에서 선언 하는 것이 더 좋으므로 섹션은 독립형이며 복사하여 붙여 넣을 수 있습니다. 그렇지 않으면 리팩토링하는 동안 관련 코드를 따로 따로 이동하지 않고 몇 줄의 코드를 새 함수에 복사하여 붙여 넣으면 var실수로 글로벌하게됩니다.

특히:

for (var i; i<100; i++)
    do something;

for (var i; i<100; i++)
    do something else;

Crockford는 두 번째를 제거하도록 권장합니다 var(또는 vars를 제거 하고 var i;위 의 작업을 수행 하십시오). 그러나 IMO var는 함수 상단에 여분의 쉽게 잊혀진 코드 비트 를 두지 않고 모든 관련 코드를 함께 유지하면서 두 가지를 모두 유지하는 것이 더 쉽습니다.

개인적으로 필자 var는 독립적 인 코드 섹션에서 변수의 첫 번째 할당으로 같은 함수의 다른 부분에서 동일한 변수 이름을 별도로 사용하는지 여부 를 선언하는 경향이 있습니다. 나에게 var전혀 선언 하지 않는 것은 바람직하지 않은 JS 사마귀이다. JavaScript에서 ANSI C의 [이전 개정] 제한 사항을 복제하는 것이 내 의무로 보지 않습니다.

(* : 중첩 함수 본문 이외)


답변

이론적으로 언어에는 블록 범위가 없으며 함수 범위 만 있기 때문에 JavaScript에서 아무런 차이가 없어야합니다.

성능 인수에 대해서는 확실하지 않지만 Douglas Crockford는 여전히 var함수 문에서 첫 번째 명령문이어야한다고 권장합니다 . JavaScript 프로그래밍 언어에 대한 코드 규약 에서 인용 :

JavaScript에는 블록 범위가 없으므로 블록에 변수를 정의하면 다른 C 계열 언어에 익숙한 프로그래머가 혼동 될 수 있습니다. 함수 상단에 모든 변수를 정의하십시오.

다음 예에서 볼 수 있듯이 그는 요점이 있다고 생각합니다. 함수 상단에 변수를 선언하면 독자가 변수 ifor루프 블록 의 범위에 있다고 생각하는 것을 혼동해서는 안됩니다 .

function myFunction() {
  var i;    // the scope of the variables is very clear

  for (i = 0; i < 10; i++) {
    // ...
  }
}


답변

ECMA-/Javascript언어 hoists기능의 정상에 어디 선언 된 모든 변수입니다. 이 언어가 있기 때문이다 않는function scope와 않습니다 하지block scope다른 언어 C와 같은처럼.
이라고도합니다 lexical scope.

당신이 같은 것을 선언하면

var foo = function(){
    for(var i = 0; i < 10; i++){
    }
};

이것은 hoisted:

var foo = function(){
    var i;
    for(i = 0; i < 10; i++){
    }
}

따라서 성능에 아무런 차이가 없습니다 (그러나 여기서 완전히 틀렸다면 정정하십시오). 함수의 최상위가 아닌 다른 곳에서 변수를 선언 하지 않는
훨씬 더 좋은 주장 은 가독성 입니다. 내에서 변수를 선언하면 이 변수가 아니라 루프 본문 내에서 액세스 할 수 있다는 잘못된 가정으로 이어질 수 완전히 잘못 . 실제로 현재 범위 내 어디에서나 해당 변수에 액세스 할 수 있습니다.for-loop


답변

내년에는 모든 브라우저에 코드를 사전 컴파일하는 JS 엔진이 있으므로 성능 차이 (동일한 코드 블록을 반복해서 구문 분석하고 할당을 실행함으로써 발생)는 무시할 수있을 것입니다.

또한 필요한 경우가 아니면 성능을 최적화하지 마십시오. 변수를 처음 필요한 곳에 가깝게 유지하면 코드를 깨끗하게 유지할 수 있습니다. 부정적인 측면에서, 블록 범위를 가진 언어에 익숙한 사람들은 혼란 스러울 수 있습니다.


답변

우리가 지금 let그리고 constES2015에서 또 다른 고려 사항 은 변수를 루프 블록으로 구체적으로 범위 지정할 수 있다는 것입니다. 따라서 루프 외부에서 동일한 변수가 필요하지 않은 경우 (또는 각 반복이 이전 반복에서 해당 변수에 수행 된 작업에 의존하는 경우) 다음을 수행하는 것이 좋습니다.

for (let i = 0; i < 100; i++) {
    let value = somearray[i];
    //do something with `value`
}


답변

방금 Chrome에서 간단한 테스트를 수행했습니다. 브라우저 에서 바이올린 을 시도하고 결과를 확인하십시오

  var count = 100000000;
    var a = 0;
    console.log(new Date());

    for (var i=0; i<count; i++) {
      a = a + 1
    }

    console.log(new Date());

    var j;
    for (j=0; j<count; j++) {
      a = a + 1;
    }

    console.log(new Date());

    var j;
    for (j=0; j<count; j++) {
        var x;
        x = x + 1;
    }

    console.log(new Date());

결과는 마지막 테스트에 ~ 8 초가 걸리고 이전 2 개는 ~ 2 초에 불과합니다. 순서에 관계없이 매우 반복적으로.

그래서 이것은 나에게 증명합니다. 루프 외부에서 항상 변수를 선언해야합니다. 궁금한 점 i은 for () 문에서 선언 한 첫 번째 사례 입니다. 이것은 인덱스를 미리 선언 한 두 번째 테스트만큼 빠르다.


답변

JavaScript는 C 또는 C ++로 맨 아래에 작성된 언어이므로 어떤 언어인지 잘 모르겠습니다. 그리고 그 목적 중 하나는 내부 메모리 처리의 노력을 절약하는 것입니다. C 또는 C ++에서도 변수가 루프 내에서 선언 될 때 많은 리소스를 소비할지에 대해 걱정할 필요가 없습니다. JavaScript로 왜 걱정해야합니까?