[YOU DON'T KNOW JS] 네이티브

uoayop·2021년 10월 26일
1

JavaScript

목록 보기
23/24
post-thumbnail

네이티브

네이티브는 ES 명세의 내장객체다.

  • 가장 많이 쓰는 네이티브 ( == 내장 함수 )
    • String(), Number(), Boolean(), Array(), Object(), Function(), RegExp(), Date(), Error(), Sysbol()
var str = new String("hello world");

typeof str; // "object" --> String이 아님!!

str instanceof String; //true

Object.prototype.toString.call(str);
// [Object String]
  • 자바에서 생성자로 인스턴스를 생성하듯이 네이티브도 생성자처럼 사용할 수 있음

    • 근데 type을 찍어보면 Object 가 나옴!
      • String() 으로 문자열을 만들었는데, 타입은 Object? ㄱ-
    • 그리고 instanceof로 어디서 만들어졌는지 물어보면 String이 나옴!
  • new String으로 만든 결과는 원시값 "hello world"를 감싼 객체 래퍼 임을 알 수 있음

    • Object > String > "hello world"

    • 🔥 원시값이 담긴 문자열 래퍼가 만들어지지만 원시값은 아니라는 점


[[class]]

  • 타입이 object인 값에는 [[class]] 라는 내부 프로퍼티가 존재함

  • [[class]] 는 해당 값과 관련된 내장 네이티브 생성자를 가리킴 (Null, Undefined 제외)

  • 이 프로퍼티는 Object.prototype.toString() 메소드를 호출해 존재를 볼 수 있음

  Object.prototype.toString.call([1, 2, 3]);
  // [Object Array]
  
  Object.prototype.toString.call(/regex-literal/i);
  // [Object RegExp]
  • 배열은 내부 [[class]] 값이 "Array", 정규식은 "RegExp"임을 알 수 있음

박싱

  • Null, Undefined를 제외한 나머지 원시값은 박싱(Boxing) 과정을 거침

    1. Prologue

    • 박싱 = 단순 원시값 ➡️ 객체 래퍼
  Object.prototype.toString.call("abc");
  // [Object String]
  
  Object.prototype.toString.call(42);
  // [Object Number]
  
  Object.prototype.toString.call(true);
  // [Object Boolean]
  • 왜 박싱 과정을 거치는걸까?

    • 원시값엔 프로퍼티나 메소드가 없기 때문에!
    • .length(), .toString() 같은 내장 함수를 사용하기 위해선 객체 래퍼로 박싱을 해줘야함
  var a = "abc";
  
  a.length = 3;
  • 원래라면 원시값은 내장 함수를 사용할 수 없지만, 다행히도 JS 엔진이 알아서 박싱을 해줌
  • 그러니 new String("abc"); 같은 객체 형태로 만들 필요가 없다~

언박싱

  • valueOf : 객체 래퍼의 원시값을 가져옴
    • 암시적으로 언박싱이 일어남
var a = new String("abc");

var b = a + "";	// "abc"
var c = a.valueOf();	//"abc"

typeof b;	//String
typeof c; //String
  • JS 엔진이 자동으로 박싱, 언박싱을 해주니 굳이 직접 객체를 생성하지말자!
    왜냐면 에러 투성이가 될 확률이 높다~~~

    아래의 경우를 보자

Boolean()

  • Boolean 객체 래퍼로 false를 감싼 뒤 값을 출력해보면, 반대의 결과가 나옴
  var a = new Boolean(false);
  
  if (!a) { console.log("true지롱");} // true지롱
  • 왜냐면 !!!객체가 truthy이기 때문!!!

  • 수동으로 원시값을 박싱하려면 Object() 함수를 이용해야함

  var a = "abc"
  
  var b = new String("abc");
  var c = Object(a);
  // b와 c는 같은 결과

Array()

  • Array 생성자는 인자로 숫자를 하나만 받으면, 배열의 크기를 미리 정하게 됨

    • 배열의 크기를 미리 정하려면 빈 배열을 만들고, length 프로퍼티를 변경하는 것이 좋음
  • 빈 슬롯을 한군데 이상 가진 '구멍 난 배열'이 생길 수 있다는 의미

  • join을 사용했을 떄 이 문제는 두각을 드러냄

  var a = new Array(3);
  var b = [undefined, undefined, undefined];
  
  a.join("-"); // --
  b.join("-"); // --
  
  a.map(function(v, i) {return i;});	// [empty x 3]
  b.map(function(v, i) {return i;});	// [0, 1, 2]
  • join은 슬롯이 있다는 가정하에 length만큼 루프를 돔

    근데 map은 그렇지 않아서 요상한 결과가 나오게 됨

  • null로 채워진 배열을 만들기 위해선

    var a = Array.apply(null, {length: 3});

  • apply(객체 바인딩, 인자의 배열) : 안에 포함된 원소들이 펼쳐져 함수의 인자로 전달됨

Date()

  • date 객체는 new Date()로 생성한 뒤 getTime()을 호출하면 됨

    그치만 Date.now()를 사용하는게 더 쉬움!

    ( 책에는 더 자세히 나와있지 않아 찾아보니 Date.now()는 정적 Helper fundtion이라
    중간에 Date 객체를 만들지 않아서 더 빠르다고 한다. )


네이티브 프로토타입

  • 내장 네이티브 생성자는 .prototype 객체를 가짐
    • ex) Array.prototype, String.prototype
    • 해당 객체의 하위 타입별로 고유한 로직이 담겨있음
  • 해당 객체에 정의된 메소드에 접근할 수 있음!
    • String.prototype.XYZ() == String#XYZ()

정리

  • JS는 원시값을 감싸는 객체 래퍼(네이티브) 를 제공함
  • 객체 래퍼에는 타입별로 쓸 만한 기능이 구현되어 있음
    (String#trim(), Array#concat() )
  • 원시값이 있을 때, (Object).prototype에 정의된 메소드를 호출하면
    JS는 자동으로 ''박싱''을 해서 필요한 메소드와 프로퍼티를 쓸 수 있게 해줌!
profile
slow and steady wins the race 🐢

0개의 댓글