자바스크립트의 데이터 타입은 크게 '기본 타입'과 '참조 타입'으로 나뉜다.
자바스크립트의 거의 모든 것은 객체이다. 하지만 기본 데이터 타입인 boolean, number, string, null, undefined는 객체가 아니다. 여기서 boolean, number, string은 모두 객체처럼 다룰 수 있기 때문에, null과 undefined만이 객체가 아니라고 할 수 있다.
기본 타입인 boolean, number, string를 객체처럼 다룰 수 있다는 말의 예시를 들자면 다음과 같다.
var a = "javascript";
a.charAt(2); // "v"
이 예시에서, 변수 a는 string타입이지만 객체의 형태로 메서드를 호출했다. 이것은 기본값이 메서드 처리 순간에 객체로 변환되어 호출되고, 다시 기본값으로 복귀하는 과정을 거친다.
자바스크립트에서의 함수 또한 객체이다. 자바스크립트의 함수는 일급 객체(First class object)이기 때문에 더욱 중요하다.
일급 객체만 간단히 알아보겠다. 프로그래밍 언어에서 일급 객체는 자료형을 할당, 전달, 리턴 등을 할 수 있는 자료형이다. 따라서 일급 객체는 다음과 같은 조건을 만족한다.
1. 변수에 할당될 수 있다.
2. 다른 함수의 인자로 전달될 수 있다.
3. 함수의 결과로 리턴될 수 있다.
다음은 이에 대한 간략한 예시이다.
1. 변수에 할당될 수 있다.
var f = function(x) {
return 2 * x + 1;
}
f(1); // 3
2. 다른 함수의 인자로 전달될 수 있다.
function a(func) {
return func(1);
}
a(f); // 3
3. 함수의 결과로 리턴될 수 있다.
function b() {
return function() {
return 0;
}
}
b()(); // 0
자바스크립트는 객체지향 언어이지만, 다른 객체지향 언어들과 달리 클래스(Class)가 없다. 하지만, 자바스크립트에서는 프로토타입(prototype)이 그 역할을 대신한다.
모든 객체는 숨겨진 링크(link)인 프로토타입을 가진다. 함수가 정의될 때 프로토타입 객체 또한 같이 생성된다. 그리고 그 프로토타입은 prototype이라는 속성으로 확인이 가능하다.
자바스크립트의 객체(Object)는 항상 함수로 생성된다.
f.prototype == a.__proto__
실행 컨텍스트는 실행할 코드와 관련된 환경 정보를 모아놓은 것이라고 할 수 있다.
처음 자바스크립트가 실행될 때, '전역 컨텍스트'가 생성된다. 그 후 함수가 호출된다면, 전역 컨텍스트와 관련된 코드의 실행을 중단하고 호출된 함수의 컨텍스트로 넘어간다. 또한, 컨텍스트가 생성될 때 여러가지 작업을 하는데, 그것은 다음과 같다.
함수가 실행될 때, 내부 코드 전체를 한 번 훑으며 변수 이름, 선언된 함수, 매개변수 등을 컨텍스트에 저장한다. 여기서 호이스팅이라는 개념이 나온다. 호이스팅의 과정은 다음과 같다.
// 호이스팅 전
function func() {
console.log(a);
var a = 0;
}
// 호이스팅 후
function func() {
var a;
console.log(a);
a = 0;
}
다음과 같이 변수 이름이 맨 위로 끌어올려지는 효과가 있다. 물론 실제로 위로 올라가진 않고, 호이스팅은 컨텍스트의 정보 수집을 표현한 것 뿐이다. 다음은 함수가 호이스팅되는 과정이다.
// 호이스팅 전
function func() {
console.log(a());
function a() {
console.log("a");
}
console.log(b());
var b = function() {
console.log("b");
}
}
// 호이스팅 후
function func() {
var a = function a() {
console.log("a");
}
var b;
console.log(a());
console.log(b());
b = function() {
console.log("b");
}
}
위의 코드를 실행한 결과이다. 이렇게 호이스팅 과정에서 '함수 선언문'과 '함수 표현식'의 차이도 확인해 볼 수 있다.
스코프 체인은 변수를 참조할 때 사용하는 '지도' 정도로 생각하면 될 것 같다. 스코프 체인은 현제 컨텍스트의 변수 객체와 상위 컨텍스트의 스코프 체인이 합쳐져 생성된다. 현제 컨텍스트에 참조하려는 변수가 없다면 상위 컨텍스트로 가서 참조하려는 변수를 찾아본다.
자바스크립트는 클래스를 지원하지 않지만, 객체지향 프로그래밍이 가능하다. 자바스크립트엔 클래스 대신 프로토타입이 있고, 앞의 실행 컨텍스트의 스코프 체인에서도 보았듯이, 정보의 은닉이 가능하다.
자바스크립트는 느슨한 타입(Loose typing)을 가지고 있다. 느슨한 타입 체크 언어는 변수를 선언할 때 미리 데이터 타입을 명시해 주지 않는다. 자바스크립트는 'var'이라는 단어만 변수를 선언하고, 할당되는 값으로 타입이 결정된다.
이와 반대로 C나 Java 같은 언어는 엄격한 타입 체크 언어이다.
// javascript
var a = 2;
var b = "javascript";
// Java
int a = 2;
String b = "Java";
느슨한 타입 체크는 개발자에게 자유로움을 줄 수 있다. 하지만 이러한 특성 때문에 '컴파일 타임'에서 프로그램의 오류를 잡아낼 수 없게 되고, 개발자는 '런타임 에러'를 맞닥뜨리게 될 수 있다. 최근엔 이러한 단점을 극복하기 위해 자바스크립트에 타입을 부여한 'typescript'라는 자바스크립트의 확장 언어가 나오게 되었다.