자바스크립트는 원시값을 객체처럼 다룰 수 있게 해줍니다!
원시값에도 메서드를 호출할 수 있다는 말이쥬~
원시값을 객체처럼 하용하게 된 배경
자바스크립트 객체의 장점 중 하나는 프로퍼티의 값으로 함수를 저장할 수 있다는 것입니다.
자바스크립트는 날짜,에러,HTML 요소 등을 다룰 수 있게 해주는 다양한 내장객체를 제공합니다.
고유한 프로퍼티와 메서드를 가지죠.
하 지 만
이런 기능을 사용하기 위해선 시스템 자원이 많이 필요합니다.
객체는 원시값보다 무겁고, 내부 구조 유지를 위한 자원을 필요로 하기 때문입니다.
때문에 아래와 같은 딜레마가 생겨버립니다.
1. 문자열이나 숫자와 같은 원시값을 다루는 작업이 많다.
2. 메서드를 사용하면 작업을 수월하게 할 수 있을 것 같다.
3. 하지만 원시값은 빠르고 가벼워야 한다. ( 객체화하여 사용하면 자원 측면에서 좋지 못하다. )
위와 같은 딜레마를 해결하기 위해 다음과 같은 방법이 생겨났습니다.
1. 원시값은 그대로 남겨둬 단일 값 형태를 유지합니다.
2. 문자열, 숫자, boolean, Symbol의 메서드와 프로퍼티에 접근할 수 있도록 언어 차원에서 허용합니다.
3. 이를 가능하게 하기 위해, 원시값이 메서드나 프로퍼티에 접근하려 하면 추가 기능을 제공해주는 특수한 객체,
"원시 래퍼 객체(object wrapper)"를 만들어 줍니다.
4. 사용이 끝나면 원시 래퍼 객체를 삭제합니다.
각 래퍼 객체(object wrapper)는 원시 자료형의 이름을 차용했습니다.
String, Number, boolean, Symbol 입니다.
래퍼마다 제공하는 메서드는 다릅니다.
원시형 메소드의 동작 예시!
원시형의 메소드를 한번 동작해 보겠습니다.
인수로 받은 문자열을 대문자로 바꿔주는 메소드 toUppercase()를 써봅시다!
let string = 'string';
console.log(string.toUpperCase()) // STRING
위와 같은 코드를 실행시켰을 때, 내부적으로는 다음과 같은 일이 일어납니다.
1. 문자열인 string은 원시값이므로 메소드에 접근하는 순간 String 래퍼 객체가 만들어집니다.
이때, 래퍼 객체는 문자열의 값과 실행 시킨 메소드를 포함한 여러 메소드를 가지고 있습니다.
2. 메서드가 실행되면 대문자로 바뀐 새로운 문자열이 리턴됩니다. ( 콘솔창에 출력됩니다. )
3. 출력 이후 래퍼객체는 사라지고 원래대로 원시값 만 남습니다.
이러한 동작들을 통해서
원시값은 가볍게 유지되고,
원시값에서 마치 객체에 접근하는 것처럼 메소드를 사용할 수 있습니다.
생성자로 사용하지 말자!
타 언어에서 new 키워드를 통해 래퍼객체를 직접 만들기도 하는데
자바스크립트에서는 추천하지 않습니다.
다음과 같은 혼동의 여지가 있기 때문입니다.
console.log(typeof 0) // number
console.log(typeof new Number(0)) // object
let isTrue = new Number(0);
if(isTrue){
console.log('0이 truethy라구요..?')
}
0은 falsy값 이지만 위의 if문은 실행됩니다.
new Number(0)은 객체이고,
객체는 논리평가시 무조건 true를 반환하기 때문입니다.. ㅠ
래퍼 객체로 형변환을!
위의 예시들 처럼 new를 붙이지 않고 래퍼객체를 사용하면 원하는 자료형의 원시값으로 바꿔줍니다.
console.log(Number('123')) // 123 (number)
console.log(String(123)) // 123 (string)
console.log(Boolean(123)) // true
null, undefined 는 메서드가 없다.
특수 자료형인 null, undefined 는 래퍼객체, 메서드가 없습니다.
따라서 위와 같은 법칙을 따라 동작하거나 형 변환하지 않습니다.
문자열에 프로퍼티 추가?
문자열에 프로퍼티를 추가하려 하면 다음과 같이 동작합니다.
1. 엄격모드
'use strict';
let string = "나는 문자입니다."
string.hi = '안녕'
console.log(string.hi) // error
엄격모드에서는 래퍼객체를 수정하려고 하면 에러가 발생합니다.
2. 비 엄격모드
let string = "나는 문자입니다."
string.hi = '안녕'
console.log(string.hi) // undefined
비 엄격모드에서는 래퍼 객체에 hi 프로퍼티가 추가 되지만 래퍼 객체는 곧 사라집니다.
따라서 string.hi를 찾을 수 없기 때문에 undefined가 출력됩니다.
'Frontend > JS.info 정리' 카테고리의 다른 글
자료구조와 자료형 - 문자열 (0) | 2022.01.20 |
---|---|
자료구조와 자료형 - 숫자형 (0) | 2022.01.18 |
객체: 기본 - 객체를 원시형으로 변환하기 (0) | 2022.01.11 |
객체: 기본 - 심볼 ( Symbol ) (0) | 2021.12.27 |
객체: 기본 - optional chaining ( ?. ) (0) | 2021.12.22 |