morijwana
수로그
morijwana
전체 방문자
오늘
어제
  • 분류 전체보기
    • 강의노트
    • Machine Learning
      • Pandas
      • NLP
    • Computer Science
      • Linux
      • TIL
    • Development
      • React
      • Swift
      • Javascript
    • 스터디 기록
      • Clean Code
      • 구글 BERT의 정석
      • 개발도서
      • 기타
    • Problem Solving
      • Baekjoon
      • ICPC Sinchon
    • 끄적
      • 끄적끄적
      • 요리왕

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Solution Challenge
  • cs224n
  • Pandas
  • 프로그래밍언어론
  • 프레임워크없는프론트엔드개발
  • 회고
  • 자연어처리
  • ML
  • 민트하임스터디
  • word2vec
  • Bert
  • GDSC Sookmyung
  • 구부정스터디
  • 구글BERT의정석
  • 데이터사이언스
  • nlp
  • 개발도서
  • gdsc
  • Python
  • 백준

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
morijwana

수로그

Development/Javascript

[2021 겨울 민트하임 스터디] You don't know JS - Chapter 2: 값

2021. 1. 24. 22:11

Chapter 2: 값

2021.1.24(일)
책: You don't know JS

배열 vs 유사 배열

자바스크립트의 배열

  • 어떤 타입의 값이라도 담을 수 있다. 배열 안에 배열도 넣을 수 있다(다차원 배열).
  • 배열 크기 미리 선언할 필요 없다.
  • 배열 인덱스는 숫자지만, 배열 자체가 하나의 객체이므로 키/프로퍼티 문자열을 추가할 수 있다.
    • 이렇게 추가한 경우 length가 늘어나지 않는다.
    • key가 숫자일 경우 문자열 키가 아닌 숫자 키(인덱스)를 사용한 것과 같은 효과가 일어난다. 뭔소리냐면
      var a = [];
      a["13"] = 42;
      a.length; //     14 -> ?
    • 배열에 문자열 타입 키/프로퍼티를 두는 것은 피해야 한다. 키를 사용해야 한다면 객체를 대용하고, 배열 원소의 인덱스로는 숫자만 쓰도록 하자

유사 배열

  • 직접 배열 리터럴로 선언한 array가 아닌, 숫자 인덱스가 가리키는 값들의 집합을 유사 배열이라고 한다.
    • []로 감싸져있지만 배열이 아닌 친구들을 유사 배열이라고 생각하면 된다.
  • Array.isArray() 메서드를 통해 배열인지 유사 배열인지 구분할 수 있다.
  • ES6부터는 기본 내장 함수 Array.from()을 통해 유사 배열을 배열로 변환할 수 있다.
  • call() 또는 apply()를 통해 배열로 변환하지 않고도 배열 메서드를 빌려쓸 수 있다.
    Array.prototype.forEach.call(nodes, function(el) { console.log(el); });
    [].forEach.call(els, function(el) { console.log(el); });
    // 출처: https://www.zerocho.com/category/JavaScript/post/5af6f9e707d77a001bb579d2

 

문자열 vs 문자 배열

  • 자바스크립트 문자열은 문자 배열과 다르다.
    let a = "foo"; 와 let b = ["f", "o", "o"];는 다르다.
  • 문자열은 불변값이지만 배열은 가변값이다.
    • 문자열은 불변값이므로 문자열 메서드는 항상 새로운 문자열을 생성한 후 명령을 수행한 뒤에 반환한다.
    • 반면에, 배열 메서드는 그 자리에서 바로 원본을 수정한다.
  • 문자열을 다룰 때 유용한 대부분의 배열 메서드는 사실상 문자열에 쓸 수 없지만, 문자열에 대해 불변 배열 메서드를 빌려 쓸 수는 있다.
    • reverse() 등의 가변 배열 메서드는 빌려쓸 수도 없다. 이럴 때에는 문자열을 split()으로 배열로 분할해준 다음 가변 배열 메서드를 사용하고 다시 합쳐주는 꼼수를 쓰면 된다. 😌
    • let a = "foo"; a.join("-"); // undefined a.map( /* ... */ ) // undefined let c = Array.prototype.join.call(a, "-"); let d = Array.prototype.map.call(a, (v) => { v.toUpperCase() + "."; }).join(""); c; // "f-o-o" d; // "F.O.O"

 

자바스크립트의 정신나간 숫자 비교

0.1 + 0.2 === 0.3; // false -> ?

이진 부동 소수점으로 나타낸 0.1과 0.2는 원래의 숫자와 일치하지 않는다. 그러니까 0.1과 0.2를 더해도 0.3이 아닌 0.30000000000000004에 가깝게 계산된다. 0.3 !== 0.30000000000000004이니 false가 맞긴 한데.. 글킨한데.. 이게맞나..

그러면 대체 어떻게 해야 0.1 + 0.2가 0.3과 같다는 결과를 얻을 수 있을까

보통 '반올림 오차'를 허용 공차로 처리하는 방법을 사용한다고 한다. 이렇게 미세한 오차를 '머신 입실론(컴퓨터가 이해할 수 있는 가장 작은 숫자 단위)'라고 하는데, 자바스크립트 숫자의 머신 입실론은 2^-52(Number.EPSILON으로 정의되어 있음)이다.
그러니.. 0.1 + 0.2와 0.3의 차이가 2^-52 이하힐 때 true를 반환하도록 하면 된다.

function numbersCloseEnoughToEqual(n1, n2) {
  return Math.abs(n1 - n2) < Number.EPSILON;
} 

근데 정말 이렇게까지 해야하는 걸까? 왜 다른 부동 소수점을 사용하는 언어들은 관련 이슈가 없을까?(있는데 내가 모르는 것 같다)

 

JS의 '특별한' 값들

  • undefined 타입의 값은 undefined 뿐이고, null 타입의 값은 null 뿐이다.
    • 느슨한 모드에서의 전역 스코프에서 undefined라는 식별자에 값을 할당할 수 있다.
  • void 연산자는 뒤에 오는 값을 undefined로 만들어 버린다.
    • 어떤 표현식의 반환값이 없다는 걸 확실하게 밝혀야 할 때 사용한다.
  • NaN: 나 숫자 아니다
    • NaN은 어떤 다른 NaN과도 같지 않다. NaN !== NaN이다.
    • 그러면 해당 변수가 NaN을 담고 있는지 어떻게 아는가...
      • 1) 내장 전역 유틸리티 함수 isNaN() -> X
        정말로 '인자 값이 숫자인지 여부만 평가'하므로 해당 변수가 NaN인지는 알 수 없다. window.isNaN("foo");의 경우에도 true를 뱉는다.
      • 2) Number.isNaN() -> O
        안전하게 NaN 여부를 체크할 수 있다. Number.isNaN("foo");에서 false를 반환한다.
  • DivisionByZeroError따위 자바스크립트에 없다. 자바스크립트에는 Infinity가 있다.
    • 무한대 나누기 무한대는 NaN이다.
  • +0도 있고... -0도 있다.
    • -0은 왜 존재하는가
      • "+0, -0 개념이 없다면 어떤 변숫값이 0에 도달하여 부호가 바뀌는 순간, 그 직전까지 이 변수의 이동 방향은 무엇인지 알 수가 없으므로 부호가 다른 두 0은 유용하다"라고 한다. 잠재적인 정보의 소실을 방지하기 위해 부호를 붙이는 것이다.

 

값-복사, 레퍼런스-복사는 값의 타입에 의해 결정된다

자바스크립트에는 값 또는 레퍼런스의 할당 및 전달을 제어하는 구문 암시(포인터 등)이 전혀 없다. 대신, 값의 타입만으로 값-복사, 레퍼런스-복사 둘 중 한쪽이 결정된다. 값-복사냐 레퍼런스-복사냐를 우리 맘대로 결정할 수 없다. 이 둘을 결정하는 것은 값의 타입이므로, 타입을 잘 정하는 방법밖에 없다.

원시 값은 불변하다는 특성이 있다는 걸 기억해두면 원시 값 할당 및 전달은 값-복사로 실행된다는 걸 기억하기 편할 것 같다. developer.mozilla.org/ko/docs/Glossary/Primitive#javascript

  • 값-복사: null, undefined, string, number, boolean, symbol 등의 단순 값(원시 값)
  • 레퍼런스-복사: 객체나 함수 등의 합성 값
저작자표시 (새창열림)

'Development > Javascript' 카테고리의 다른 글

[2021 겨울 민트하임 스터디] You don't know JS - Chapter 4: 강제변환(1)  (2) 2021.02.07
[2021 겨울 민트하임 스터디] You don't know JS - Chapter 3: 네이티브  (6) 2021.02.04
[2021 겨울 민트하임 스터디] You don't know JS - Chapter 1: 타입  (0) 2021.01.24
    'Development/Javascript' 카테고리의 다른 글
    • [2021 겨울 민트하임 스터디] You don't know JS - Chapter 4: 강제변환(1)
    • [2021 겨울 민트하임 스터디] You don't know JS - Chapter 3: 네이티브
    • [2021 겨울 민트하임 스터디] You don't know JS - Chapter 1: 타입
    morijwana
    morijwana
    행복한 휴학생의 devlog

    티스토리툴바