💿

[JS] 값, 타입, 연산자


컴퓨터 세계에서는 오직 데이터만이 존재한다. 데이터는 모두 일련의 긴 비트로 저장된다.

Value

긴 비트로 된 데이터들을 효율적으로 처리하려면 아무래도 Chunk(덩어리)로 관리하는 것이 좀더 편하다. 자바스크립트에서는 이 덩어리를 값(value)이라고 한다.

Type

Number

말 그대로 Number(숫자)다.

자바스크립트에서는 하나의 숫자 값을 저장하는데 'double precision floating point number'로 알려진 64비트 IEEE-764 형식을 사용한다. 52비트는 숫자를 저장하는데 사용하고, 11비트는 위치를, 1비트는 부호를 저장하는데 사용한다.

분수 표기는 점을 찍어서 할 수 있고, 아주 크거나 아주 작은 숫자는 e 다음 숫자를 추가한 과학적인 표기법을 사용할 수 있다. 예) 9.81, 2.33e8 (2.33 * 10^8)

자바스크립트에는 특별한 세 개의 숫자가 있다. 양과 음의 무한대를 나타내는 Infinity, -InfinityNaN(Not a Number)이다.

NaN(not a number)의 경우 "나 숫자 아니다"의 뜻을 가지지만 숫자 타입의 값이다. 0을 0으로 나누거나, 무한대 빼기 무한대 같은 무의미한 계산의 결과로 이 값을 얻을 수 있다.

이렇게 NaN의 원인이 다를 수 있기 때문에, NaN == NaN을 할 경우 false가 나온다.

String

String은 텍스트를 나타낸다. 자바스크립트에서 문자열(String)은 Unicode 표준(UTF-16)을 따르고, 문자당 16비트를 사용한다. 총 2162^{16}개의 문자를 표현할 수 있다는 의미인데, Unicode는 이것보다 훨씬 많은 문자를 정의하고 있다(한 두배 정도 더 많이). 그렇게 때문에 특정 문자, 예를 들어 이모지는 자바스크립트에서 두 문자만큼 공간을 차지한다. 이렇게 두 문자 차지하는 기호를 'surrogate pair(서로게이트 쌍)'라고 한다.

문자열은 시작과 끝 따옴표를 일치시키기만 한다면 따옴표(single quote), 큰 따옴표(double quote), 백틱(backtick)으로 문자열을 표현할 수 있다.

1`이건 문자열이여`
2
3'이것도 문자열이여'
4
5"이것 또한 문자열이여!"

문자열은 나누기나 곱하기, 빼기는 할 수 없지만 +는 할 수 있다. 물론 덧셈이 아니라 두 문자열을 연결하는 기능(concatenate)을 해준다. 문자열 값은 이 밖에도 여러 연산을 수행하는 데 사용할 수 있는 관련 메소드를 많이 갖고 있다.

백틱을 사용한 문자열은 일반적으로 template literal이라고 부르며, 다른 값을 포함시키는 기능을 할 수 있다.

1`계란 한 판이 9000원인데 5개 사면 ${9000 * 5}원이 필요하네`

위의 예제에서는 "계란 한 판이 9000원인데 5개 사면 45000원이 필요하네"를 얻을 수 있다.

서로게이트 쌍

위에서 두 문자를 차지하는 기호를 서로게이트 쌍이라고 했다. 서로게이트 쌍을 사용해 인코딩한 기호의 길이는 2이다.

1let smile = "😀"
2console.log(smile.length);
3// -> 2
4console.log(smile[0]);
5// -> �

자바스크립트가 만들어졌을 당시엔 서로게이트 쌍이 존재하지 않았어서, 자바스크립트는 서로게이트 쌍으로 표현된 기호를 제대로 처리하지 못한다. 위의 예시가 문제점을 잘 보여준다.

String.fromCodePoint/str.codePointAt은 서로게이트 쌍을 처리할 수 있지만, String.fromCharCode/str.charPointAt은 똑같은 기능을 하지만 서로게이트 쌍을 처리하지 못하는 것도 한 예시다.

서로게이트 쌍은 iterable 객체로 다룰 수 있는데, 이후 다루겠다.

Boolean

truefalse, 두 가지 값을 가지는 타입이다. 비교를 통해서 불리언 값을 만들어낼 수도 있다.

직관적으로 비어있다고 느껴지는 값들(0, NaN, undefined, null, 빈 문자열)은 불린 값으로 변환시 false가 된다.

Empty Values

nullundefined, 두 개의 특별한 값이 있다.

null'존재하지 않는' 값, '비어 있는' 값, '알 수 없는' 값을 나타낸다.

undefined'값이 아직 할당되지 않은 상태'를 나타날 때 사용한다. 변수는 선언했지만, 값을 할당하지 않았다면 해당 변수에 undefined 값이 자동으로 할당된다. undefined를 할당하는 것도 가능하지만, 가능하면 null을 사용해서 undefined는 할당되지 않은 변수의 초기값을 위한 예약어로 남겨두는 것이 나중에 이해하기 좋다.

Object

객체형을 제외한 다른 자료형은 한가지만 표한 가능하기 때문에 원시(Primitive) 자료형이라고 부른다. 반면 객체는 데이터의 모음이나 복잡한 개체(entity)를 표현할 수 있다.

Operator

Unary

하나의 값을 사용한다. 숫자를 부정하는 -, 논리적으로 부정하는 !, 타입을 찾아주는 typeof등이 있다.

typeof 유의점

1typeof undefined
2// -> undefined
3typeof null
4// -> object
5typeof 0
6// -> number
7typeof 10n
8// -> bigint
9typeof true
10// -> boolean
11typeof "foo"
12// -> string
13typeof Symbol("id")
14// -> symbol
15typeof Math
16// -> object
17typeof alert
18// -> function
  • null: typeof null의 결과가 object다. null은 객체가 아니지만, 하위 호환성을 유지하기 위해 이런 오류를 수정하지 않고 남겨둬서 이런 현상이 나타난다. 언어 자체의 오류임을 유의하자.

  • typeof는 피연산자가 함수면 function을 반환한다. 그런데 '함수형'은 없다. 함수는 객체형에 속한다. 이 또한 오래전에 만들어진 규칙이었기 때문에 하위 호환성 유지를 위해 남겨진 상태다.

Binary

두 개의 값을 사용한다. 기본적인 사칙연산과 논리연산(&&, ||), 비교(==, !=, ===, !== 등등)가 있다.

자바스크립트에서 연산자를 잘못된 타입에 적용하면 자기가 알아서 타입을 바꿔 계산해버린다. 이것을 type coercion(강제 형 변환)이라고 한다.

1console.log(8 * null)
2// -> 0
3console.log("5" - 1)
4// -> 4
5console.log("5" + 1)
6// -> 51
7console.log(false == 0)
8// -> true

비교 연산에서 자동 형 변환을 바라지 않으면 ===, !==를 사용할 수 있다. false === 0을 사용하면 위의 예제와는 다르게 false를 얻을 수 있다.

null== 연산에서만 형 변환이 일어나지 않는다.
null == undefined를 수행하면 특별한 규칙이 적용돼 true가 반환된다.

논리 연산자 &&, ||는 다양한 타입의 값을 처리한다. 왼쪽에 있는 값을 불리언 타입으로 변환해 수행할 작업을 결정하지만, 연산자와 변환 결과에 따라 원래의 왼쪽 값이나 오른쪽 값을 반환하게 된다. 예를 들어 || 연산자는 왼쪽 값이 true면 해당 값을 반환하고 그렇지 않으면 오른쪽 값을 반환한다. &&는 이 반대이다.
또 다른 중요한 특성은 필요할 때만 오른쪽 부분을 평가하는 것이다. true || X인 경우, 왼쪽이 참이면 무조건 참이기 때문에 오른쪽 식을 검사하지 않는다. 이것을 short-circuit evaluation이라고 한다.

1console.log(3 || 0);
2// -> 3

Nullish 병합 연산자 ??

a ?? banull이 아니고 undefined도 아니면 a를, 그 외 경우는 b를 반환한다. 피연산자 중 값이 할당된 변수를 찾는 용도로 사용된다. 괄호 없이 ||&&와 함께 사용하지 못한다. 구식 브라우저에서 사용할 경우 폴리필이 필요하다.

Ternary

세 가지 값을 갖는다. (어떤 값) ? 1 : 2 형식으로 쓴다. 예시에서 '어떤 값'이 참이면 왼쪽에 있는 '1'을, 거짓이면 오른쪽에 있는 '2'를 반환한다.


참조:
Eloquent JavaScript
ko.javascript.info