[scope란]
- 변수의 범위를 말함
- 전역변수 / 지역변수로 구분됨
[자바스크립트 scope 특징]
- 자바스크립트 만의 변수 범위가 있음
- 자바스크립트는 c-family 언어(block-level scope : 코드블럭( { .... } )내에서 유효함)와 다른 스코프를 가지고 있음
1 2 3 4 5 6 7 8 | int getSum(int a, int b) { int sum = a + b; /* sum은 해당 코드 블럭 내에서만 유효함 (굳이 sum은 필요없지만 보여주기위해) */ return sum; } | cs |
- 자바스크립트는 function-level scope임
=> 코드 블럭과는 상관없이, function(함수) 내 정의된 변수는 함수 내에서만 사용가능함
1 2 3 4 5 6 7 | var x = 0 { console.log(x) // 0, block-scope였다면 undefined였겠지만.... var x = 1; console.log(x) // 1 } console.log(x) // 1, 코드 블럭( { .... } )과 전혀 상관없음 | cs |
- ECMA6부터 let 키워드를 사용하면 block-scope level variable 사용가능
1 2 3 4 5 6 7 8 | var x = 0 { let x = 2 // let 키워드로 block-level scope로 변경 console.log(x) // 2, 위에 선언된 x는 더이상 function-level의 x가 아님 } console.log(x) // 0 | cs |
[자바스크립트 변수 scope 종류]
1) 전역변수(global variable)
- function(함수) 밖의 글로벌영역에 선언하면 됨
- 전역변수는 전역객체(window)의 속성임
1 2 3 4 5 6 7 8 9 10 11 12 | var global = 'global' function myFunction(){ console.log(global) // 'global' var local = 'local' console.log(local) // 'local' } console.log(global) console.log(local) // Uncaught ReferenceError 발생(참조할 값이 없음) | cs |
2) Non block-level scope
- 자바스크립트는 c-family 언어와 달리 코드 블럭( { ... } )에 스코프 영향을 받지않음
- 코드 블럭에 선언했다하더라도 글로벌영역으로 인식하여 전역변수로 선언됨
1 2 3 4 5 6 | { var x = 1; console.log(x) // 1 } console.log(x) // 1, 코드 블럭( { .... } )과 전혀 상관없음 | cs |
3) function-level scope(function variable == local variable)
- 자바스크립트 scope 특징
- 함수 내에서 정의된 함수는 함수 내에서만 사용됨(지역변수)
- 전역변수와 함수 내 선언된 변수명이 같을 경우 지역변수에 우선순위를 두고 참조함
1 2 3 4 5 6 7 8 9 10 11 12 | var a = 10; var c = 30; var myfunction = function(){ var b = 20; var c = 100; console.log(c) } console.log(a) // 10 myfunction() // 100 console.log(b) // Uncaught ReferenceError | cs |
- 내부 함수의 경우 내부함수를 감싸고 있는 외부함수의 변수를 참조할 수 있음
=> 유용한 방법이라고 함, 앞으로 포스팅에서 관련해서 다룰 것
1 2 3 4 5 6 7 8 9 10 11 12 | function external() { var x = 100 // var라는 키워드가 새로운 변수를 만들고 값을 참조하는 것을 뜻함 function internal() { console.log(x) } internal() } external() // 100, 오류나지않고 참조됨 | cs |
- var 키워드로 새로 생성하지않고, 전역변수를 참조하여 전역변수 값 변경 가능함
=> 앞서까지는 전역변수와 지역변수의 차이를 보이기위해 변수명은 같지만 새로운 변수를 선언한 것
=> 지금은 변수명으로 값을 가져오고, 값을 변경하는 것임
=> 물론 함수 내에서 전역변수를 가져오는 것은 당연히 됨
=> 지역변수에서 새롭게 선언한 변수는 전역에서 사용 불가지만, 함수 내에서 전역변수를 수정하는 것은 된다는 것
1 2 3 4 5 6 7 | var x = 100 function myfunction(){ x = 200 } console.log(x) // 200 | cs |
4) 암묵적 전역변수(implied global)
- 함수 내에서 변수를 선언할 때 var 키워드를 사용하지않으면됨
- var 키워드가 새로운 변수를 생성할 때 사용하는 키워드라는 것을 잊지말 것
1 2 3 4 5 6 7 | var x = 100 function myfunction(){ x = 200 } console.log(x) // 200 | cs |
5) 호이스팅(hoisting)
- var 구문이나 function 선언문을 해당 스코프 맨위로 올리는 것을 말함(최상위 선언)
- 원인 : 변수생성과 값 초기화를 분리해서하기때문에(자세한 것은 다음 공부 후 포스팅할 것, 자바스크립트 엔진 내부 동작)
=> 코드를 실행하기 전 호이스팅을 함, 이후 코드 실행
- 자바스크립트 코드는 모두 호이스팅을 함
- 함수선언식(기명함수)은 함수 호이스팅 : 맨 뒤에 함수선언식으로 선언을 해도 맨 앞에서 호출 가능
=> 스크립트가 로딩 되는 시점에 초기화를 함, 코드를 실행할 때는 이미 초기화가 되어있음
1 2 3 4 5 6 | foo() // 100 function foo() { var x = 100 console.log(x) } | cs |
- 함수표현식(익명함수)은 변수 호이스팅
=> 런타임 시점에 함수를 해석하여 실행함
1 2 3 4 5 6 | foo() //Uncaught TypeError var foo = function(){ var x = 100 console.log(x) } | cs |
6) 변수명의 중복
- 서로 다른 js 파일이 있음(a.js, b.js)
- 각각의 파일에 선언된 변수명이 같고, 모두 전역변수임
- 게다가 같은 변수명을 호출하는 루프문이 돌고 있음
=> 무한루프문에 빠지기 쉬움
=> 아주 극단적인 예이지만 피해야할 것들을 알아둘 것
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* a.js */ function foo(){ i = 0 } /* b.js */ var a = 0 for(var i=0; i<10; i++){ foo() /* for은 i도 전역변수이기때문에 foo()가 계속해서 0으로 초기화 그 결과 무한루프가 돔 */ console.log(i) } | cs |
- 변수명을 짤 때 무의미하게 짜지 않기
- 전역변수는 딱 필요한 부분에서만 선언하기
- 반드시 전역변수가 필요한 것이 아니라면 지역변수 이용하기
=> 속도면에서도..... 중요..!
[함수 전역변수 줄이기]
- 전역변수 남발을 막기위해 어떤이의 제안임
- 전역변수 객체고 필요한 변수를 속성으로 만들고 값을 저장하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var global = { // 객체를 전역변수로 global_variable1: "전역변수1", global_variable2: "전역변수2" } console.log(global.global_variable1) // "전역변수1" var MYAPP = { } /* 객체 내 객체 */ MYAPP.student = { name: "jinbro", num: "2011890031" } console.log(MYAPP.student.name) | cs |
'javascript' 카테고리의 다른 글
[웹 기본개념] 쿠키 (0) | 2017.03.28 |
---|---|
[웹 기본개념] URL / URI / REST API (0) | 2017.03.24 |
[웹 기본개념] HTTP 통신 (0) | 2017.03.21 |
[자바스크립트] 프로토타입 (0) | 2017.03.18 |
[자바스크립트] 함수는 무엇이다 (0) | 2017.03.15 |
댓글