어서와, 개발은 처음이지?

자바스크립트 내장타입과 네이티브(native) 본문

[기획] 누구도 알려주지 않은 이야기

자바스크립트 내장타입과 네이티브(native)

오지고지리고알파고포켓몬고 2019. 7. 9. 00:38
반응형



이전 글에서 자바스크립트의 컴파일레이션 과정에 대해 알아보았습니다.


컴파일레이션은 스코프를 좀 더 쉽게 이해할 수 있는 초석으로, 이어서 스코프에 대한 글을 작성하는게 순서상 맞지만, 스코프를 나가면 호이스팅을, 호이스팅을 나가면 클로저로 계속 이어지기 때문에 js의 내장타입과 네이티브를 간단하게 소개하고 넘어가도록 하겠습니다.



1. 내장타입


우선 자바스크립트에는 내장타입라고 불리는 7가지 자료형이 존재합니다.


1. null

2. undefined

3. boolean

4. number

5. string

6. symbol (es6부터 추가됨)

7. object


이들 중 object를 제외한 모든 값은 변경 불가능한 값(불변값, immutable - 참조와 값의 개념에서의 불변으로, 현 토픽에서는 이해하지 못해도 상관없습니다)이며 이 6가지 자료형을 기본 자료형(primitive)이라고 합니다.


위 7가지 자료형은 typeof 키워드로 확인할 수 있습니다.


typeof undefined; // undefined
typeof true; // boolean
typeof 100; // number
typeof "yuddomack"; // string
typeof Symbol("someKey"); // symbol
typeof {}; // object,  주의 - js의 Array는 object로 구현되어 있기 때문에 typeof [] -> object입니다
typeof null; // object


위 7가지 자료형 중 null이 object로 표현되는 것은 20년째 고쳐지지 않은(레거시 코드가 많아서 파급 효과를 우려하여 고칠 수 없는) 버그라고 합니다.

때문에 실제로는 null로 표현되어야 한다는 점을 인지해주시면 됩니다.


이외의 타입들은 최상위 레벨의 내장 타입이 아닌, 내장타입을 사용하여 만든 하위 타입(예 : function)입니다.



1-1. immutable 감잡기


/* immutable */
var a1 = 10;
var a2 = a1;
a2 = 20;
console.log(a1); // 10
console.log(a2); // 20

/* mutable */
var b1 = { ref: 10 };
var b2 = b1;
b2.ref = 20;
console.log(b1); // { ref: 20 }
console.log(b2); // { ref: 20 }


number은 immutable 하므로 a2에 20을 할당하여도 a1의 참조 값은 변하지 않습니다.

object는 mutable 하므로 b2의 ref를 수정하면 b1의 참조 값 또한 변하게 됩니다.



2. 네이티브


네이티브는 window객체처럼 브라우저에 종속되는 것이 아닌 ECMA Script 명세의 내장 객체를 뜻하며, 함수의 형태로 이루어져 있습니다.

네이티브는 실행 환경에 종속되지 않는 ECMA Script 명세의 내장 객체를 뜻하며, 함수의 형태로 이루어져 있습니다.(ex, window 객체는 브라우저에 종속됩니다.)


다음은 자주 사용되는 네이티브입니다.


* String()

* Number()

* Boolean()

* Array()

* Object()

* function()

* RegExp()

* Date()

* Error()

* Symbol()


네이티브는 생성자 처럼 사용할 수 있지만(이후에 나오겠지만 new 키워드를 사용하면 생성자처럼 동작하지만 js에서 생성자라는 함수는 실존하지 않습니다.) 실제로 생성되는 결과물은 원시 값(primitive)를 감싼 객체(object) 래퍼 입니다.


var a = new String("asdf");
console.log(a); // [String: 'asdf']

'asdf' == a; // true
'asdf' === a; // false
'asdf' === a.toString(); // true

typeof a; // object;
typeof 'asdf'; // string;
a instanceof Object; // true
'asdf' instanceof Object; // false


여기서 알아야 할 것은.

우리가 실제로 값이 담겨있는 변수에서 함수를 호출할 수 있는 것은(예 - a.toString) 코드 실행 단계에서 원시값이 객체 래퍼로 박싱되어 해석되기 때문이라는 것 입니다.




3. 내부 [[Class]]


typeof가 'object'인 값(array 등)에는 [[class]]라는 내부 프로퍼티가 추가로 붙습니다.

이 프로퍼티는 직접 접근할 수 없고 Object.prototype.toString 메소드에 값을 넣어 호출하는 것으로 존재를 확인할 수 있습니다.(primitive 값은 객체 래퍼로 박싱 과정을 거칩니다. (Object.prototype.toString.call('yuddomack') -> Object.prototype.toString.call(String('yuddomack'))


var a = [1,2,3];
var b = /asdf/;

Object.prototype.toString.call(a); // '[object Array]'
Object.prototype.toString.call(b); // '[object RegExp]'

// 문득 드는 궁금증 
typeof a; // 'object'
a.toString(); // '1,2,3'

// 왜 이런 차이가?
Object.prototype.toString === a.toString; // false
Array.prototype.toString === a.toString; // true

// Array() toString이 Object() toString을 오버라이딩 한 것으로 추정



4. 마치며


이번 글에서는 내장타입과 네이티브에 대하여 간단하게 알아봤습니다.


그래서 이걸 알면 뭐가 좋은거지? 하는 의문이 들정도로 급 마무리가 되었는데, 정리하자면 자바스크립트의 7가지 자료형, 우리가 아무렇지 않게 사용하던 코드들은(변수에서 함수를 호출하던 행위) 객체 래퍼로 박싱되는 과정을 거친다. 라는 동작원리를 이해하시면 되겠습니다.


다음 글에서는 스코프에 대해 알아보도록 하겠습니다.



5. 참고


You don't know js(타입과 문법, 스코프와 클로저) / 갓 심슨 형님께 영광을 바칩니다.








Comments