2012-11-29 6 views
6

:재 선언 자바 스크립트 변수

var greeting = "hi"; 

function changeGreeting() { 
    if (greeting == "hi") { 
     var greeting = "hello"; 
    } 

    alert(greeting); 
} 

changeGreeting();​ 

... greeting는 정의되지 않습니다. 그러나 나는 var을 제거하고이에 changeGreeting()을 변경하는 경우 :

function changeGreeting() { 
    if (greeting == "hi") { 
     greeting = "hello"; 
    } 

    alert(greeting); 
} 

을 ... 내가 "안녕하세요"예상대로 얻을.

내 코드에서 이와 같은 변수를 결코 재 선언하지 않겠지 만 왜 이런 일이 발생합니까?

답변

27

JavaScript 변수에는 기능 범위가 있습니다. 따라서 함수 안에 var greeting이 존재하면 로컬 변수 greeting이 선언됩니다.이 변수는 if 조건에서 정의되지 않은 상태로 선언됩니다. 글로벌 변수는 함수 내부에서 보이지 않고 로컬 변수에 의해 가려집니다. 따라서 if이 발생하지 않고 hello에 대한 할당이 발생하지 않으며 변수는 여전히 정의되지 않습니다.

두 번째 예제에서는 전역 변수를 전역 변수로 사용하고 있습니다 (함수 내에 var greeting이 없기 때문에 지역 변수에 의해 가려 짐이 없습니다). 예상대로 작동합니다.

+3

+1 잘 대답하고 명확한 대답. – Aesthete

+0

사실 +1 선생님. –

+0

@bfavaretto :'var greeting'은 에러 였고, var currentSize' 글로벌 변수 선언 (첫 번째 예제에서는 회색 음영으로, 두 번째 예제에서는 회색 음영으로 표시)을 가정했습니다. 그렇지 않으면 예제와 전혀 관련이 없습니다. – Amadan

-1

첫 번째 코드 단편에서 전역 변수를 검사하고 있습니다. 존재하지 않는 경우 - 조건이 충족되면 통과하지 못합니다.

이 자바 스크립트 범위 및 방법 변수와 함께 작동하는 방법에 체크 아웃 Javascript garden - function scopes

+1

첫 번째 스 니펫은 전역 변수를 검사하지 않고 _not_ 함수 본문에는 그 변수의'var' 선언이 포함되어 있습니다.이 변수는 맨 위에 올립니다. 그것은 함수를 반환 한 후에 GC'ed 된 로컬'var currentLength;'<- 정의되지 않은 변수를 검사하고 있습니다. –

+0

아, 맞습니다. 나는 호이 스팅을 완전히 숨겼다 :/ – rdamborsky

6

그것은 매우 간단합니다 : JS 현재 범위의 상단에 변수 선언를 게양하지만, (할당 포함) 작업이 없습니다 물론, (같은 범위 내에서 두 번째 사례 설명을 참조하십시오). 그래서 당신의 조각이 VAR을두면

(function() 
{ 
    var currentSize;//undefined 
    if (currentSize == 'hi')//always false 
    { 
     currentSize = 'hello';//assignment that will never be 
    } 
    alert(currentSize);//alerts undefined, of course 
}()); 

로 번역되어, 범위 스캔을 진행 (전역 범위에서 선언되는 변수에 대한 확인). 슬프게도 이렇게하면 var의 첫 번째 사용 컨텍스트가 손실되고 (브랜치 내부에서) 할당이 발생합니다. 암시 된 세계는 으로 번역됩니다.
감사합니다. 사실이 아닙니다. 나는 이것을 확신했다. 콘솔에서 콘솔의 두 가지를 테스트했기 때문에 이것을 가정했다. 이 경우 @amadan이 옳다. 전역 변수 (이것을 게시했을 때 실수로 스 니펫에 greeting이라고 부름)를 사용하고있다. JS에서 스코프/스코프 스캐닝을 이해할 때 누군가 도움이되기를 바라는 바, 전역 변수가 실제로 무엇인지 보여주기 위해 코드를 아래의 코드 (수정)로 남겨 둘 것입니다.

var currentSize = 'hello'; 
//well, actually implied globals can be deleted, so it's more like 
Object.defineProperty(this,'currentSize',{value:undefined, 
              writable:true, 
              enumerable:true, 
              configurable:true}); 
(function() 
{ 
    if (currentSize == 'hi')//always false 
    {//this still doesn't get executed 
     currentSize = 'hello';//assignment that will never be 
    } 
    alert(currentSize);//alerts undefined 
}()); 
+0

변수 범위에 대한 정중하게 설명 된 답변 JS에서 변수 범위에 대한 나의 개념을 수정하기 위해 많은 것을 배웠다. –