2012-10-09 5 views
2

가능한 중복 :
JavaScript Variable Scope간단한 포인트 - 자바 스크립트

나는 자바 스크립트 꽤 새로운 (명백하게) 오전, 나는에 대한 다른 스레드에서 몇 가지 다른 점을 보았다 글로벌 변수와 로컬 변수의 사용법에 대해 설명 하겠지만 주제에 대한 기본 사항을 한 곳에서 잠그려고합니다.

다음은 기능의 외부 (또는 내부에서 사용되는)로 선언 된 것의 차이점은 무엇입니까?

var thing = 1;

건 = 1;

var를 사용하면 변수가 현재 범위에 있음을 알게된다는 것을 알고 있습니다. 따라서 var를 제거하면 전역이됩니다. 나타날 수있는 몇 가지 함정은 무엇입니까? 누군가 변수를 서로 밟을 수있는 간단한 예제를 줄 수 있습니까?

미리 감사드립니다.

+3

이 링크를 통해 이동하십시오. 그것은 분명 도움이 될 것입니다 : - http://stackoverflow.com/questions/500431/javascript-variable-scope –

+0

'var'을 사용하지 않고 코드를 작성해보십시오. 조만간 함정을 발견 할 것입니다. –

+1

@RahulTripathi 링크를 사용해 주셔서 감사합니다. http://stackoverflow.com/questions/6628209/global-local-variables-in-javascript 및 http://stackoverflow.com/questions/1276095/javascript-local-vs-global과 같은 몇 가지 다른 스레드를 검색했지만 그런 목록은 가지고있는 것이 좋다 – Benny

답변

2
  1. 는 차이점은 두 for 루프를 가지고 상상 그

  2. 에 대해 걱정할 필요가 없습니다 너무 작고, 당신이 뭔가를하고 싶어 그들과 함께.

.

for (i = 0; i < elements.length; i++) { 
    element = elements[i]; 
    for (i = 0; i < items.length) { 
     item = items[i]; 
     element.add(item); 
    } 
} 

이 의사 코드 조각은 여러 언어로 잘 작동합니다. 프로그램은 inner-loop와 outer-loop를 볼 것이고, i은 같은 것을 언급하지 않는다고 말할 수 있습니다.

JavaScript에서는 동일합니다. i.
다른 언어가 블록 범위를 가지고 있기 때문에 - 새로운 중괄호를 입력 할 때마다 프로그램은 새로운 것과 같이 변수를 처리합니다. 자바 스크립트

내부 기능 변수 신규로 취급되는 것을 의미에서만 작동 범위가 있지만, 제어 명령 (if, for, switch)의 내부들은 동일한 값을 가진 동일한 변수입니다.
그래서 외부 루프는 i을 0으로 설정하고 내부 루프로 들어갑니다.
내부 루프는 항목의 목록을 모두 통과하고,
그런 다음이 외부 루프로 돌아갑니다 ... 잘 지내까지 i을 구축하고, 그 이하 elements.length을의 경우 i 여전히 items.length - 1 ...
동일 그러면 items 길이보다 더 높은 i에 하나가 더해 지므로 더 이상 내부 루프에서는 아무 것도 일어나지 않습니다 ...
... items.lengthelements.length보다 큰 경우, 외부 루프는 한 번에 끝나면 끝납니다 .

지금, 나는 당신이 당신이 x 또는 name 또는 value 또는 el 또는 sum 또는 i 또는 default 또는 src 또는 url 또는 img 또는 script 등 여러 번 사용할 수있는 위치 시간에 대해 생각하기 시작 수 있다는 확신 전체 프로그램 (심지어 수만 줄, 심지어), 그리고 위의 루프와 같은 상황에 대해 생각하기 시작할 수 있습니다. 동일한 이름으로 서로 다른 두 가지를 호출하면 문제가 발생할 수 있습니다.

이 같은 문제가 VAR-위해 fallthrough 하나 x라는 변수를 사용하여 기능과 x라는 또 다른 변수를 사용하는 다른 기능이있는 경우

, 좋아요 ... .. 변수를 선언하는 것을 잊지 않는 한.

// no problems! 
function func1() { var x = 0; } 
function func2() { var x = "Bob"; } 

// big problems! 
function func1() { x = 0; } 
function func2() { x = "Bob"; } 

func1window.x = 0; func2

window.x = "Bob"; 세트 ...window.x이 42와 같다고 가정하면 다른 프로그램이 올바로 작동하기 때문에 이제는 누락 된 var이 있기 때문에 깨진 앱이 3 개있을 가능성이 있습니다.

그러나 전역 변수를 즉시 설정하지는 않습니다. 실제로 그것이하는 일은 기능 체인을 통과하는 것입니다. 다른 함수 안에 함수를 만들면 선언되지 않은 var가 부모의 변수, 그 다음에 조부모의 변수 및 그 다음에있는 증조부의 변수를 찾습니다.
window에 도달하면 아무도 var을 입력하면 window에 그 이름을 가진 이름을 만듭니다. 당신이 FUNC1를 호출 할 때

function func1() { 
    var x = 0; 

    function func2() { 
     var y = 1; 
     x = 2; 
     z = 3; 
    } 

    func2(); 
} 

, 그것은 x 0으로 자신을 설정하고 FUNC2를 호출합니다. FUNC2가 z이없고 FUNC1이 z이없는 zwindow이 없기 때문에 FUNC2이, 그리고 자신의 y 1. 그 다음은 설정에서 func1의 x 2. 로 설정, 그것은 3

window.z을 설정

이것은 혼란의 시작일 뿐이며, 왜 그 함수의 내부에서 (그리고 그 함수 내부에서 생성 된 함수 내에서) 사용할 수 있어야하는 변수를 정의하고 있는지를 확인하는 아주 좋은 아이디어입니다. .. ... 기존의 변수를 참조 할 때는 코드를 신중하게 참조하고 코드에서 정의 된 변수의 위치를 ​​알아야합니다 (정의 된 함수 ... ... s o 체인에서 프로그램이 끝나기 전에 어디에서 프로그램이 종료 될지, 다른 기능의 내부에서 변경하는 이유는 무엇입니까?

+0

이것은 훌륭한 대답입니다. 감사! – Benny

1

일반적인 함정은 루프 카운터입니다. 항상 카운터 이름은 i이며 충돌합니다. 예 : 많은 C 스타일의 언어와는 달리

function a() { 
    for (i = 0; i < 5; i++) 
     b(); 
} 
function b() { 
    for (i = 0; i < 3; i++) 
     ; // something 
    // now, the /global/ i is reset to 3 
    // … and the condition in function a will never be met 
} 
// so 
a(); 
// is an infine loop instead of executing something 15 times 
+0

아직도이 물건을 혼자서 생각하기 위해 올바른 뇌 경로를 만들려고 노력합니다. 예를 들어 주셔서 감사합니다. – Benny

0

는 자바 스크립트 블록 구문을 지원하지만 블록 범위를 지원하지 않기 때문에 당신이 예상하는대로 다음이 실행되지 않을 수 있습니다 : 이것은 또한 분명하다

var foo = 'bar'; 

{ 
    var foo = 'baz'; 
} 

console.log(foo); // 'baz' 

다른 자바 스크립트 if 같은 지원하는 블록을 구축 :

var foo = 'bar'; 

if (true) { 
    var foo = 'baz'; 
} 

console.log(foo); // 'baz' 

을 또한, BERGI가를 들어, i 카운터를 지적for이 새 범위를 만들지 않기 때문에 서로 무시합니다.

Crockford는 자바 스크립트의 블록 범위가 부족한 것으로 간주합니다. "Awful Part"입니다. 대신, 자바 스크립트는 lexical scoping 그렇게 만 기능이 새로운 범위를 만들 것 같습니다

var foo = 'bar'; 

(function() { 
    var foo = 'baz'; 
    console.log(foo); // 'baz' 
}()); 

console.log(foo); // 'bar' 

자바 스크립트의 모든 기능을 포함하는 함수에서 변수에 액세스 할 수 있습니다; 내부는 외부에 대한 액세스 권한을 가지지 만 그 반대는 아닙니다. 위 예제의 경우 IIFE (즉시 호출 된 함수 표현식)은 전역 범위에 정의 된 foo = 'bar';에 액세스 할 수 있지만 대신 foo을 로컬 var 선언으로 다시 정의하고 'baz'과 같게 설정합니다.

보너스 포인트 : 당신이 정말로 블록 범위를 원하는 경우

var foo = 'bar'; 

with ({foo: 'baz'}) { 
    console.log(foo); // 'baz' 
} 

console.log(foo); // 'bar' 

크록 포드 discourages with 인해 그 모호성하지만, 나는 아무런 해를 볼 : Shog9는 with 지금과 같은 객체 리터럴로 블록 범위를 시뮬레이션 할 수 있다는 것을 발견 with 해결 방법.이미 전역 범위에있는 경우