(자알쓰) Scope Part. 2

자알쓰란?

바스크립트 자. (잘 쓰자는 의미도 담겨있다.)
자바스크립트라는 언어 자체는 내 기준에서는 설계 상 미스가 참 많다.
함수 단위의 스코프, 호이스팅, 동적 타입 등등
자바와 같은 깐깐(?)한 언어를 배우고 바라본 자스는 허점 투성이처럼 보였다.
애초에 자바스크립트는 어떠한 프로그램을 만들기 위해서 탄생했다기 보다는
웹 페이지에 입력값에 대한 유효성 검사(데이터가 공란인지 아닌지 등등)와 같은
페이지의 동적 제어가 주된 목적 + 짧은 개발 기간(넷 스케이프 사의 새로운 브라우저에 탑재 예정) 때문에
설계 상에 미스가 있을 수 밖에 없다고 나는 생각된다.
일종의 안전 장치가 없어서 개발자가 일일이 구현해주고, 신경써야 하는 느낌이었다.
그렇다고 해서 자바스크립트를 극혐하거나 그런 것은 아니고 매우 사랑한다.
또한 그 허점을 아는 사람은 허점을 보완해서 요리조리 피해서 잘 쓰겠지만…
잘 모르는 부분들은 잘못 써도 동작이 잘 되기 마련이다.
이는 지금 당장에는 큰 문제가 안 될지 모르겠지만, 추후에 대규모 웹 어플리케이션을 만들거나
직면할 문제로부터 미리 해방시키기 위해 처음부터 좋은 습관을 들여가는 것이 좋다고 생각한다.
그 네 번째 시리즈는 ES2015+의 Scope(스코프)를 주제로 진행하겠다.
일단 ES5 이하에서 스코프를 읽고 오길 바란다.

ES5와의 차이점

ES2015+ 들어서 변수를 선언할 때 const와 let이 추가되었다.
이에 대한 설명은 추후 포스트에서 정리할 예정이다.
ES2015+를 쓴다 하더라도 var를 쓰면 큰 차이점이 없다.
var와 const, let을 비교해보자.

1
2
3
4
const a = 1;
var b = 2;
// const와 let은 window 객체의 프로퍼티에 할당되지 않는다.
console.log(window.a, window.b); // undefined 2

블록 단위의 스코프

ES5의 var는 함수 단위의 스코프라고 얘기했다.
블록은 {} 요 구문을 뜻 하고 요 안에서만 변수가 살아 숨쉰다고 보면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// for문 - ()와 {}을 포함 - 에서 선언한 변수 i가
// for 문 밖에서도 살아 숨쉬고 있다.
for(var i=0; i<10; i++) {}
console.log(i); // 11

// var와는 달리 let은 for문 안에서 선언했으면
// for 문 외부에서는 참조가 불가능하다.
for(let j=0; j<10; j++) {}
console.log(j); // j is not defined

// for 문 외부에서 선언해야 for 문 외부에서도 사용이 가능하다.
let k = 0;
while(k++ < 10) {}
console.log(k); // 11


// {}으로 명시적으로 스코프를 만들 수도 있다.
// 이 다음 모듈화 포스트에 얘기할 즉시 실행함수 패턴과 유사하다고 보면 된다.
{
const a = 1;
console.log(a); // 1
}

{
const a = 2;
console.log(a); // 2
}

ES5와 공통점

이 역시 파일 별로 스코프를 가지는 게 아니라 역시 전역 스코프를 더럽힌다는 단점이 있다.

1
2
3
4
5
// a.js
const a = 2;

// b.js
const a = 3; // Identifier 'a' has already been declared

이를 극복하기 위해 import/export 문법이 있지만 다음 모듈화 포스트에서 다룰 예정이다.