자바스크립트 deep dive - week 1

하머·2022년 11월 1일
0
post-thumbnail
  • 4장에서 7장까지의 내용을 담았습니다.
  • 각 장 마다 내용을 간단히 정리하고 추가 사항이나 궁금증이 있다면 추가적으로 검색해 적었습니다.
  • 업로드된 사진이 문제될 경우, 요청 시 지우도록 하겠습니다.

느낀점과 새로 알게된 내용들

  • 변수 부분을 정리하며 메모리와 실행컨텍스트, 가비지 컬렉터 등 추상적으로 기억하고 있는 부분들(2진수, 런타임, var/let/const 차이, 가비지 컬렉션 조건)을 명확하게 정리할 수 있어서 좋았다.

  • 숫자 타입에서 0.1 + 0.2 === 0.3을 비교할 때 false가 나오는 것은 알고있었지만 '왜' 다른지 몰랐고, 윈도우 설치할 때도 '왜' 32비트는 4기가까지 인식할 수 있는지 몰랐다. 하지만 이번 기회에 궁금해져서 찾아보았고 정답을 알 수 있었다. 늘 궁금증을 가지는 개발자가 되어야 겠다.

  • 중간에 리팩토링의 저자의 말을 인용해 사람이 이해할 수 있는 코드를 짜야한다고 쓰여져 있는 부분이 마음에 걸린다. 나는 과연 다른사람이 봤을 때 이해할 수 있는 코드를 짜는걸까... 앞으로는 이부분을 명심해야겠다는 생각이 든다

  • 기초를 다지는 것이 성장의 가장 빠른 방법이라고 믿고 있다. 여기에서도 자바스크립트의 메모리 관리 및 클린 코드에 필요한 개념들이 전부 적혀져 있다. 주니어에서 미드레벨로 넘어가기 원한다면 결국 기초를 다지는 것이 가장 빠른방법임을 다시금 상기 시켰다.


4. 변수

  • 변수란 무엇인가

    • 컴퓨터는 모든 데이터를 2진수(1비트)로 처리하고, 저장되는 데이터(값)의 주소는 16진수로 나타내어 ((32bit, 4GB) 0x00000000 ~ 0xFFFFFFFF) 로 나타난다.

    • 추가 - 윈도우 32비트와 64비트의 차이

      • 32비트 os는 cpu가 최대 32비트만큼을 가져와 연산하는데 그것이 위의 0xFFFFFFFF = 2의 32승 = 4,294,967,295 이다. 32비트 프로그램에서의 최대 정수값이 2147483647인 이유 이기도 하다. (예 : 스타크래프트 최대 값, 유튜브 강남스타일 조회수)

      • 이전에 윈도우 설치 시 4기가를 넘기면 64비트로 설치하라는 것을 보고 왜 그런지 모른채 설치를 했었는데 책의 내용 중 0xFFFFFFFF가 무슨 뜻인지 이해하기 위해 검색을 함으로써 그 이유를 알았다.

    • 컴퓨터는 값을 저장한 메모리 셀을 재사용하기 위해 변수를 사용해 다시 가져오는데, 변수는 값을 저장한 메모리 자체 또는 메모리 주소를 식별하기 위해 붙인 이름(식별자)을 뜻한다.

      • 왜 메모리 주소를 직접 참조하지 않는가 => 자바스크립트는 값이 저장될 메모리 주소를 코드가 실행될 때 메모리의 상황에 따라 임의로 결정한다. (실행 컨텍스트) 따라서 동일 컴퓨터, 동일 코드를 실행하면 값이 저장될 메모리 주소가 변경되므로 올바른 방법이 아니다

      • 식별자는 변수, 함수, 클래스 등 변수 이름에만 국한해서 사용되지 않고 메모리 상에 존재하는 값을 식별할 수 있는 이름은 모두 식별자라고 부른다.

  • 자바스크립트의 변수 선언

    • 선언 단계란

      • 선언을 통해 변수 이름을 실행 컨텍스트에 등록하고, 메모리 셀과 연결시켜준다.
    • 초기화 단계란

      • 메모리 셀에 값을 넣어준다. (초기 할당)
    • var

      • 선언과 초기화가 동시에 이루어짐
      • 선언문에서 할당할 경우 초기화 단계에서 undefined로 할당된 뒤 할당됨, 사실상 재할당
      var foo; // undefined 할당
      foo = 1 // 1 재할당
      
      var foo = 1; // 위와 똑같이 동작한다.
    • let

      // 시간상 사각지대(TDZ) 시작
      console.log(name) // ReferenceError: name us not defined
      
      // 시간상 사각지대(TDZ) 끝
      let name = "hayeong";
      console.log(name) // expected result: "hayeong"
    • const

      • 선언과 초기화가 동시에 일어나지만 재할당과 런타임이전 실행이 불가능하다.
      • 변수에 저장된 값을 변경할 수 없다면 변수가 아니라 상수(constant)라고 하는데 상수는 한번 정해지면 다시 변하지않는, 한번만 할당할 수 있는 변수를 뜻한다.
      console.log(name) // ReferenceError: Cannot access 'name' before initialization
      
      const name = "hayeong";
  • 변수 할당과 호이스팅

    • 실행 컨텍스트에서 변수 선언과 런타임은 따로 되어있고 스코프(렉시컬 환경의 환경 레코드)에 선언이 먼저 된 뒤, 런타임으로 넘어가기 때문에 호이스팅이 가능하다.
  • 가비지 컬렉터

    • 도달 가능성을 판단해 도달 가능성이 없다면 메모리 연결을 해제하는 자바스크립트 엔진의 메모리 관리법 => 코드에서 직접적으로 명시하여 메모리를 해제할 수 없음

    • 참조-세기 알고리즘을 통해 도달 가능성을 판단함

    • 한계: 순환 참조

      // x와 y 모두 참조되므로 메모리가 해제되지 않고 누수가 일어나는 순환 참조의 예
      function f() {
         var x = {};
         var y = {};
         x.a = y;         // x는 y를 참조합니다.
         y.a = x;         // y는 x를 참조합니다.
      
         return "azerty";
       }
      
       f();

5. 표현식과 문

    • 값이란 식(표현식)이 평가되어 생성된 결과

    • 모든 값은 데이터 타입을 가지며 메모리에 2진수, 비트의 나열로 저장된다.

      데이터 타입에 따라 비트의 나열은 다르게 해석된다.

      ex) 0100 0001은 데이터 타입에 따라 65와 "A"로 다르게 해석된다.

  • 리터럴

    • 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하기 위해 미리 약속한 표기법
  • 표현식

    • 표현식은 값으로 평가될 수 있는 문, 표현식이 평가되면 새로운 값을 생성하거나 기존값을 참조한다.
    • 문은 프로그램을 구성하는 기본 단위이자 최소 실행단위
    • 문은 여러 토큰으로 구성되는데 토큰이랑 문법적인 의미를 가지고 더이상 나눌 수 없는 코드의 기본요소
    • 문의 종료는 세미콜론으로 나타난다. 자바스크립트 엔진은 소스코드를 해석할 때 문의 끝이라고 예상되는 지점에 자동삽입 기능이 있어서 붙이지 않아도 되지만 eslint나 ecmascript 기술 위원회 등에서는 세미콜론 사용을 권장한다.
    • 표현식인 문과 표현식이 아닌 문의 차이는 변수 할당 가능 여부
    var foo = var x; // 변수 선언문은 값처럼 사용할 수 없다.
     var y;
     var bar = y = 100; // 표현식인 문은 값처럼 사용할 수 있다.

6. 데이터 타입

  • 원시 타입과 객체 타입

    • 원시 타입
      • number
      • string
      • boolean
      • undefined
      • null
      • symbol
    • 객체 타입
      • object, function, array
  • 숫자 타입

    • 자바의 경우 정수를 나타내는 int, long과 실수를 나타내는 float, double이 있지만 자바스크립트는 단 한가지의 숫자 타입을 가진다.

    • 모든 수를 실수로 처리하고 배정밀도 64비트 부동소수점 형식의 2진수로 저장된다. 뜰 부에 움직일 동 이라는 뜻의 부동소수점은 정확하지 않고 움직인다.

    // 2진수, 8진수, 16진수 모두 값을 참조 시 10진수로 해석된다.
    0b01000001 === 0o101 === 0x41 === 65 // true
    // 소수를 일반적으로 비교하였을 때
    (0.1 + 0.2) === 0.3 // false
    // 정확히 계산하여 비교하는 법
    (0.1 + 0.2).toFixed(1) === 0.3 // true
    • 십진법 소수를 이진법으로 나타내는 방법
    • 세가지 특별한 값
    console.log(10 / 0); // Infinity
    console.log(10 / -0); // -Infinity
    console.log(1 * "String"); // NaN = 산술 연산 불가(Not a Number)
  • 문자열 타입

    • 유니코드 문자 UTF-16 의 집합으로 전세계의 대부분의 문자를 표현할 수 있음
    • c와 자바와 다르게 문자열을 원시 타입으로 두고 변경 붉가능한 값(immutable value)로 둔다.
  • 템플릿 리터럴

    • 백틱으로 표현되며 이스케이프를 사용하지 않고도 줄바꿈이 허용되고 ${}으로 표현식을 나타낸다.
  • undefined 과 null 타입

    • null 과 undefined 비교 => 정의되지 않았다는 뜻의 undefined는 의도적으로 값을 비운 null과 다르므로 undefined를 변수에 할당하지 않도록 하자
    • 변수에 null을 할당할 경우 이전 참조를 제거 하므로 해당 변수가 도달 가능성이 없다면 가비지컬렉터가 값을 지운다
  • 심벌 타입

    • 외부로 노출 되지 않아 확인할 수 없으며 다른값과 절대 중복되지 않는 유일무이한 값
    • 이름의 충돌 위험이 없는 유일한 프로퍼티 키를 만들기 위해 사용된다.
  • 데이터 타입의 중요성

    • 변수에 할당되는 값의 데이터 타입에 따라 메모리 공간의 크기가 결정하기 위해
    • 값을 참조할 때 한번에 읽어들여야 할 메모리 공간의 크기를 결정하기 위해
    • 메모리에서 읽어 들인 2진수를 어떻게 해석할지 결정하기 위해
  • 동적 타이핑

    • 자바스크립트는 데이터타입을 선언하지 않는다. 미리 선언한 데이터 타입의 값만 할당할 수 있는 정적 타이핑 언어들과 달리 어떤 데이터 타입이라도 자유롭게 할당 할 수 있다.

    • 즉 자바스크립트의 변수의 데이터 타입은 할당 된 이후에, 할당에 의해 타입이 결정되고 추론 가능해 진다. 또한 재할당으로 인해 변수의 타입은 언제든지 동적으로 변할 수 있다. 이를 동적 타이핑이라고 한다.

    • 변수는 타입을 갖지 않지만, 값은 타입을 갖는다. 현재 변수의 값에 의해 변수의 타입이 동적으로 바뀐다.

    => 자바스크립트의 특징: 유연성은 높지만 신뢰성은 떨어지므로 오해를 가지기 쉬워진다. 오해는 커뮤니케이션을 어렵게하고 생산성을 떨어트리고 팀의 사기를 저하시킨다.

    => 즉 컴퓨터가 이해하는 코드가 아닌 사람이 이해할 수 있는 코드를 써야한다.

    컴퓨터가 이해하는 코드는 어떤 바보도 쓸 수 있다. 하지만 훌륭한 프로그래머는 사람이 이해할 수 있는 코드를 쓴다. - 마틴 파울러 <리팩토링>의 저자


7. 연산자

새로 알게된 내용만 적겠습니다.

  • 연산자의 뜻

    • 연산자는 하나 이상의 표현식을 대상으로 연산하여 새로운 값을 만든다.
    • 피연산자가 값이라는 명사의 역할이라면 연산자는 동사의 역할.
  • 일치 비교 연산자

    NaN === NaN; // false, Number.isNaN을 사용하도록 하자
    
    0 === -0; // true 
    Object.is(-0, +0) // false
  • 삼항 연산자와 if ... else 문의 차이

    • 삼항 연산자 표현식은 값처럼 사용할 수 있지만 if ... else 문은 값처럼 사용할 수 없다.
    • 조건에 따라 어떤 값을 결정해야한다면(수행해야 할 문이 하나면) 삼항연산자
    • 조건에 따라 수행해야 할 문이 여러 개라면 if ... else 문
  • typeof 연산자

    • typeof null의 경우 object를 반환하므로 값이 null 타입인지 확인할 때는 typeof 연산자보다는 일치 연산자(===)를 사용하자 ECMA에서는 에러이지만 수정하지 않는다고 한다.
    • 선언하지 않은 식별자의 경우 에러를 일으키지 않고 undefined를 반환한다.
  • 지수 연산자

    • Math.pow 대신 지수연산자를 쓰면 가독성을 올릴 수 있다.

0개의 댓글