자바스크립트 완벽 가이드/ 변수

변수 타입

자바스크립트 변수는 자바나 C와 달리 변수 타입이 고정되어 있지 않다. 자바스크립트 변수는 어떠한 데이터 타입의 값이라도 담을 수 있다. 예컨대 자바스크립트에서는 어떤 변수에 숫자 값을 할당한 후 같은 변수에 다시 문자열을 할당해도 아무런 문제가 되지 않는다.

변수 선언

변수 선언에는 var 키워드를 사용한다. var 문으로 선언된 변수는 영구적이다. delete 연산자를 사용해서 그 변수를 제거하려 할 경우 에러가 발생한다.

변수 선언의 반복과 생략

var 구문으로 같은 이름의 변수를 여러 번 선언해도 무방하다. 만일 그 반복된 선언에 변수 초기화 구문이 함께 있을 경우 그저 변수에 값을 할당하는 구문과 동일하게 작동한다.

선언되지 않은 변수의 값을 읽으려 할 경우 에러가 발생한다. 만일 아직 var문으로 선언되지 않은 변수에 값을 할당하려 하면, 자바스크립트가 암묵적으로 그 변수를 선언한다. 단, 암묵적으로 선언된 변수는 항상 전역 변수로 선언된다. 설사 그 변수가 함수 안에서 쓰인다 하더라도 마찬가지다. 따라서 모든 변수 선언에는 항상 var 를 사용하는 것이 좋다.

변수의 유효 범위

전역 변수는 자바스크립트 코드 전체에 걸쳐 정의된다. 반면 어떤 함수 안에서 선언된 지역 변수는 오직 그 함수 몸체 안에서만 정의된다. 함수 내부에서는 지역 변수가 같은 이름의 전역 변수보다 우선적으로 사용된다.

블록 단위의 유효 범위는 없다

함수 안에서 정의된 변수는 그것이 정의된 위치에 관계없이 항상 함수 전체에 걸쳐 유효하다. 그러나 어떤 함수에서건 모든 변수의 선언을 함수의 시작부에 두는 것이 좋은 습관이다.

정의되지 않은 변수 vs 할당되지 않은 변수

선언되지 않은 변수를 읽으려 하면 런타임 에러가 발생한다. 그러나 정의되지 않은 변수에 값을 할당할 때는 에러가 발생하지 않는다. 이 경우에는 암묵적으로 해당 변수가 전역 변수로 선언된다.

선언은 되었으나 아직 값이 할당되지 안은 경우 undefined를 얻게 된다.

기본 타입과 참조 타입

데이터 타입에는 크게 기본 타입과 참조 타입 두 가지 종류가 있다. 숫자, 불리언 값, null, undefined 타입은 기본타입이다. 한편 객체(Object), 배열, 함수는 참조 타입이다.

기본 타입은 고정된 크기의 메모리를 갖는다. 예컨대 숫자 타입은 8바이트, 불리언 값은 1비트 등

반면 참조 타입은 어떤 크기라도 가질 수 있다. 즉 객체는 고정되어 있지 않다. 마찬가지로 배열도 원소 개수에 제한이 없다. 함수도 얼마든지 많은 자바스크립트 코드를 포함할 수 있다.

참조 타입은 크기가 고정되어 있지 않기 때문에 참조 타입의 값은 8바이트 메모리를 가지는 변수에 직접 저장할 수 없다. 대신, 변수에 저장되는 것은 이런 값에 대한 ‘참조’다. 참조는 보통 포인터의 한 종류이거나 메모리 주소이다. 참조는 데이터 값 자체가 아니라 그 값을 찾을 수 있는 위치를 변수에게 알려주는 것이다.

기본 타입과 참조 타입을 구별하는 것은 매우 중요하다. 왜냐하면 이 두 가지는 서로 다르게 작동하기 때문이다. 예컨대 기본 타입과 참조 타입은 아래와 같이 변화한다

var a = 3;
var b = a;
a = 4;
alert(b); // 3이 출력된다. 복사본의 값은 바뀌지 않았다.

var a = [1, 2, 3];
var b = a;
a[0] = 99;
alert(b); // 새로운 참조를 쓰지만 변경된 배열 [99, 2, 3]이 출력된다

가비지 컬렉션

참조 타입은 크기가 고정되어 있지 않다. 참조 타입 중 몇 가지는 경우에 따라선 매우 커질 수도 있다. 문자열, 객체, 배열 등은 크기가 정해져 있지 않다. 따라서 이들을 담기 위한 저장소는 그 크기를 알 수 없는 상태에서 동적으로 할당되어야 한다. 자바스크립트 프로그램에서 문자열이나 배열, 또는 객체 등을 생성할 때마다, 인터프리터는 해당 개체를 저장하기 위한 메모리를 할당해야 한다. 이렇게 동적으로 할당된 메모리는 언젠가 반드시 해제되어 재활용 될 수 있어야 한다. 그렇지 않으면 자바스크립트 인터프리터가 시스템의 모든 가용 메모리를 잡아머어 결국은 시스템이 다운되고 말 것이다.

C나 C++에서 수동으로 메모리를 해제해야 했던 것과 달리 자바스크립트에서는 프로그래머가 수동으로 메모리를 해제하도록 강제하지 않는 대신, 가비지 컬렉션이라 불리는 기술에 의존한다. 자바스크립트 인터프리터는 어떤 객체가 어느 시점부터 프로그램에서 더이상 쓰이지 않는지 알아챌 수 있다. 가비지 컬렉션은 프로그래머에게 보이지 않고 자동적으로 일어난다.

변수와 프로퍼티

자바스크립트의 변수는 근본적으로 객체 프로퍼티와 동일하다.

전역 객체

자바스크립트 인터프리터가 구동되면 자바스크립트 코드를 실행하기 전에 먼저 수행하는 사전 작업들이 있는데 그 중 하나가 바로 전역 객체(global object)를 생성하는 일이다. 이 객체의 프로퍼티들은 자바스크립트 프로그램들의 전역 변수들이다. 여러분이 자바스크립트 전역 변수를 선언하면, 실제로는 전역 객체의 프로퍼티가 정의된다.

최상위 코드, 즉 어떤 함수에도 속하지 않은 코드에서는 자바스크립트의 this 키워드를 사용해서 전역 객체를 참조할 수 있다.

지역 변수: 호출 객체

전역 변수들이 특수한 전역 객체들의 프로퍼티에 해당한다면 지역 변수들은 어떨까? 이들 역시 어떤 객체의 프로퍼티에 해당한다. 이 객체를 일컬어 호출 객체(call object)라고 부른다. 호출 객체는 전역 객체보다 수명이 짧지만 쓰이는 목적은 동일하다. 함수를 실행하는 동안 그 함수의 전달인자와 지역 변수는 이 호출 객체의 속성으로 저장된다. 자바스크립트에서 지역 변수 용도로 전혀 별개의 객체를 사용하는 덕에 지역 변수가 같은 이름의 전역 변수를 덮어쓰는 것을 방지할 수 있는 것이다.

자바스크립트 실행 컨텍스트

자바스크립트 인터프리터가 어떤 함수를 실행할 때마다, 그 함수에 대한 새로운 실행 컨텍스트를 생성한다. 실행 컨텍스트란, 자바스크립트 코드가 실행되고 있는 컨텍스트를 말한다. 이 컨텍스트에서 중요한 부분 중 하나로 변수들이 정의되어 있는 객체를 들 수 있다. 이를테면, 어떤 함수에도 속하지 않은 자바스크립트 코드를 실행하는 컨텍스트에서는 전역 객체를 사용해서 변수를 정의한다. 그리고 모든 자바스크립트 함수는 각기 자신만의 고유한 컨텍스트에서 실행되며, 이 컨텍스트에는 지역 변수가 정의되어 있는 고유한 호출 객체가 있다.

변수의 유효 범위(재해석)

모든 자바스크립트 실행 컨텍스트에는 유효 범위 체인(Scope Chain)이라는 것이 딸려 있다. 이 유효 범위 체인이란 객체들의 나열(또는 체인)이다. 자바스크립트 코드에서 x라는 변수의 값을 찾으려면(이는 ‘변수 이름 판별’ 이라 불리는 과정이다) 제일 먼저 체인의 첫 번째 객체부터 검색을 시작한다. 만일 이 객체에 x라는 이름의 프로퍼티가 있을 경우, 해당 프로퍼티의 값이 쓰이게 된다. 만일 첫 번째 객체에 x라는 이름의 프로퍼티가 없을 경우 다음의 객체로 검색이 계속 된다. 두 번째 객체에도 x라는 이름의 프로퍼티가 없을 경우 그 다음 객체로 검색이 계속 된다. 두 번째 객체에도 x라는 이름의 프로퍼티가 없을 경우 그 다음 객체로 검색을 계속하는, 이러한 작업이 계속된다.

최상위 자바스크립트 코드의 경우(즉, 어떠한 함수 정의에도 포함되지 않은 코드) 이 유효 범위 체인은 ‘전역 객체’ 단 하나의 객체만으로 이루어진다. 이 객체에서 모든 변수를 검색한다. 이 객체에 존재하지 않는 변수의 값은 undefined이다. 그러나 (중첩되지 않은) 함수의 경우, 유효 범위 체인은 두 개의 객체로 이루어진다. 첫 번째는 이 함수의 호출 객체이고, 두 번째는 전역 객체다. 이 함수에서 어떤 변수를 참조할 경우, 호출 객체(지역 유효 범위)를 먼저 확인한 다음, 전역 객체(전역 유효 범위를 확인하게 된다. 중첩된 함수의 경우 세 개 또는 그 이상의 객체가 유효 범위 체인에 존재한다.

[ssba]

The author

지성을 추구하는 디자이너/ suyeongpark@abyne.com

댓글 남기기

This site uses Akismet to reduce spam. Learn how your comment data is processed.