출처 : http://blog.naver.com/PostView.nhn?blogId=tkandrea92&logNo=90028329412&categoryNo=9&parentCategoryNo=0&viewDate=&currentPage=1&postListTopCurrentPage=&userTopListOpen=true&userTopListCount=5&userTopListManageOpen=false&userTopListCurrentPage=1

 

 

세상에서 가장 많이 쓰이는 언어를 꼽으라면 C, C++, 자바이다. 그리고 자바스크립트를 빼놓을 수 없다. 특히 자바스크립트는 최근 Ajax 프로그래밍 열풍과 각종 위젯 제작 언어로 각광을 받으면서, 제2의 부흥기를 맞이했다. 아이러니 한 것은 이런 대중성에도 불구하고 세상에서 가장 잘못 알려진 프로그래밍 언어라는 사실이다. 여기서는 Ajax가 아닌 자바스크립트 언어를 기초부터 다시 한 번 짚어보는 시간을 가져보고자 한다. 서광열 kwangyul.seo@gmail.com·현재 (주)노매드커넥션의 CTO로 재직 중이다. 관심 분야는 플랫폼, 가상 머신, 프로그래밍 언어 등이며 현재는 웹 플랫폼에 많은 관심을 가지고 연구 개발을 진행 중이다. 개인 블로그인 서광열의 소프트웨어 이야기(http://skyul.tistory.com)을 통해 소프트웨어 개발과 IT 산업에 대한 생각을 정리하고 있다.

 

퀴즈
다음 중 자바스크립트와 가장 유사한 언어는 무엇일까?

1) C/C++
2) Java
3) Scheme 혹은 Self

1)번이라고 답한 사람은 아마 자바스크립트의 문법(특히 중괄호를 블록으로 사용하는 스타일)이 C/C++과 유사하다는 사실에 착안했을 것이다. 자바스크립트의 외형이 C/C++ 계열 언어와 유사하다는 점은 자바스크립트에 대한 오해의 시발점이다. 하지만 문법적으로 유사한 C, C++, C#, 자바 등이 정적 타이핑을 하는 프로그래밍 언어임에 비해, 자바스크립트는 동적 타이핑을 하는 스크립트 언어이다.

2)번이라고 대답한 사람은 자바스크립트의 ‘자바’라는 접두사에 현혹되었을 가능성이 크다. 또한 자바가 브라우저에서 실행하는 간단한 애플리케이션은 애플릿(applet)으로 출발했고, 자바스크립트 역시 웹 브라우저를 기반으로 한 프로그래밍 언어라는 측면에서 혼란이 가중되었다. 이렇게 혼란스러운 이름이 붙은 것은 순전히 이런 혼란을 의도한 마케팅적인 요소가 강하다. 실제로 넷스케이프 사가 처음 붙인 이름은 라이브스크립트(LiveScript)였는데, 출시 직전에 자바스크립트로 변경되었다. 하지만 앞에서 언급한 문법적 유사성과 ‘자바’라는 이름을 제외하면 두 언어는 실제로는 큰 관련이 없다.

자바스크립트가 함수형 언어의 요소를 상당 부분 차용했다는 사실을 아는 개발자는 아마 3)번을 선택했을 것이다. 함수형 언어의 가장 큰 특징 중에 하나는 함수가 제1클래스라는 사실이다. 쉽게 말해서 함수의 인자나 리턴 값으로 함수를 주고받을 수 있고, 변수에 함수를 저장할 수 있다. 자바스크립트도 함수가 제1클래스이고, 클로저도 생성할 수 있다. 이런 특성은 자바스크립트가 기존 언어와는 차별화되는 점이고, 완전히 다른 프로그래밍 스타일을 가능케 한다. 자바스크립트의 함수 언어적 요소를 이해하는 것은 자바스크립트를 100% 활용하기 위한 첫걸음인 셈이다.

코어 자바스크립트란?
자바스크립트에 대해 흔히 하는 오해 가운데 하나는 클라이언트-사이드(client-side) 자바스크립트가 코어 자바스크립트라고 생각하는 것이다. 일반적으로 웹 브라우저에서 사용하는 DOM API와 Ajax 등에서 자주 사용하는 XMLHttpRe quest 오브젝트 등은 자바스크립트의 코어가 아닌 웹 브라우저가 제공하는 확장 API일 뿐이다. 우리가 코어 자바스크립트 언어라고 부르는 부분은 이런 확장 API를 제외한 기본적인 데이터 타입과 일부 Date, RegExp 등의  오브젝트만을 포함한다. 

자바스크립트 여러 버전과 변종들
넷스케이프 네비게이터의 페이지 스크립트를 위해 개발된 자바스크립트는 웹 브라우저의 성공에 힘입어 처음부터 폭발적인 사용자를 확보한다. 그래서 초기 상당수의 설계 오류를 포함하고 있음에도 이를 수정, 보완 과정을 거치지 못한 상태로 수많은 개발자들에게 노출되었다. 이후 자바스크립트 언어가 표준화 기구인 ECMA에 상정되면서 표준안이 나오지만, ECMA는 초기 설계 오류는 수정하지 않고 추가 기능을 정의한 표준안을 내놓는다. 자바스크립트를 표준화한 ECMA-262 문서는 총 3번의 개정안을 거쳤고, 현재 자바스크립트 2.0이라고 불리는 4번째 개정안을 작업 중에 있다.

이렇게 표준안 자체가 여러 버전으로 나뉜 상태인데다가, 중앙화된 기구 없이 각 브라우저 벤더들은 자신만의 방식으로 자바스크립트를 구현하기 시작했다. 마이크로소프트는 JSc ript라는 이름으로 자바스크립트 구현했다. JScript는 크게 보면 자바스크립트와 동일하지만 일부 API가 빠져있는 등 완벽치 않은 표준 지원으로 브라우저 간 호환성은 심각하게 제한받게 되었다. 마찬가지로 ECMA 표준안을 바탕으로 출발한 어도비(Adobe) 사는 자사의 플래시/플렉스 제품에 자바스크립트의 변종인 ActionScript를 사용한다. ActionScript 2.0은 자바스크립트 1.5에 상응하지만, ActionScript 3.0은 아직 표준화가 끝나지 않은 자바스크립트 2.0에 기반하고 있다.

현재 Ajax 프로그래밍은 인터넷 익스플로러, 파이어폭스, 사파리, 오페라 등 대부분의 웹브라우저가 지원하는 자바스크립트 1.5(ECMA 3번째 개정안)를 바탕으로 한다. 파이어폭스의 경우 자바스크립트 1.6, 1.7 등을 추가로 지원하나, 브라우저 간 호환성 때문에 이렇게 추가된 기능을 충분히 활용하기는 힘들다. 자바스크립트 버전과 관련된 혼란스러운 상황을 숙지하길 바라며, 이후로는 가장 많이 사용되는 자바스크립트 1.5를 기준으로 자바스크립트의 기능들을 살펴보도록 하겠다.

기본 데이터 타입(primitive data type)
자바스크립트의 기본 데이터 타입은 boolean, number, string 이렇게 세 종류이다. 
이 가운데서 number가 내부적으로 64비트 부동소수점 수라는 점이 다른 언어와 비교해 주목할 만한 차이다. 자바스크립트가 간단한 스크립트 용도로 사용되었을 때는 큰 문제가 되지 않지만, 이를 이용해 복잡한 Ajax 애플리케이션을 제작한다면 숫자 연산이 많은 프로그램은 이 부분이 병목지점이 될 수도 있다. 실제로 자바스크립트를 이용한 암호 알고리즘이나 그래픽 렌더러(render)는 이런 기본 데이터 타입의 제한으로 심각한 성능 저하를 겪고 있다. 

어도비 사의 플렉스 2가 도입한 ActionScript 3.0은 이런 문제 해결을 위해 int와 uint 타입을 도입하였다. int는 해당 플랫폼의 기본 정수형 타입으로 변환되므로, 루프 변수 등으로 사용되었을 경우 무척 효율적이다. 하지만 자바스크립트 1.5 기반에서는 숫자 데이터 타입은 number 하나로 제한되어 있어 당분간은 이 문제를 염두에 두고 문제를 풀어나가야 한다.

오브젝트
자바스크립트의 오브젝트는 가장 범용적인 데이터 타입이다. 오브젝트는 문맥에 따라 해시테이블이 되기도, 객체지향 언어가 말하는 오브젝트가 되기도 한다.
<리스트 1>에서 {}는 빈 오브젝트 객체를 생성함을 의미한다. 오브젝트의 기본적인 사용법은 [] 연산자를 이용해 키 값을 지정해 주는 것이다. 그러니까 person 오브젝트는 키 값을 “name”으로 줬을 때 person[“name”]은 “Kwang Yul Seo”라는 값을 가지게 된다. 자바스크립트가 재미있어 지는 부분은 person[“name”]를 person.name의 형식으로도 읽을 수 있다는 사실에 있다. 반대로 person.gender를 person[“gen der”]로 읽을 수도 있다.

 


<리스트 1> 자바스크립트 오브젝트 사용 예
var person = {}; 
person["name"] = "Kwang Yul Seo"; 
print(person.name);

person.gender = "male"; 
print(person["gender"]);
 


이는 자바스크립트 오브젝트의 속성(property)이 오브젝트를 해시 테이블로 봤을 때는 키-값(key-value 혹은 name-value) 페어로 1:1 매치된다는 의미이다. 따라서 자바스크립트 오브젝트는 그 자체로 해시 테이블 데이터 구조이면서, 동시에 객체지향 언어의 객체 역할을 하게 된다. 이는 C/C++처럼 오브젝트의 속성이 컴파일 타임에 정해지는 언어와 달리 상당히 동적인 프로그래밍을 가능케 한다. 다음 예제는 custo mer의 속성인 name0, name1, name2, name3 속성을 for 문을 돌면서 수집하는 모습이다. 속성 이름을 프로그램 상에서 생성한 후에 속성의 값을 얻어올 수 있다.


<리스트 2> 동적인 객체 속성 참조
var fullname = ""; 
for(i = 0; i < 4; i++) { 
    fullname += customer["name" + i];
}


또한 오브젝트 상수(object literal)를 이용하면 복잡한 속성을 쉽게 표현할 수 있다. 다음 예제는 오브젝트 상수를 이용해 오브젝트를 정의하는 방법이다.
이런 오브젝트 상수는 함수의 인자를 이름으로 호출(call by name) 할 때 유용하다. 

<리스트 3> 오브젝트 상수를 이용한 오브젝트 정의 방법
var person = {
    "name" : "Kwang Yul Seo",
    "age" : 34,
    "married": false,
    "email' : "kwangyul.seo@gmail.com"
};
 


특히 일부 인자가 옵션일 때 인자를 차례대로 호출할 경우, 옵션 인자에는 null을 줘야하는 불편함이 있다. 자바스크립트는 ‘이름으로 호출‘ 기능이 없지만 오브젝트 인자를 하나 지정하고 { opt1: “opt1”, opt2: “opt2” }와 같은 형태로 오브젝트 상수를 넘겨주면, 받는 쪽에서는 o[“opt1”]과 같은 형태로 필요한 인자만 참조할 수 있다.

함수
자바스크립트의 함수는 C/C++, 자바 등과 가장 큰 차이가 나는 부분이다. 기존 언어와 자바스크립트 함수의 차이점을 크게 4가지로 나눠 살펴보자.

함수가 제1클래스이다
앞에서 함수형 언어와 유사점을 설명하면서 언급했듯이 자바스크립트의 함수는 제1클래스이다. 따라서 고전적인 C/C ++ 등의 언어와 달리 함수를 동적으로 생성하고 변수에 저장하거나 함수 호출시 인자로 넘길 수 있다. 다음 예제를 보자.

<리스트 4> 함수를 선언하는 두 가지 방법
// 1
function f(x) { return x * x; }
// 2
var f = function(x) { return x * x; };



자바스크립트는 일반적인 언어처럼 function function_ na me(argument_lists...) { /* code */ }의 형태로 함수를 선언할 수 있지만, function(argument_lists...) { /* code */ }의 형태로 이름 없는 함수를 선언한 후에 이를 변수에 대입할 수 있다. <리스트 4>에서 1과 2는 동일한 함수 f를 정의하는 셈이다.

한 번만 호출하고 끝나는 함수의 경우에는 이름을 주지 않고 다음과 같이 호출할 수도 있다. 이런 익명 함수는 블록 범위(block scope)가 없는(<박스기사 참조>) 자바스크립트에 블록 범위를 주고자 할 때나 복잡한 오브젝트에 간단한 이름을 주고자 할 때 주로 사용된다.

<리스트 5> 익명 함수의 호출
(function(a, b) {
    var c = a + b;
    return c;
})(obj1.foo.num1, obj2.foo.num2);


중첩 함수를 허용한다
자바스크립트는 함수 안에 다른 함수를 정의하는 것을 허용한다. 이는 함수의 접근을 제한하는 효과가 있으므로 캡슐화에 무척 효과적이다(<리스트 6> 참고).
<리스트 6>에서 square 함수는 hypotenuse 함수 내부에서만 사용되므로 중첩 함수를 사용해 외부의 접근을 제한하고 있다. 특정 알고리즘을 구현하기 위해 보조 함수가 필요한 경우 이렇게 중첩 함수를 이용하면 네임스페이스를 어지럽히지 않고 새로운 함수를 추가할 수 있다.

<리스트 6> 중첩 함수의 사용
function hypotenuse(a, b) {
    function square(x) { return x * x; }
    return Math.sqrt(square(a) + square(b));
}



클로저(closure)를 지원한다
클로저는 지난 호 마소에서 루비를 이용해 자세히 설명한 바 있다. 간단히 요약하면, 클로저는 함수+환경으로 정의할 수 있다. 여기서 환경이란 클로저를 정의한 시점에 렉시컬 범위(lexical scope)에서 참조할 수 있는 모든 변수들을 말한다. <리스트 7>은 자바로 구현된 자바스크립트 엔진인 Rhino 상에서 add_x 함수를 정의하고 호출해 본 것이다.


<리스트 7> 클로저의 예
js> function add_x(x) {
    return function(y) { return x + y; };
}
js> f = add_x(3);

function (y) {
    return x + y;
}

js> f(4);
7
js> f(5);
8


add_x 함수를 살펴보면 x라는 인자를 받아 새로운 함수 function (y) { return x + y; }를 리턴한다. 이 함수는 y라는 인자를 새로 받아서 add_x에 인자로 넘어온 x를 더한 후 리턴하는 함수이다. 따라서 add_x(3)를 호출하고 f에 저장하면, f는 인자 하나를 받아 3을 더한 후에 리턴하는 함수가 된다. 

여기서 add_x의 인자 x에 주목할 필요가 있다. x는 지역 변수이므로 add_x가 호출되면 없어져야 하지만, 내부의 클로저가 x를 참조하므로 x는 add_x 함수가 리턴된 후에도 보존된다. 클로저가 생성되면 생성 당시의 외부 환경(lexical scope)이 보존되기 때문이다. 덕분에 f에 4, 5 등을 인자로 호출하면 3이 더해진 7과 8이 리턴되는 것을 확인할 수 있다(클로저에 대한 자세한 설명은 마소 3월호를 참고하기 바란다).

함수도 오브젝트이다자바스크립트에서 함수는 호출이 가능한 특별한 오브젝트로 볼 수 있다. 따라서 함수를 정의하고 호출할 수 있을 뿐만 아니라, 함수 자체에 여러 가지 속성을 부여하고 참조하는 것도 가능하다. 다음 예제는 add 함수를 정의할 뿐만 아니라 name이라는 속성을 부여해 어떤 함수인지를 나타내게 해보았다
.

<리스트 8> 함수의 속성
var add = function(x, y) { return x + y; };
add.name = "addition";

 


클래스, 생성자, 프로토타입
자바스크립트는 객체지향 프로그래밍 언어이다. 하지만 클래스라는 개념은 없다. 이 말은 C++이나 자바 계열에서 전향한 개발자들을 미궁 속으로 몰아넣는 자바스크립트의 미스터리다. 클래스가 없는데 객체는 어디서 생성되는 걸까? 이 의문을 해결하는 열쇠는 바로 new 연산자이다. <리스트 9>는 새로운 Date 오브젝트를 생성하는 예제이다.

var today = new Date();<리스트 9> new 연산자와 생성자 함수

코드만 보면 마치 자바처럼 Date라는 클래스가 존재하고 Date의 디폴트 생성자를 호출해 새로운 Date 객체를 얻어오는 것 같다. 하지만 문법적으로 자바의 클래스 생성과 무척 유사해 보임에도 불구하고, 자바스크립트는 내부적으로는 전혀 다른 방식으로 동작한다. 

코드가 실제로 하는 일은 단순하다. 새로 생성한 빈 객체 {}를 new 연산자를 통해 생성한 후, 해당 객체를 Date라는 함수의 암묵적(implicit) 인자로 넘겨주는 것이다. 이렇게 새로 생성된 {} 오브젝트는 Date 함수 내에서 this라는 키워드로 접근 가능하다. Date 함수는 this 키워드를 이용해 {} 오브젝트에 몇 가지 속성을 새로 생성해 주는 것이다. 그리고 Date 함수의 리턴 값은 별도로 return 문을 이용해 명시하지 않는 이상 새로 생성된 오브젝트(this)가 된다(return 문을 명시적으로 쓰면 다른 값을 리턴할 수도 있다). Date 함수가 대문자 D로 시작하는 이유는 생성자임을 나타내기 위한 컨벤션일 뿐이므로 언어적으로 특별한 역할을 하지는 않는다.


<리스트 10> new 연산자와 생성자 함수
function Rectangle(w, h) {
    this.width = w;
    this.height = h;
}

var rect1 = new Rectangle(1, 2);
var rect2 = new Rectangle(3, 4);


<리스트 10>의 예제는 이런 원리를 바탕으로 실제 생성자(constructor) 함수를 정의해 본 것이다. 코드를 해석하면, new 연산자가 빈 오브젝트 {}를 만들고, 이를 Rectangle 함수에 암묵적으로 넘긴다. 새로 생성된 오브젝트는 자동으로 Rectangle 함수 내에서 this로 참조할 수 있다. 이후 Rect angle 함수를 두 개의 인자로 실행시키는데, this의 width와 height 속성을 각각 원하는 값으로 세팅해준다. 리턴 값을 별도로 정의하지 않고 있으므로, 이 함수의 리턴 값은 자동으로 this가 된다. 따라서 rect1은 { width: 1, height: 2 }인 오브젝트가 된다. 이 과정에서 클래스라는 개념은 필요하지 않음을 알 수 있다.

또 하나 특별한 규칙이 적용되는 부분은 오브젝트의 속성에 함수를 정의했을 경우이다. 다음 예제를 살펴보자. 이 예제에서는 새로 생성된 r 오브젝트에 area라는 속성을 추가하는데, 함수를 정의한다. 오브젝트의 속성으로 지정된 함수에서는 해당 오브젝트를 this라는 키워드로 참조할 수 있다. 따라서 r.area() 함수를 호출하면 area 함수 내에서 this는 r이 되므로 r.width * r.area 값을 리턴하게 되는 것이다. 

쉽게 말해 오브젝트의 속성으로 정의된 함수는 그 오브젝트의 메소드가 되는 셈이다. 하지만 메소드와 함수의 구분이 명확한 것은 아니다. 그저 this라는 키워드를 사용하느냐 안 하느냐의 차이일 뿐이다. 실제로 글로벌 함수도 this 키워드를 사용할 수 있는데, 이때는 맥락에 따라 가리키는 오브젝트가 다르다. 클라이언트-사이드 자바스크립트의 경우 글로벌 함수에서 this는 보통 윈도우 오브젝트가 된다.
여기까지는 클래스 없이도 오브젝트를 정의하고 필요한 메소드를 정의할 수 있다. 하지만 일반적인 객체지향 언어의 특징 중 하나인 클래스 상속이라는 개념이 빠져있음을 알 수 있다. 자바스크립트는 클래스가 없으므로 클래스를 상속한다는 개념도 사실은 있을 수 없다. 대신에 이를 흉내낼 수 있는 방법을 제공하는데, 그게 바로 프로토타입이다.


<리스트 11> 오브젝트 속성과 메서드
var r = Rectangle(1, 2);
r.area = function() { return this.width * this.height; };

<리스트 12> 오브젝트 속성과 프로토타입
function Rectangle(w, h) {
    this.width = w;
    this.height = h;
}

Rectangle.prototype.area = function() { return this.width * this.height; };
var r = Rectangle(1, 2);


자바스크립트의 오브젝트는 또 하나의 특별한 규칙을 가지는데, 속성을 참조할 때 우선 자기 오브젝트의 속성을 먼저 찾고, 여기에 존재하지 않으면 다음에는 오브젝트를 생성한 함수(constructor 속성으로 접근 가능함)의 prototype이라는 속성을 참조한다는 것이다. 따라서 <리스트 11>은 다음과 같이 작성될 수 있다.

<리스트 12>에서 r.area()를 호출하면 우선 r의 속성 중에 area라는 속성이 있는지 찾는다. 없을 경우, 다음으로 r을 생성하는데 사용된 함수인 Rectangle 함수의 prototype 속성 내에 area라는 속성(Rectangle.prototype.area)이 있는지 찾는다. 있다면 이를 대신 이용한다. r에 직접 area 메소드를 정의한 경우 Rectangle로 생성한 다른 오브젝트는 area 메소드를 이용할 수 없는 반면에, Rectangle.prototype에 area를 정의해주면 Rectangle로 정의된 모든 오브젝트가 area 메소드를 이용할 수 있는 것이다(C, C++의 메소드에 가깝다). 이와 같은 과정을 속성 상속(property inheritance)이라고 부른다.

한 가지 주의할 점은 속성 상속은 읽기에 한해 발생하고, 쓰기의 경우는 적용되지 않는다는 사실이다. 즉, r.area()를 호출할 때는 해당 속성이 오브젝트에 없을 경우 함수 prototype을 통해 찾아올라가지만, 반대로 r.area에 새로운 함수를 정의해 줄 경우에는, prototype의 함수를 오버라이드하지 않고 해당 오브젝트 함수만 덮어쓰게 된다. 따라서 같은 함수로 생성된 다른 오브젝트들은 여전히 원래 prototype에 정의된 함수를 이용한다. 다음 예제를 보면 보다 명확해질 것이다.


<리스트 13> 속성 상속의 특징
function Rectangle(w, h) {
    this.width = w;
    this.height = h;
}

Rectangle.prototype.area = function() { return this.width * this.height; };
var r1 = Rectangle(1, 2);
var r2 = Rectangle(3, 4);

r1.area = function() { return 0; }

r1.area(); // -> 0
r2.area(); // -> 12


r1.area = function() { return 0; }을 해주면 r1에 새로운 속성 area를 추가하고 이 메소드는 r1을 통해서만 호출 가능하다. 즉, 쓰기의 경우 속성 상속을 통해 Rectangle.pro totype.area를 덮어쓰지 못한다. 따라서 r2.area()를 호출하면 r2에는 area 속성이 없으므로 Rectangle.prototype.area를 호출하게 되는 것이다.
자바스크립트의 객체 생성 및 상속은 이런 특별한 규칙 몇 가지로 이루어진다. new 연산자와 this 키워드, 그리고 생성 함수의 property 속성을 이용한 속성 상속이 그것이다. 

이는 자바스크립트의 강력함과 유연함이기도 하지만, 많은 개발자에게 혼란을 가져오기도 한다. 

특히 이 3가지의 조합만으로도 여러 가지 객체지향 프로그래밍 스타일이 나올 수 있다는 사실이 문제다. 속성 상속을 잘 이용해 C++이나 자바의 클래스 상속을 흉내 내는 방법도 있고, 반대로 루비나 일부 함수형 언어가 제공하는 믹스인(mix-in, 코드 상속 기법)을 따라할 수도 있다. 이 부분은 어느 한 쪽으로 통일하기로 합의된 바가 없다. 실제로 현재 Ajax 라이브러리들을 보면 각자 특정 스타일의 객체지향기법을 사용하고 있고, 그 구현 방식이 조금씩 다르다. 프로토타입(Proto type) 라이브러리의 경우 클래스를 흉내 내는 방식을 사용하고 있고, jQuery의 경우 $.extend와 같은 함수를 통해 믹스인을 제공하기도 한다. 하지만 앞에서 언급한 몇 가지 언어적 특징만 이해하면 어떤 식으로 객체지향을 구현하더라도 그 원리를 이해하는데 큰 어려움이 없을 것이다.

자바스크립트는 문서가 부족하고 부실하기로 유명하다. 언어 표준 명세서인 ECMA 262는 가장 중요한 문서이지만, 너무 어려워 이해가 쉽지 않다. 조금 더 깊이 있는 내용을 공부하고 싶은 개발자는 반드시 ‘JavaScript, The Definitive Guide 5th Edition, O’Reilly’를 읽어보기 바란다. 자바스크립트 관련해 거의 유일하게 제대로 설명한 책이기 때문이다.

현재 Ajax가 부각되고, 각종 위젯 프로그램이 자바스크립트 구현되고 있다. 특히 어도비의 아폴로 프로젝트 등을 필두로, 자바스크립트는 브라우저 이상의 범용적인 프로그래밍 언어로 발전할 가능성이 크다. 지금은 이런 변화의 중심에 있는 자바스크립트의 기초 다지기가 필요한 시점이 아닐까 싶다. 

참고 문헌
[1] JavaScript, The Definitive Guide 5th Edition, O’Reilly
[2] Wikipedia , Closure
http://en.wikipedia.org/wiki/Closure_(computer_science)
[3] A Survey of the JavaScript Programming Language
http://javascript.crockford.com/survey.html