| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- JavaScript
- 프론트엔드
- 오블완
- provider 패턴
- 클린코드
- AI
- 회고
- 티스토리챌린지
- 리액트
- frontend
- 이것저것
- context.api
- 에세이
- 아키텍처
- sharedworker
- Web
- 웹워커
- 접근성
- CustomHook
- TypeScript
- Webworker
- react
- vite
- MFA
- MicroFrontEnd
- CRA
- Function Region
- 리팩토링
- 자바스크립트
- Aria
- Today
- Total
Lighthouse of FE beginner
[JavaScript] 원시 값과 메서드 본문
들어가며
자바스크립트에서 원시 값(Primitive Value)(예: 문자열, 숫자, 불리언)은 객체가 아니며 메서드를 가질 수 없는 불변(Immutable)한 값입니다.
하지만 우리는 코드를 작성할 때 “hello”.toUpperCase()처럼 원시 값의 메서드를 흔하게 사용하고 있습니다. 원시 값은 객체가 아니어서 메서드를 가질 수 없다고 했는데 어떻게 각 타입의 메서드를 사용할 수 있을까요?
이는 자바스크립트 엔진이 내부적으로 래퍼 객체(Wrapper Object)라는 임시 객체를 생성하여 원시 값을 객체처럼 다룰 수 있게 해주는 내부 메커니즘 덕분입니다.
원시 값 메서드 사용 메커니즘
원시 값에 메서드를 호출하는 코드가 실행될 때, 자바스크립트 엔진은 자동 박싱(Auto-boxing) 메커니즘을 사용합니다.
1. 원시 값의 메서드 호출 시도 감지: 개발자가 원시 값에 마침표(.) 표기법을 사용하여 프로퍼티나 메서드에 접근하려고 시도하는 코드를 엔진이 감지합니다.
const str = "hello";
str.toUpperCase(); // 엔진이 이 메서드 호출을 감지
2. 임시 래퍼 객체(Wrapper Object) 생성: 엔진은 메서드를 호출해야 하는 원시 값의 타입에 상응하는 표준 빌트인 래퍼 객체( String , Number , Boolean)를 사용하여 임시 객체를 생성합니다.
- 원시 문자열은 "hello" 에서 new String("hello") 으로 객체를 생성합니다.
- 이 임시 래퍼 객체는 String.prototype 등이 제공하는 모든 메서드를 상속받게 됩니다.
3. 래퍼 객체에서 메서드 호출 및 결과 반환: 생성된 임시 래퍼 객체를 통해 원하는 메서드(toUpperCase())가 호출되고 결과가 반환됩니다.

4. 임시 래퍼 객체 즉시 파괴: 메서드 호출이 완료된 직후, 자바스크립트 엔진은 메모리 효율을 위해 임시로 생성했던 래퍼 객체를 즉시 파괴합니다.
원시 값의 불변성 유지
이 메커니즘 덕분에 원시 값 자체는 불변(Immutable)하게 유지됩니다. 원시 값에 프로퍼티를 추가하려고 시도하면, 그 프로퍼티는 잠시 생성되었다가 사라지는 임시 객체에만 적용되고 즉시 파괴되므로, 원시 값에는 영구적인 영향을 주지 않습니다.
const num = 123;
// ① new Number(123) 임시 객체 생성 → 프로퍼티 추가 → 즉시 파괴
num.testProp = 'This is a test';
// ② 새로운 new Number(123) 임시 객체 재.생.성. → 'testProp'이 없으므로 undefined 반환 → 즉시 파괴
console.log(num.testProp); // undefined
프로퍼티 접근 시 매번 새로운 임시 객체가 생성되므로, 원시 값 num 자체는 변하지 않고 불변 상태를 유지합니다.
래퍼 객체를 직접 생성하여 사용하면 안되는 이유
new String(), new Number()와 같이 생성자 함수를 사용하여 래퍼 객체를 명시적으로 생성하는 것은 일반적인 자바스크립트 프로그래밍에서 권장되지 않습니다. 그 이유는 데이터 타입의 차이와 비교 방식의 차이로 인해 심각한 혼란과 오류를 유발할 수 있기 때문입니다.
데이터 타입의 차이
일반적인 원시 값과 생성자 함수를 사용해 만든 래퍼 객체는 데이터 타입이 다릅니다.
| 구분 | 생성 방식 | typeof 결과 | 데이터 타입 |
| 원시 값 | 리터럴 ("123") | string | 원시 타입 |
| 래퍼 객체 | 생성자 (new String("123")) | object | 객체 타입 |
const primitive = '123';
const wrapper = new String('123');
console.log(typeof primitive); // 'string'
console.log(typeof wrapper); // 'object'
값 비교 (===)
자바스크립트에서 동등 연산자 === 의 비교 방식은 데이터의 값 뿐만 아닌 타입까지 비교하는 연산자 입니다.
- 원시 값: 저장된 값 자체를 비교합니다.
- 객체: 메모리에 저장된 참조 값(주소)을 비교합니다.
new 키워드로 생성된 래퍼 객체는 내부 값이 같더라도 메모리상에서 서로 다른 주소에 저장된 별개의 객체입니다.
const primitive1 = '123';
const wrapper1 = new String('123');
const wrapper2 = new String('123');
// ① 원시 값과 객체의 비교: 타입이 다르므로 false
console.log(primitive1 === wrapper1); // false
// ② 객체와 객체의 비교: 서로 다른 참조(주소)를 가지는 별개의 객체이므로 false
console.log(wrapper1 === wrapper2); // false
new String("123") vs String("123")의 차이점
String을 호출해 값을 생성할 때 new 연산자를 사용하는 것이 어떤 차이가 있는지 알아봅시다.
String과 같은 표준 빌트인 생성자 함수는 사용 방식에 따라 객체를 생성하거나 원시 값을 반환하는 두 가지 역할을 수행합니다.
| 사용 방식 | 코드 예시 | 역할 | 반환 값의 타입(typeof) |
| 생성자 함수 | new String("123") | 래퍼 객체를 생성하여 반환 | object |
| 일반 함수 | String("123") | 인수를 문자열로 변환하여 반환 | string |
1. new String("123") (생성자 함수 호출)
new 키워드를 붙여 호출하면, String 함수는 문자열 "123"을 감싸는 String 타입의 객체(래퍼 객체)를 생성하여 반환합니다.
const objStr = new String("123");
console.log(typeof objStr); // 'object'
이는 메모리에 별도의 주소를 갖는 객체이므로, 위에 설명된 대로 원시 값과 비교하거나 다른 래퍼 객체와 비교할 때 false가 나올 수 있습니다.
2. String("123") (일반 함수 호출)
new 키워드 없이 호출하면, String 함수는 생성자가 아닌 타입 변환 함수(Casting Function)로 동작합니다. 인수로 전달된 값을 강제로 원시 문자열 타입으로 변환하여 반환합니다.
const primitiveStr = String("123");
console.log(typeof primitiveStr); // 'string'
위 방식은 일반적인 원시 문자열 값이므로, 객체를 직접 생성하는 혼란을 피하기 위해 원시 타입으로의 변환이 필요할 때 사용됩니다.
결론적으로, 자바스크립트에서 원시 값을 다룰 때는 new 키워드 없이 리터럴 방식이나 타입 변환 함수(String(), Number())를 사용하여 원시 값을 유지하는 것이 가장 안전하고 권장되는 방법입니다.
'자바스크립트' 카테고리의 다른 글
| [JavaScript] this 심화 탐구 (1) | 2025.04.10 |
|---|---|
| [JavaScript] 실행 컨텍스트 (3) | 2024.12.15 |
| [JavaScript] this 바인딩 (2) | 2024.12.10 |
| [JavaScript] eval 메서드에 대하여 (0) | 2024.12.01 |
| [JavaScript] var 그리고 let, const (2) | 2024.11.27 |