티스토리 뷰

4장 변수와 스코프, 메모리

< 프론트엔드 개발자를 위한 자바스크립트>(2013 인사이트, 한선용 옮김) 의 책을 요약한 내용으로 자바스크립트 제대로 배우기 스터디 그룹(페이스북) 의 글입니다.


4.1 원시 값과 참조 값

  • 원시값 : 단순한 데이터 (Undefined, Null, 불리언, 숫자, 문자열)
  • 참조값 : 여러 값으로 구성되는 객체
많은 언어에서 문자열은 객체로 표현되어 참조탑입으로 간주하지만 ECMAScript 는 이전통을 깨트렸습니다.


4.1.1 동적 프로퍼티

참조값(객쳬)를 생성하고 동적으로 멤버변수를 추가 할수 있다. 하지만 원시값에도 동일한 작업이 가능하지만 에러

를 발생하지 않는다.

var person = new Object();
person.name = "anyjava";
console.log( person.name );

var person2 = "anyjava";
person2.age = 27;
console.log( person2.age ); // undefined


4.1.2 값복사

원시형의 경우 값에 의한 복사가 일어나고 참조형의 경우 참조에 의한 복사가 일어난다. (Java 와 동일함.)


4.1.3 매개변수 전달

함수의 매개변수로 전달할때 기본적으로 변수의 값을 복사해서 전달한다. 단, 원시형의 경우 데이터값이 복제되는 것이고, 참조형의 경우 객체를 참조하는 주소값을 복사하게 된다.


4.1.4 타입판별

  • typeof [var]                           원시값을 판별할 때
  • [var] instanceof [Object]    참조값의 타입을 판별할때


4.2 실행컨텍스트와 스코프

엄청 중요한 개념!

실행컨텍스트는 변수나 함수의 실행 컨텍스트는 다른 데이터에 접근할 수 있는지, 어떻게 행동하는지를 규정함.

가장 바깥쪽에 있는 컨텍스트가 전역컨텍스트 이며 함수가 호출될때마다 독자적인 실행 컨텍스트가 생성됩니다.해당 컨텐스트는 컨텍스트 스택에 쌓입니다.

컨텍스트 코드를 실행하면 변수 객체에 '스코프 체인(scope chain)'이 만들어집니다. 스코프 체인의 목적은 실행 컨텍스트가 접근할 수 있는 모든 변수와 함수에 순서를 정의하는 것.

전역컨텐스트의 변수객체가 항상 스코프 체인의 마지막에 존재하며, 식별자(변수)를 찾을때는 스코프 체인 순서를 따라가면서 해당 식별자 이름을 검색합니다.(식별자를 찾을 수 없다면 에러가 발생합니다.)

해당내용은 엄청 중요하므로 교재 114페이지를 참고바랍니다.


4.2.1 스코프 체인 확장

try-catch 문의 chatch 블럭,with문 문장은 스코프체인 앞 부분에 임시로 변수 객체를 만들며 해당 변수 객체는 코드 실행이 끝나면 사라집니다.

풀어 설명하면 catch문과 with 문의 대괄호 안에 있는 지역변수라도 해당 구문이 속하는 함수내에서는 사용가능합니다.


4.2.2 자바스크립트에는 블록 레벨 스코프가 없습니다.

일반 Java, C와 달리 실행 블럭( {...} ) 이 끝나도 변수는 존재합니다. 아래 예제를 보시죠.

if( true ) {
    var temp = "temp";
}

console.log( temp ); // temp 출력!


변수선언

var를 사용하여 초기화 하면 가장 가까운 컨텍스트에 추가됩니다. 하지만 var키워드를 이용하여 변수를 선언하지 않은채 초기화 하면 전역 컨텐스트에 추가됩니다.

하지만, 변수를 선언하지 않고 초기화 하는 방법은 추천되지 않으며 스트릭트 모드에서는 에러가 발생됩니다.


식별자 검색

전역 컨텍스트와 로컬 컨텍스트에 동일식별자가 있을 경우 로컬컨텍스만 참조하고 검색이 종료되어 집니다. 즉, 로컬변수와 전역변수 명이 같을경우 로컬변수로 접근이 됩니다. 전역변수에 접근하기 위해서는 windows.변수명으로 접근해야 합니다.


4.3 가비지컬렉션

함수내부에 선언된 로컨변수가 차지하는 메모리는 함수 실행이 끝나면 회수되어 진다. 회수하는 방법은 브라우져마다 다르며 보통 다음의 2가지 방법이 있다.


4.3.1 표시하고 지우기

가비지 컬렉터가 작동하면 메모리에 저장된 변수 전체에 표시를 남깁니다. 그다음 컨텍스트에 있는 변수와 컨텍스트에 있는 변수가 참조하는 변수에 표시를 지웁니다. 이후 가비지 컬렉터는 표시가 남아 있는 값을 모두 회수합니다.


4.3.2 참조 카운팅

변수를 선언하고 참조값이 할당되면 1입니다. 다른 변수가 값은 객체를 참조하면 참조값이 2로 증가합니다. 해당참조값에 다른 참조값이 할당되면 1일 줄어드는 원리입니다. 그리하여 가비지 컬렉터는 참조값이 0인 객체를 모조리 회수합니다.

하지만, 이는 즉시 순환참조라는 심각한 문제가 발생할 수 있습니다.

function test() {
    var objA = new Object();
    var objB = new Object();
    objA.someObj = objB;
    objB.anotherObj = objA;
}

위 예제는 함수가 종료되더라도 objA와 objB가 참조하는 객체는 회수 되지 않습니다. 이 때문에 넷스케이프 버전 4.0에서는 참조 카운팅의 방법을 버렸습니다.

그리고 IE8과 그 이전버전에서는 DOM, BOM 이 네이티브 자바스크립트가 아니며 가비지콜렉션이 참조 카운팅 방식을 사용하여 즉시 순환참조 문제를 야기할 수 있습니다. 이때문에 DOM, BOM 을 사용할떄는 null 로 명시적으로 해제해주는 습관을 들이는게 좋을 듯 합니다.

예제는 교재(p.124)참고 바람


4.3.3 성능

가비지 컬렉션은 주기적으로 실행되면 자원을 많이 사요하여 자주 발생하면 성능의 문제가 된다. IE6 이전에서는 너무 자주 발생되어 성능이 현저하게 떨어지는 현상이 발생할 수 있다.


4.3.4 메모리 관리

웹브라우져는 데스크탑 어플리케이션만큼의 충분한 메모리를 사용할 수 없는 환경이다. 따라서 꼭 필요한 객체만을 사용하도록 하는 습관이 필요하다.

지역변수의 경우 함수 실행이 종료되면 참조가 사라져 회수되는 전역변수의 경우 명시적으로 nulll값으로 초기화 해주는 습관이 필요하다.



페이스북 그룹 자바스크립트 제대로 배우기의 스터디로 학습내용을 정리한내용입니다.


[JavaScript 스터디 다른글]

4장. 변수와 스코프, 메모리


댓글
댓글쓰기 폼