본문 바로가기
IT/JavaScript & TypeScript

[JavaScript] 타입

by 저당단 2025. 10. 21.

1장 내용.

 

원시 타입

  • 7가지가 있으며, 객체와 달리 속성이나 메서드를 가지고 있지 않다.
  • 하지만 대응하는 래퍼 객체가 존재하기 때문에 속성을 사용 가능하다.
  • 예를 들어 "doringri"라는 문자열은 String이라는 래퍼 객체가 존재하기 때문에 .length 속성을 사용 가능하다.

 

Number

  • 자바스크립트는 정수와 부동소수점을 구분하지 않기 때문에 1과 1.0은 같은 값이다.
  • 내부적으로 배정밀도(64비트) 부동소수점 방식으로 숫자를 다룬다.
  • 3.14처럼 값을 직접 표현하는 것을 리터럴이라고 한다.
  • 표현할 수 있는 부동소수점 리터럴의 최대 크기는 대략 2의 1024승이다.
  • 오차 없이 표현할 수 있는 최댓값은 Number.MAX_SAFE_INTEGER이다.

 

BigInt

  • 부동소수점의 범위를 벗어나는 큰 정수를 다룰 때 사용한다.
  • 정수 뒤에 n을 붙이거나 BigInt 함수를 호출하여 사용한다. (ex: 123n, BigInt(123))
  • Number 타입과의 연산을 위해서는 타입을 맞춰야 한다.

 

템플릿 리터럴

  • 백틱(`)을 사용한 문자열 표현 방법이며, 개행문자 없이 여러 줄을 적거나 문자열 사이에 다른 표현식을 넣을 수 있다.
  • 태그드 템플릿을 이용하면 템플릿 리터럴을 커스텀할 수 있다.
// strings 파라미터는 문자열의 리터럴 부분, values 파라미터는 ${} 안의 표현식
function tag(strings, ...values) {
  console.log(strings); // ['안녕 ', '야 ', '!']
  console.log(values);  // ['철수', '오늘']
  return `${strings[0]}${values[0].toUpperCase()}${strings[1]}${values[1]}${strings[2]}`;
}

const result = tag`안녕 ${'철수'}야 ${'오늘'}!`;
console.log(result);

 

 

Symbol

  • 리터럴이 없고 Symbol 함수를 통해서만 생성되며, 항상 고유한 값을 가짐
  • 자바스크립트에서 객체의 키는 모두 문자열이라서, 다른 사람이 객체에 필드를 붙일 때 충돌의 우려가 있고, 자바스크립트의 내장 기능을 구별하기 힘들기 때문에 고안됨.
// 문자열 key
const user = { name: "철수" };
user.id = 1;   // 내가 추가한 속성


// 심볼 key
const id = Symbol('id');
const user = { name: '철수', [id]: 1 };

console.log(user[id]); // 1
console.log(user); // { name: '철수' }  ← Symbol은 보통 숨겨짐
  • 두 가지 종류가 있는데, 위 코드와 같이 만들어지는 일반 Symbol숨겨진 프로퍼티를 만들 때 유용하다.
  • 또 하나는 전역 Symbol인데 Symbol.for(key) 로 만든다. 이를 통해 전역 레지스트리에 등록되는 Symbol을 만들 수 있으며 기본적으로 제공되는 메서드에는 Symbol.iterator, Symbol.hasInstance 등이 있다.
// 전역 Symbol 만들기
const x = Symbol.for('token');
const y = Symbol.for('token');
console.log(x === y); // true
  • 하지만 전역 Symbol은 어디서든 생성하거나 참조가 가능하기 때문에 메모리에서 제거되지 않는다. 그래서 WeakMap 등에서는 사용할 수 없다.

 

typeof 연산자

  • 어떤 값의 타입을 알고 싶을 때 사용하면 타입을 string으로 반환한다.
  • 특이한 점은 Null은 "object"를 반환한다. 자바스크립트의 버그라고 한다.
  • 함수는 "function"을 반환한다.

 

타입 변환

  • 자바스크립트는 동적 타입 언어로, 다른 타입끼리 연산하려 하면 타입을 강제로 변환시킨다.
  • 이를 암시적 타입 변환이라고 하며, 개발자가 의도적으로 타입을 변환하는 경우는 명시적 타입 변환이라고 한다.
// Number 타입 변환
Number(null);    // 0
Number(undefined);    // NaN
Number(true);    // 1
  • Boolean 타입으로 변환될 때 true인 값을 Truthy, false인 값을 Falsy라고 한다. Falsy엔 -0"" (빈 문자열) 도 포함된다.
  • Symbol.toPrimitive는 객체를 원시값으로 변환시키는 메서드이며 개발자가 커스텀할 수 있다.
// hint 파라미터: 형변환 시도 시 연산자 문맥에 따라 자바스크립트 엔진이 알아서 문자열을 정해줌

const obj = {
  [Symbol.toPrimitive](hint) {
    if (hint === "string") return "문자열됨";
    if (hint === "number") return 42;
    return "default";
  },
};

console.log(`${obj}`);     // 문자열됨
console.log(+obj);         // 42
console.log(obj + "!!");   // default!!    (객체 + 문자열 -> 애매한 연산)
  • 모든 객체는 Object.prototype에서 기본 valueOf()와 toString을 물려받는다. 당연히 커스텀도 가능하다.
const obj = {};
console.log(obj.valueOf()); // {}    (기본적으로 this, 즉 자기 자신 반환함)
console.log(obj.toString()); // "[object Object]"    (이 문자열로 고정됨)
  • 보통 객체는 문자열이나 숫자로 변환될 때 Symbol.toPrimitive가 있으면 그걸 호출하고 없으면 valueOf(), toString() 순으로 호출한다. 즉 valueOf()를 호출했는데도 여전히 객체면 toString을 호출한다.
  • valueOf()는 this를 리턴하므로 객체의 암시적 타입 변환 시 valueOf()는 커스텀하지 않는 이상 무조건 toString으로 빠진다.
const myobj = {name: "doringri"}
console.log(myobj + "asdf")    // '[object Object]asdf'
  • 단항 + 연산자(피연산자 하나, ex: +"10")는 Number 타입으로 강제 변환을 시키며, 이항 + 연산자는 숫자끼리면 산술 덧셈, 하나라도 문자열이면 문자열로 변환시킨 뒤 연결한다.
  • 단항 - 연산자는 단항 + 연산자와 같은 동작을 한 뒤 부호를 반전시키며, 이항 - 연산자는 문자열 연결 없이 숫자로 변환시킨다.
  • 일치 연산자(===)는 값과 타입이 모두 일치하는지 비교하는데 유의해야 할 연산은 부호 있는 0NaN이다.
+0 === -0    // true, 부동소수점 표준에서 0은 부호 고려 안한다고 정의되어 있어서
NaN === NaN    // false, 숫자 간 연산에서 에러가 전파되지 않도록 하기 위해
  • 동등 연산자(==)는 비교할 두 피연산자의 타입이 다르면 강제 변환시켜 비교하는데, 기본적으로 숫자 타입으로 변환시킨다.
"123" == 123;    // true
true == 1;    // true

 

 


늦게 정리하는 1장...