자바스크립트 객체는 크게 3개의 객체로 분류할 수 있다.
Object,String,Number,Boolean,RegExp,Array,Map/Set,Promise ... 등 40여개의 표준 빌트인 객체를 제공한다.
Math,Reflect,JSON을 제외한 표준 빌트인 객체는 모두 인스턴스를 생성할 수 있는 생성자 함수 객체다.
생성자 함수 객체가 아닌 표준 빌트인 객체는 정적 메서드만을 제공한다.
문자열이나 숫자, 불리언 등의 원시값이 있는데도 문자열, 숫자, 불리언 객체를 생성하는 String,Number,Boolean등의 표준 빌트인 생성자 함수가 존재하는 이유는 무엇일까?
다음 예제를 보면, 원시값은 객체가 아니므로 프로퍼티나 메서드를 가질 수 없는데도 원시값인 문자열이 마치 객체처럼 동작한다.
const str = 'hello';
// 원시 타입인 문자열이 프로퍼티와 메서드를 갖고 있는 객체처럼 동작한다.
console.log(str.length) // 5
console.log(str.toUpperCase()); // HELLO
이렇게 접근이 가능한 이유는, 자바스크립트 엔진이 일시적으로 원시값을 연관된 객체로 변환해주기 때문이다.
즉 원시값을 객체처럼 사용하면 자바스크립트 엔진은 암묵적으로 연관된 객체를 생성하여 생성된 객체로 프로퍼티에 접근하거나 메서드를 호출하고 다시 원시값으로 되돌린다.
이처럼 문자열, 숫자, 불리언 값에 대해 객체처럼 접근하면 생성되는 임시 객체를 래퍼 객체라 한다.
예를 들어, 문자열에 대해 마침표 표기법으로 접근하면, 그 순간 래퍼 객체인 String 생성자 함수의 인스턴스가 생성되고 문자열은 래퍼 객체의 [[StringData]] 내부 슬롯에 할당된다.
메서드 처리 이후 StringData 내부의 문자열은 다시 원시값으로 되돌아가고, 래퍼 객체는 GarbageCollector에 의해 삭제된다.
전역 객체는 코드가 실행되기 이전 자바스크립트 엔진에 의해 어떤 객체보다도 먼저 생성되는 특수한 객체이며, 어떠한 객체에도 속하지 않은 최상위 객체이며, 모든 빌트인 객체의 최상위 객체다.
하지만 오해하지 말아야 할 부분은 프로토타입 상속 관계에서 최상위 객체라는 의미가 아니다, 전역 객체는 어떤 객체의 프로퍼티도 아니며, 객체의 계층적 구조상 표준 빌트인 객체와 호스트 객체를 프로퍼티로 소유한다는 것을 말한다.
전역 객체는 빌트인 객체를 프로퍼티로 가지고 있으며, var 키워드로 선언한 변수와, 키워드 선언 없이 선언한 변수를 프로퍼티로 갖는다.
const,let 키워드로 선언한 전역 변수는 보이지 않는 개념적인 블록 내에 존재하게 된다.
전역객체는 전역객체를 가리키는 식별자 window/global을 생략하여 호출할 수 있다.
parseInt는 문자열을 숫자로 치환하는데, 2번째 인수로 진법을 나타내는 기수를 전달할 수 있다. 반환되는 값은 항상 10진수의 값이다.
parseInt('FFEA15',16) // 16771605
parseInt('101011010',2) // 346
만약 기수를 전달하지 않으면 어떻게 될까?
parseInt('FFB14') // NaN
parseInt('101010') // 101010
공백으로 구분되어 있다면,Error를 띄우지 않고 첫 번째 문자열만 해석하여 반환한다.
parseInt('24 뷰냐리액트냐132',10) // 24
문자열을 이스케이프 처리하거나, 이스케이프문을 다시 돌려준다.
꼭 URL,URI가 아니더라도 가능하다.
이걸 통해서 간단한 암호 전달 앱을 만들어도 좋을 것 같다.
보내는 사람
let sendMessage =
encodeURI('안녕 이건 비밀편지야')
//'%EC%95%88%EB%85%95%20%EC%9D%B4%E....
encodeURI로 암호화 처리 후 replace를 통해 2번쨰 암호화
(단순 복붙으로 무슨 뜻인지 알아낼 수 없게끔 처리..)
const monitorMessage = sendMessage.replace(/%/g,'')
//'EC9588EB859520EC9DB4EAB1B420EBB984EBB080ED8EB8ECA780EC95BC'
서로의 화면에 보이는 글자
'EC9588EB859520EC9DB4EAB1B420EBB984EBB080ED8EB8ECA780EC95BC'
받는 사람에게 실제 보내는 데이터(클릭과 같은 이벤트에 의해 보여지게끔?)
const receiveMessage = decodeURI(sendMessage)
// '안녕 이건 비밀편지야'
Wrapper Object
문자열,숫자,불리언 값에 대해 객체처럼 접근하면 생성되는 임시 객체.
마침표 표기법, 대괄호 표기법을 통해 객체에 접근할 수 있는데, 그동안 자연스럽게 string type에도 위 표기법을 통해 원시값인 string에 접근해왔다.
각 원시값의 타입에 맞는 프로토타입 메서드,프로퍼티를 사용할 때, Wrapper Object가 생성되고, 생성된 Wrapper Object의 프로퍼티 어트리뷰트 [[StringData]]에 문자열이 할당된다.
그리고 처리가 종료되면, 식별자를 다시 원시값으로 되돌리고, Wrapper Object는 Garbage Collection의 대상이 된다.
식별자를 다시 원시값으로 되돌린다.. 무슨말일까?const test = 'react or vue'; test.toUpperCase(); // REACT OR VUE console.log(test) // react or vue
위와 같이, 변경 값이 저장되지 않고,
다시 원래의 값으로 돌아가는 것을 확인할 수 있었다.
이것도 어쩌면, 불변성을 지키려하는 자바스크립트 엔진의 작동 원리 아닐까 싶다.
Wrapper Object는 Number,String,Boolean,Symbol 이외의 원시값(null,undefined)에는 래퍼 객체를 생성하지 않고, 에러가 발생한다.
만약 빈 문자열에 적용하면 어떻게 될까?const test = ''; test.toLowerCase() // ''
Error가 나타나지 않는다.
빈 문자열도 문자열이기 때문이다.
encodeURI / decodeURI
문자열을 이스케이프 처리하거나, 이스케이프문을 다시 돌려준다.
꼭 URL,URI가 아니더라도 가능하다.
이걸 통해서 간단한 암호 전달 앱을 만들어도 좋을 것 같다.
보내는 사람const sendMessage = encodeURI('뷰 안하면 이러다 다 죽어....') //'%EC%95%88%EB%85%95%20%EC%9D%B4%E....
encodeURI로 암호화 처리 후 replace를 통해 2번쨰 암호화
(단순 복붙으로 무슨 뜻인지 알아낼 수 없게끔 처리)const monitorMessage = sendMessage.replace(/%|\./g,'') //'EBB7B020EC9588ED9598EBA9B420EC9DB4EB9FACEB8BA420EB8BA420ECA3BDEC96B4'
서로의 화면에 보이는 글자
'EC9588EB859520EC9DB4EAB1B420EBB984EBB080ED8EB8ECA780EC95BC'
받는 사람에게 실제 보내는 데이터(클릭과 같은 이벤트에 의해 보여지게끔?)
const receiveMessage = decodeURI(sendMessage) // '안녕 이건 비밀편지야'