본문 바로가기
개발 관련/javascript

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

by lazysnack 2022. 7. 13.

다루는 내용

  1. 변수의 원시값과 참조값
  2. 실행 컨텍스트의 이해
  3. 가비지 컬렉션의 이해

1. 원시값과 참조값

  • 원시값은 기본타입(문자열, null, undefined etc), 참조값은 메모리에 저장된 객체(객체의 프로퍼티)

  • 대부분의 언어에서는 문자열을 참조값으로 침 (Ex. Java String)

  • 참조값의 경우 동적 프로퍼티가 가능 (원시값은 불가)

      1) 참조값
      var person = new Object();
      person.name = "snack";
      console.log(person.name); // snack
    
      2) 원시값
      var name = "snack";
      name.age = 29;
      console.log(name.age); // undefined
  • 값을 복사할 경우에도 원시값과 참조값은 서로 다름

      1) 원시값 // 값이 각각 다른 곳에 저장
      var num1 = 1;
      var num2 = num1;
      num1 = 10;
    
      console.log(num1); // 10
      console.log(num2); // 1
    
      2) 참조값 // 힙에 저장된 레퍼런스를 가리키기 때문
      var obj1 = new Object();
      var obj2 = obj1;
      obj1.name = "snack";
      console.log(obj2); // snack
  • 매개변수는 모두 값으로 전달됨

      function setName(obj) {
        obj.name = "snack";
        obj = new Object();
        obj.name = "Gray";
      }
    
      var person = new Object();
      setName(person);
      console.log(person.name); // sanck
    
      /* 
       * setName() 의 매개변수인 obj 가 전역변수인 person 을 가리키기 때문에 반영이 됨
       * obj 가 값이 아니라 참조로 전달되었다면, console.log 가 Gray 가 나왔을 것
       */
  • 원시 타입에서는 typeof 참조 타입에서는 instanceof

2. 실행 컨텍스트와 스코프

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

  • 이 코드 하나로 실행 컨텍스트가 대강 설명이 될 거 같다.

    var color = "blue";
    
    function changeColor() {
      var anotherColor = "red";
    
      function swapColors() {
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
        // swapColors 내부에서는 color, anotherColor, tempColor 전부 접근 가능 
      }
    
      // changeColor 내부에서는 color, anotherColor 만 접근 가능
      swapColors();
    }
    // color 만 접근 가능
    changeColor();
  • 블록 레벨 스코프가 없기에 if, for 같은 제어문은 조심

    if(true) {
      var ex1 = "good";
    }
    
    console.log(ex1); // good;
    --------------------------------
    for(var i=0; i < 10; i++) {
      doSomething(i);
    }
    
    console.log(i); // 10
  • 식별자 검색은 로컬 컨텍스트에서 점점 범위를 넓혀 전역 컨텍스트까지 찾고, 정의되어 있지 않으면 undefined

    var color = "green"
    
    function getColor() {
      var color = "dark";
      return color;
    }
    
    console.log(getColor()); // dark
    // green 을 불러오고 싶다면 window.color

    3. 가비지 콜렉션

  • 필요한 메모리를 자동으로 할당하고 사용하지 않는 메모리는 자동으로 회수

  • 가능한한 최소한의 메모리를 사용해야 페이지 성능을 올릴 수 있으므로 참조가 끝나 필요없어진 데이터는 null 을 할당해 참조를 제거 하는 게 좋음

3.1 표시하고 지우기

  • 가장 널리 쓰이는 방법
  • 변수 전체에 표시를 남기고, 컨텍스트에 있는 변수, 컨텍스트가 참조하는 변수등에 대해 표시를 지움. 이후 표시가 남아있는 변수 삭제 후 메모리 회수

3.2 참조 카운팅

  • 각 값이 얼마나 많이 참조되었는지를 카운팅
  • 참조할 경우 카운팅 증가, 참조 변수에 다른 값을 할당하면 카운팅 감소
  • 상호 참조, 순환 참조의 경우 카운팅이 감소되지 않아 메모리 회수가 안되는 문제가 있을 수도 있음

생각해볼 점
  • 내용은 짧지만, 다루고 있는 내용은 짧다는 느낌이 안 듦
  • 힙, 스택 메모리 영역에 대한 이해가 다시금 필요할 것 같음

'개발 관련 > javascript' 카테고리의 다른 글

7. 함수 표현식  (0) 2022.07.13
6. 객체 지향 프로그래밍  (0) 2022.07.13
5. 참조 타입  (0) 2022.07.13
3. 언어의 기초  (0) 2022.07.13
2. HTML 속의 자바스크립트  (0) 2022.07.13