3 minute read

updated at 2022-01-21

Javascript The Definitive Guide - David Flanagan

여기서는 위 서적에서 발견한 몇가지의
내가 몰랐던, 꼭 알아야할, 혹은 알면 좋을,
혹은 사소한 것들을 정리한다.

3.2.4 이진 부동소수점과 반올림 오류

자바스크립트의 실수 표현 범위가 정해져있기 때문에, 우리가 자바스크립트에서 실수를 다룰 때에는, 주로 실제 실수근사치 를 다루게 된다.

Javascript의 IEEE-754 부동소수점 표현은 이진표현이다. 따라서 1/2, 1/4, 1/1024 같은 분수는 정확히 표현할 수 있다. 하지만, 우리가 자주 쓰는 수는 10진수(1/10, 1/100 같은) 이기 때문에, 이진 부동소수점 표현으로는 0.1과 같은 실수를 정확히 표현하지 못한다. 그래서 반올림 오류 와 다음과 같은 상황이 발생한다.

let x = .3 - .2;
let y = .2 - .1;
x === y => false
x === .1 => false
y === .1 => true

만약 실수의 동일성을 검증하는 상황이 발생한다면, 정수로 변환한 후 검증하는 방법을 고려해야한다.

3.2.5 BigInt

ES2020에서 새로운 숫자형 BigInt 가 도입되었다. 64-비트 정수 표현을 지원하기 위해서이다. (BigInt는 timing-attack을 방지하지 않아 암호화에는 적합히지 않다.)

BigInt는 소문자 n이 뒤따라오는 문자열로 쓰여진다. 십진수가 기본이지만, 2, 8, 16진수 표현도 지원한다. BigInt() 를 이용하여 일반 자바스크립트 숫자나 문자열을 BigInt값으로 변환할 수 있다. 나머지를 구하거나, 반내림 연산을 제외한 모든 연산을 일반 숫자와 같이 수행할 수 있다.

BigInt와 일반 숫자를 섞어서 연산해서는 안된다. 어느한쪽이 다른 한쪽의 자료형을 포함하는 경우에는, 더 표현 범위가 넓은 쪽으로 형변환 이 일어나지만, 자바스크립트 실수와 BigInt는 서로 표현범위가 다른 자료형이기 때문에 두 숫자를 섞어서 연산하면 제대로 연산이 이루어지지 않는다.

비교 연산자는 일반 숫자와 BigInt 간에 제대로 작동한다. 또한 비트연산 도 작동한다.
하지만 Math 객체의 메소드는 BigInt와 사용할 수 없다.

3.3 Text

string 은 불변의 16비트 값(Unicode character)들의 연속이다.

Javascript는 UTF-16 인코딩을 사용한다. 그리고 자바스크립트 문자열은 unsigned 16-bit 값들의 연속이다. 16비트 인코딩으로 모자란 UTF-16 문자들도 있는데, 이들은 2개의 UTF-16 문자의 짝으로 인코딩된다. 이는 하나의 유니코드 문자를 자바스크립트로 문자로 표현하더라도, 이 문자열의 길이는 2 가 될 수도 있다는 말이다.

자바스크립트에서는 원래 이렇게 문자열을 다룰 때 16비트 값들로 나누어서 문자열을 다루는데,
ES6 부터는 문자열이 순회가능한 객체이고, for/of, … 연산자를 사용하면 16비트 기준이 아니라 실제 문자 단위로 접근할 수 있게 되었다.

3.3.1 String Literals

"one\
long\
line"
이렇게 여러 줄에 걸쳐  문장을   있다.

`the newline
this is newline`
백틱을 사용하면 줄바꿈 문자가 그대로 들어간다.

3.3.3 문자열 다루기

몇가지 새로알게된 문자열 메소드들.

  • .normalize(): 유니코드 정규화
  • .charCodeAt(): 특정 인덱스의 16비트 코드를 반환한다.
  • .padStart, padEnd(몇칸, 어떤문자): 문자열의 앞/뒤에 특정문자나 공백을 삽입한다.

문자열은 불변이므로 문자열을 변형하는 메소드들은 새로운 문자열을 반환한다.

3.3.4 템플릿 문법

Tagged template literals

만약 함수 이름이 여는 백틱 앞에 오면, 그 문자열과 표현식의 값들이 그 함수의 파라미터로 넘겨진다. 이는 html, sql 등의 문자열을 처리하는데 사용될 수 있다.(graphql에도 사용된다.)
다음처럼 쓴다.

String.raw`\n`.length => 2

3.9.2 명시적 형변환

몇몇 명시적 형변환에 사용되는 메소드와 함수들.

number to string
let n = 1234.234;
n.toFixed(0) => "1234"
n.toExponential()
n.toPrecision()

parseInt()
parseFloat()

3.9.3 객체의 원시형 변환

자바스크립트 객체를 원시타입의 자료로 형변환을 하는 경우가 있다. 이런 경우에 3가지 근본적인 알고리즘을 사용해서 객체를 원시 자료값으로 바꾸게 된다.

  • prefer-string: 이 알고리즘은 문자열 타입을 선호하여, 만약 문자열로 변환이 가능하면 문자열을 반환한다.
  • prefer-number: 이 알고리즘은 실수 타입을 선호하여, 만약 실수로 변환이 가능하면 실수를 반환한다.
  • no-preference: 이 알고리즘은 선호하는 타입이 없다. 자바스크립트의 내장 타입들 중에서는, Date 클래스를 제외한 모든 타입들이 이 타입을 prefer-number 로 적용한다. Date 클래스는 이를 prefer-string 으로 적용한다.

객체 -> 불리언 변환

모든 객체는 true 값으로 변환된다.

객체 -> 문자열 변환

객체가 문자열로 변환될 필요가 있을 때에, 자바스크립트는 먼저 prefer-string 알고리즘을 이용해 원시자료형으로 변환하고, 반환되는 값을 문자열로 변환한다.

객체 -> 실수 변환

객체가 실수로 변환될 필요가 있을 때에, 자바스크립트는 먼저 prefer-number 알고리즘을 이용해 원시자료형으로 변환하고, 반환되는 값을 실수로 변환한다.

특수한 경우의 연산자를 이용한 변환

+, ==, !=, <, > 등의 연산자를 이용할 때 암시적으로 형변환이 일어나거나, 일어나도록 의도하는 경우가 있지만, 이는 좋지 않은 프로그래밍 방법이라 생각한다.

toString, valueOf method

모든 객체는 객체를 원시형으로 변환하기위 한 두가지의 메소드를 상속받는다.

  • toString() 메소드는 객체의 문자열 표현을 반환한다.
  • valueOf() 메소드는 어떠한 원시 자료형이라도 존재하면, 객체의 원시 자료값을 반환한다. 객체는 여러값이 합성된 값이고, 따라서 대부분의 객체는 단 하나의 원시 자료값으로 표현될 수 없다. 그래서 객체의 valueOf() 메소드의 기본 반환값은 원시 자료형 보다는 객체 자신이다.

변수와 상수의 스코프

선언이 코드의 최상부에 위치하면 그것을 전역 변수 가 된다. Node와 client-side Javascript module 에서는 전역변수의 스코프가 선언된 파일이 된다. 전통적인 client-side Javascript에서는, 선언된 HTML document 가 스코프가 된다.