키워드, 블록 스코프 -ECMAScript
글로벌 변수 오해
글로벌 오브젝트에 작성한 변수는 글로벌 오브젝트가 스코프입니다.
글로벌 오브젝트에 작성하여 글로벌 변수라고 부르는 것이지,
글로벌 오브젝트에서 보면 로컬 변수입니다.
var
키워드를 작성하지 않으면 글로벌 변수로 간주한다는 점으로 인해var
키워드를 작성하지 않을 뿐이지 글로벌 변수는 var
키워드를 사용하지 않는다는것이 아닙니다.
글로벌 변수도 var 키워드를 사용하여
var global = “”;
형식으로 작성하는 것이 정확한 작성법입니다.
글로벌 변수는 객체지향 관점에서 보면 단점이라고 할 수 있습니다.function
안에서 글로벌 오브젝트에 작성된 글로벌 변수를 사용할 수는 있지만,
다른 프로그램에서 글로벌 변수 값을 변경 하거나 재사용 할 수도 있는 위험이 있습니다.
이러한 경우는 자칫 오류를 만들게 되어 객체 지향 기본에서 어긋나는 행동입니다.
let 키워드
let
키워드 변수 선언 형태
let sports = “축구”;
let
키워드는 var
키워드의 문제점을 해결하기 위한 것으로
다음과 같은 특징이 있습니다.
- 함수 안에 작성한
let
변수는 함수가 스코프 입니다. - 함수 안에
if(a=b)
{let sports = “축구”}
형태의 코드를 작성했을 때,sports
변수는 함수가 스코프가 아니라if문의 블록{}
이 스코프입니다. - 블록{} 밖에 같은 이름의 변수가 있어도 스코프가 다르므로 변수 각각에 값을 설정할 수 있고 그 변수 값이 유지됩니다.
- 블록{} 안에 블록{}을 계층적으로 작성하면 각각의 블록이 스코프입니다.
- 같은 스코프 안에서 같은 이름의
let
변수는 허용되지 않습니다.
블록 스코프
let
변수를 선언하는 가장 큰 목적은 스코프이며 그중에서도 블록 스코프가 돋보입니다.
블록{} 안과 밖에 변수 이름이 같더라도 스코프가 다르므로 변수가 선언되고 각 변수에 할당된 값이 대체되지 않고 유지됩니다.
1 | let sports = "축구"; |
if
문 앞에 같은 이름의sports
변수가 있지만 블록{}을 기준으로
스코프가 다르므로 각sports
변수에 값이 할당되어“축구”
가“농구”
로 대체되지 않고 각 값이 유지됩니다.
let과 this 키워드
1 | 1. var music = "음악"; //var (this) |
var
키워드는 현재 글로벌 오브젝트의 상태이고this
는 글로벌 오브젝트를 참조하게 되어music
변수 값인 “음악”이 출력됩니다.
let
키워드로 선언,할당한 후this
로sports
값을 출력하면undefined
가 출력됩니다.this
가 글로벌 오브젝트를 의미하여window
오브젝트를 참조하는데window
오브젝트에let
변수가 없다는 것은window
오브젝트에let
변수가 설정되지 않는다는 의미 입니다.
이점이var
변수와let
변수의 차이입니다.
function
function
도 스코프를 가지므로 하나의 블록 스코프입니다.function
안에 선언된 모든 변수가 function
내의 스코프에 속하고function
안에 if 블록{}
은 스코프 안에 스코프를 가지는 계층 구조의 형성입니다.
1 | let sports = "축구", music = "재즈"; |
var
변수와 마찬가지로 함수안에서music
변수를 검색하고,없으면
함수 밖으로 나가 검색합니다. 함수안에music
변수가 있으므로
“클래식”이 출력됩니다.
- 함수안에
sports
변수가 없으므로 함수 밖의sports
값인 “축구”를 출력합니다.
이와 같이 let 변수도 가장 가까운 스코프에 있는 변수를 먼저 사용합니다.
1 | var sports = "축구"; // var sports |
strict
모드에서window.get
과 같이get()
앞의 오브젝트 위치에window
를 작성하면function get()
내의this
가window
오브젝트를 참조합니다.함수 안에
sport
변수가 있으므로 그 값인 “농구”를 출력합니다.window.get()
형태로 호출했으므로this
가window
오브젝트를 참조하여get()
함수 밖의var
변수sports
의 값 “축구”를 출력합니다.undefined
this
가window
오브젝트를 참조하여get()
함수 밖의music
변수를 찾지만music
변수가let
으로 선언되어 있어this
(window 오브젝트)로 참조할 수 없어undefined
가 출력됩니다.
get()과 같이 오브젝트를 지정하지 않고 호출하면 this가 window 오브젝트를 참조하지 않습니다.
sports
는var
변수입니다.var
변수는window
오브젝트 지정과 관계없이 함수 안의 변수를 참조하여
“농구”가 출력됩니다.,3. 에러
window
오브젝트를 작성하지 않고 호출하여this
가window
오브젝트를 참조하지못하고 엔진은 참조할 오브젝트 위치에undefined
를 설정합니다.this
는 참조할 오브젝트 위치에 있는undefined
를 참조하게 되고TypeError
가 발생합니다.
try-catch
try-catch
문에서 try 블록{}
기준으로 블록 스코프를 갖습니다.catch
블록은 스코프를 가지지 않으며 try
블록 스코프에 속합니다.
1 | let sports = "축구"; //try문 밖의 let sports |
try
문블록{}
스코프의sports
값 출력 “농구”try
문 밖의sports
값 출력 “축구”
switch-case
switch-case
문에서 switch
블록이 블록 스코프입니다.switch
안에 case
는 별도의 스코프를 갖지 않으며 switch
스코프에 속합니다.
1 | var count = 1; // switch문의 case1:을 실행하기 위해 count에 1할당 |
for()
for()
문에서 var
변수로 작성하는 것과 let
변수로 작성하는 것에는 큰 차이가 있습니다.
let 변수는 반복할 때 마다 스코프를 갖는 반면, var 변수는 스코프를 갖지 않습니다.
1 | <ul> |
1 | var nodes = document.querySelector("ul"); |
querySelector(“ul”)
으로 html
에 작성된 li
요소 3개를 nodes
변수에 할당합니다.nodes.childern.length
는 NodeList
의 요소 수로 3입니다.for
문을 반복하면서 각 li
요소마다 onclick
이벤트를 설정합니다.
클릭시 배경색을 변경하고 for
문의 K
변수 값을 출력합니다.
어떤 li
요소를 클릭하더라도 콘솔에 K
값 3이 출력되며 3이 K의 최종값 입니다.
클릭한 li
요소에 해당하는 K변수 값
을 출력하고 싶다면let
변수를 사용하면 됩니다.
let
1 | var nodes = document.querySelector("ul"); |
li
요소를 클릭하면 onclick
이벤트를 설정했을 때 사용한 K변수 값
을 출력합니다. 0,1,2
이는 let
변수가 스코프를 갖기 때문입니다.
const
const
변수에 할당된 값은 상수가 됩니다.
상수는 재할당 할 수 없으며 재선언 할 수도 없습니다.
const
변수는 선언-초기화-할당을 한번에 합니다.
즉, const a;
처럼 선언만 해놓을 수 없습니다. 반드시 const a = 0;
처럼 초기값을 할당해 줘야 합니다.
상수 선언에는 대소문자 모두 사용할 수 있지만, 일반적인 관습은 모두 대문자를 사용하는 것입니다.