ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 230215 30분 TIL
    하루 30분 TIL 2023. 2. 15. 12:48

    가비지 콜렉터란?

     

    애플리케이션이 할당한 메모리 공간을 주기적으로 검사하여 더 이상 사용되고 있지 않는 메모리를 해제하는 기능을 말한다. 자바스크립트는 가비지 콜렉터를 내장하고 있는 매니지드 언어로서 가비지 콜렉터를 통해 메모리 누수를 방지한다.

     

    자바스크립트 데이터 타입(자료형)

     

    자바스크립트는 7개의 데이터 타입을 제공한다.
    데이터 타입은 원시타입(primitive type)과 객체타입(reference type)으로 분류할 수 있다.


    1. 원시 타입

    • 숫자(number)
    • 문자열(string)
    • 불리언(boolean)
    • undefined
    • null
    • symbol : 변경 불가능한 원시타입의 값, 다른 값과 중복되지 않는 유일무이한 값 ⇒ 충돌 위험이 없는 객체에 유일한 프로퍼티 키를 만들기 위해 사용한다.

    2. 객체 타입

    • 객체, 함수, 배열 등

     

    undefined와 null의 차이점

     

    undefined는 개발자가 의도적으로 할당하기 위한 값이 아니라 자바스크립트 엔진이 변수를 초기화할 때 사용하는 값이다. 그래서 변수를 참조했을때 undefined가 반환된다면 초기화하지 않은 변수라는 것을 알 수 있다.

     

    null은 변수에 값이 없다는 것을 의도적으로 명시할 때 사용한다. (의도적 부재) 이는 이전에 할당되어 있던 값에 대한 참조를 명시적으로 제거하는 것을 의미하며, 자바스크립트 엔진은 누구도 참조하지 않는 메모리 공간에 대해 가비지 콜렉션을 수행한다.

     

    자바스크립트의 number 타입은 다른 언어와 차이점이 무엇인가?

     

    다른언어는 다양한 숫자 타입이 있지만, JS number 타입은 모든 수를 실수로 처리한다.

     

    정적타입언어 vs 동적타입언어

     

    C나 자바같은 정적타입언어는 변수의 타입을 변경할 수 없으며, 변수에 선언한 타입에 맞는 값만 할당할 수 있다. 정적 타입 언어는 컴파일 시점에 타입 체크를 수행한다. 만약 타입 체크를 통과하지 못했다면 에러를 발생시키고 프로그램 실행 자체를 막는다. 이를 통해 일관성을 강제함으로써 더욱 안정적인 코드의 구현을 통해 런타임에 발생하는 에러를 줄인다.

     

    정적타입언어는 변수 선언 시점에 변수의 타입이 결정되고, 변수의 타입을 변경할 수 없다. 하지만 동적타입언어인 JS는 선언이 아닌 할당에 의해 타입이 결정되고, 재할당에 의해 변수의 타입이 동적으로 변할 수 있다.

     

    • 동적타입언어의 단점
      • 변수의 값을 추적하기 어렵다.
      • 유연성은 높지만 신뢰성은 떨어진다.

    순수 함수

     

    부수 효과가 없는 함수, 동일한 인수가 전달되면 언제나 동일한 값을 반환하는 함수이다. 즉, 어떤 외부 상태에도 의존하지 않고 오직 매개변수를 통해 함수 내부로 전달된 인수에게만 의존해 반환값을 만든다.

     

    순수함수의 또 하나의 특징은 함수의 외부 상태를 변경하지 않는다는 것이다. 즉, 순수 함수는 어떤 외부 상태에도 의존하지 않으며 외부 상태를 변경하지도 않는 함수이다.

    var count = 0;
    
    // 순수 함수 increase는 동일한 인수가 전달되면 언제나 동일한 값을 반환 
    function increase(n) {
      return ++n;
    }
    
    count = increase(count);
    console.log(count); // 1
    
    count = increase(count);
    console.log(count); // 2
    var count = 0;
    
    // 비순수 함수
    function increase() {
      // 외부 상태에 의존하여 외부 상태를 변경
      return ++count;
    }
    
    // 비순수 함수는 외부 상태(count)를 변경하므로 상태 변화를 추적하기 어려워진다.
    increase();
    console.log(count); // 1
    
    increase();
    console.log(count); // 2

     

     

    • 원시 타입(primitive type)

    원시 타입의 값, 즉 원시값은 변경 불가능한 값(immutable value)이다.

    원시값을 변수에 할당하면 변수에는 실제값이 저장된다.

    원시값을 갖는 변수를 다른 변수에 할당하면 원본의 원시값이 복사되어 전달된다. 이를 값에 의한 전달(pass by value)이라 한다.

     

    • 객체 타입(reference type)

    객체는 변경 가능한 값(mutable value)이다.

    객체를 변수에 할당하면 변수에는 참조값이 저장된다.

    객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조값이 복사되어 전달된다. 이를 참조에 의한 전달(pass by reference)이라 한다.

     

    • 객체가 변경 가능한 값으로 설계된 이유

    객체는 원시값처럼 크기가 일정하지 않아서, 복사해서 생성하는 비용이 많이든다. 즉, 메모리를 효율적으로 사용하기 어렵다. 따라서 객체는 객체를 복사해 생성하는 비용을 절약하기 위해서 변경 가능한 값으로 설계되었고, 이로인해 여러 개의 식별자가 하나의 객체를 공유한다는 구조적인 단점을 안고있다.

     

    • 참조에 의한 전달(pass by reference)의 부작용

    객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조값이 복사되어 전달되는데, 이때 두 객체는 저장된 메모리 주소는 다르지만 동일한 참조값을 갖는다. 즉, 두 객체는 동일한 객체를 가리킨다. 따라서 원본 또는 사본 중 어느 한쪽에서 객체의 프로퍼티 값을 변경하거나 삭제하면 서로 영향을 주고 받는다.

     

    • 참조에 의한 전달 부작용 해결방법

    객체를 불변 객체로 만들어 사용한다. 객체의 복사본을 새롭게 생성하는 비용은 들지만, 객체를 마치 원시값처럼 변경 불가능한 값으로 동작하게 만드는 것이다. 객체의 상태 변경이 필요한 경우에는 객체를 깊은 복사(Deep copy)를 통해 새로운 객체를 생성하고 재할당을 통해 교체한다. 이를 통해 외부 상태가 변경되는 부수 효과를 없앨 수 있다.

     

     

     

    전역변수, 지역변수

    var x = 'global';
    function ex() {
      var x = 'local';
      x = 'change';
    }
    ex(); // x를 바꿔본다.
    alert(x); // 여전히 'global'
    • 전역변수란 제일 바깥 범위인 최상단 범위에 만든 변수를 뜻한다 여기서는 x가 전역변수이다. 지역변수란 함수 안에 들어있는 변수를 뜻한다. 여기서 ex함수 내의 x변수에 해당한다.

    위의 상황에서 지역변수는 아무리 해도 전역 변수에 영향을 끼칠 수 없는데 바로 함수 스코프 때문이다

    스코프(scope)

    var x = 'global';
    function ex() {
      x = 'change';
    }
    ex();
    alert(x); // 'change'
    • 스코프는 범위란 뜻으로 함수 안에서 선언된 변수는 함수 안에서만 쓸 수 있다
      그렇기에 위의 예에서 var x= 'local'은 함수 내에서만 쓸 수 있으며 밑은 x='change'또한 함수 안의 지역변수 x를 바꾸는 것이다.
    • 하지만 밑의 예는 위와 달리 함수 안에서 변수를 선언하지 않았기 때문에 이제 x='change'로 전역변수가 바뀌게 된다.
    • 그 이유는 자바스크립트는 변수의 범위를 호출한 함수의 지역 스코프부터 전역 스코프까지 점차 넓혀가며 해당 변수를 찾기 때문이다. 바로 이 개념이 스코프 체인(scope chain)이다.

     

    렉시컬 스코핑(lexical scoping)

    ✅ 여기서 주의 스코프는 함수가 호출 될 때가 아닌 선언됐을 때 형성된다. 그래서 정적스코프라고 불린다.

    var name = 'zero';
    function log() {
      console.log(name);
    }
    
    function wrapper() {
      var name = 'nero';
      log();
    }
    wrapper();
    • log함수는 호출될 때가 아닌 선언될 때 이미 스코프가 형성이 되었고 해당 스코프에서 스코프체인을 통해 전역변수 name을 찾아 반환한다. 결국 wrapper 함수 안에서 log를 호출해도 var name = 'nero'를 참조하는 것이 아닌 그대로 전역변수 name의 값 zero가 된다.

    자바스크립트 언어는 동적언어지만, 유효범위는 코드가 작성되는 순간 정해지는 정적인 특성을 가진다. 다시한번 정리하면, 함수안에서 정의된 변수는 함수 밖으로 빠져나갈 수 없다는 것이 핵심이다.

    '하루 30분 TIL' 카테고리의 다른 글

    230217 30분 TIL  (0) 2023.02.17
    230216 30분 TIL  (0) 2023.02.16
    230214 30분 TIL  (0) 2023.02.14
    230209 30분 TIL  (0) 2023.02.10
    230116 30분 TIL (Proxy)  (0) 2023.01.16

    댓글

Designed by Tistory.