변수는 선언 위치(전역 또는 지역)에 의해 Scope를 가지게 된다. 즉 전역에서 선언된 변수는 전역 Scope를 갖는 전역 변수이고, 지역(자바스크립트의 경우 함수 내부)에서 선언된 변수는 지역 Scope를 갖는 지역 변수가 된다.
전역 Scope를 갖는 전역 변수는 전역(코드 어디서든지)에서 참조할 수 있다. 지역(함수 내부)에서 선언된 지역 변수는 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다.
javascript는 함수 코드블럭만 지역Scope로 인식하며, 그 외는 전역 Scope이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
var x = 0; // global { var x = 1; // global console.log(x); // 1 } console.log(x); // 1
let y = 0; // global { let y = 1; // local console.log(y); // 1 } console.log(y); // 0
let은 block-level-scope를 지원한다.
1. Global scope
전역 변수는 전역 객체 window의 프로퍼티이다.
1 2 3 4 5 6 7 8 9 10 11 12
varglobal = 'global'; // 전역 변수
functionfoo() { // 전역 함수 var local = 'local'; // this로 선언하면 함수외부에서도 참조가가능하다 but var는 안된다. console.log(global); console.log(local); } foo();
console.log(global); // window.global을 해도 같은 값이 나온다. 편의상 없앴다. console.log(local); // Uncaught ReferenceError: local is not defined
함수내부에 this로 선언한 변수들은 public 외부에서 참조가 가능하며 var로 선언한 변수들은 private하여 외부에서 참조가 불가능하다.
2. Non block-level scope -> Function-level scope
1 2 3 4
if (true) { var x = 5; // function이 아니니깐 global하다. } console.log(x); // 5가 나온다.
3. Function scope
1 2 3 4 5 6 7 8
var a = 10; // 전역변수
(function () { // IIFE 즉시실행함수이다. var b = 20; // 지역변수 })();
console.log(a); // 10 console.log(b); // "b" is not defined
자바스크립트는 function-level scope를 사용한다. 즉 함수 내에서 선언된 매개변수와 변수는 함수 외부에서는 유효하지 않다. 따라서 변수 b는 지역 변수이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
var x = 'global';
functionfoo() { var x = 'local'; console.log(x);
functionbar() { // 내부함수 console.log(x); // local }
bar(); } foo(); console.log(x); // global
Scope 체이닝이 발생한다. = 실행 컨텍스트
내부함수는 자신을 포함하고 있는 외부함수의 변수에 접근할 수 있다. 이는 매우 유용하다. 클로저에서와 같이 내부함수가 더 오래 생존하는 경우, 타 언어와는 다른 움직임을 보인다.
1 2 3 4 5 6 7 8 9
var x = 'global';
functionfoo() { var x = 'local'; console.log(x); }
foo(); // local console.log(x); // global
1 2 3 4 5 6 7 8 9 10
var x = 10;
functionfoo() { x = 100; console.log(x); } foo(); // 100 console.log(x); // 100 Q. 왜 100인가요?? 숫자는 지역값을 가져오나요? // A. 내부함수에 var가아닌 전역으로 선언해서 그렇다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
var foo = function () {
var a = 3, b = 5;
var bar = function () { var b = 7, c = 11; // 이 시점에서 a는 3, b는 7, c는 11 a += b + c; // 이 시점에서 a는 21, b는 7, c는 11 }; // 이 시점에서 a는 3, b는 5, c는 not defined bar( ); // 이 시점에서 a는 21, b는 5 -> a가 참조되어서 bar안에서 변경되서 a=21이며 b는 내부함수껏을 사용못하니깐 5이다.