객체 생성방식

  • 리터럴 : 일반적이고 간단

    1
    var a = {b : ‘c’, d : ‘e’}
    cs

     

  • 생성자 함수 : 오늘 알아볼것

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function a() {
     
    this.b = ‘c’;
     
    this.d = ‘e’;
     
    }
     
    var a = new a();
    cs

 

생성자 함수

  • new와 함께 호출하여 객체를 생성하는 함수

  • new없이 호출하면 생성자 함수가 아닌 일반 함수로 동작

  • 종류 : Object, String, Number, Boolean, Function, Array, Date, RegExp, Promise 등

  • 사용하는 이유

    • 객체 리터럴의 문제점 : 동일한 객체 여러번 생성할때 비효율적
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      const a1 {
       
      num : 123,
       
      printnum() {return this.num};
       
       }
       
      console.log(a1.printnum()); // 123
       
       
       
      const b1 {
       
      num : 456,
       
      printnum() {return this.num};
       
       }
       
      console.log(b1.printnum()); // 456
      cs
    • 생성자 함수를 사용할 경우 프로퍼티 구조 동일한 객체를 간편하게 생성 가능
    • 자바의 클래스 개념과 유사
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      function a(num) {
       
      this.num = num;
       
      this.printnum = function() {return this.num};
       
      }
       
       
       
      const a1 = a(123);
       
      const b1 = a(456);
       
       
       
      console.log(a1.printnum()); // 123
       
      console.log(b1.printnum()); // 456
      cs

생성자 함수, 인스턴스 생성 과정

  • 인스턴스 생성과 this 바인딩
    • 빈 인스턴스가 생성
    • this는 빈 인스턴스에 바인딩
      • 앞에 new 붙이지 않으면, this는 window를 가르킴(일반 함수로 호출되기 때문)
      • 그래서 함수와 생성자 함수를 구분하기 위해서 생성자 함수는 첫글자를 대문자로함(파스칼 케이스라고 부름)
    • 위 과정은 생성자 함수 코드가 실행되기 전에 실행됨
      • 어려운 말로, 런타임 이전에 실행
  • 인스턴스 초기화
    • 생성자 함수 코드 한줄씩 실행되며, 인스턴스를 초기화
  • 인스턴스 반환
    • return 따로 명시하지 않아도 this를 반환
    • 만약 this아닌 다른 객체를 return 하면, this가 아닌 다른 객체를 return
    • this 아닌 primitive 반환하면 무시
      • primitive : String, Number 등
      • 이러면 꼬이게됨, 일반적으로 return을 생략해서 사용
  • 예시
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    function Circle(radius) {
     
    // 1. 빈 인스턴스 생성 및 this에 바인딩
     
     
     
    // 2. 코드 한줄씩 실행되며 인스턴스 초기화
     
    this.radius = radius;
     
    this.getDiameter = function() {
     
        return 2 * this.radius;
     
    };
     
     
     
    // 3.this를 return
     
    };
     
    cs

생성자 함수로 만든 객체가 일반 객체와 다른점

  • 일반 객체는 호출할 수 없지만 함수는 호출 가능
    • 일반 객체에게 없는, 함수로서 동작하기 위한 내부슬롯과 내부 메소드를 가짐
    • 내부슬롯, 내부메소드 : 외부로 노출되진 않지만, 자바스크립트 내부에서 동작하는 객체, 메소드
    • 내부슬롯
      • [[Environment]]
      • [[FormalPrameters]]
    • 내부 메소드
      • [[Call]] : 일반함수로서 호출되면 실행
      • [[Construct]] : new 연산자와 함께 호출되면 실행

생성자 함수로 객체 생성이 불가능한 함수

  • 함수 내부 메소드로 [[Construct]]가 없는것은 생성자로 함수로 객체 생성이 불가능
  • 객체 생성이 가능한 함수
    • constructor로 부름
    • 함수 선언문 : function Circle() {~~}
    • 함수 표현식 : var Circle = function() {~~}
    • 클래스(클래스도 함수)
  • 객체 생성이 불가능한 함수
    • ES6 메서드 축약 표현 :
      const obj = {
      x() {}
      }
    • 화살표 함수 : const Circle = () => {};

생성자 함수가 일반 함수와 다른점

  • this
    • 생성자 함수는 this가 인스턴스를 가르키지만,
  • 일반 함수의 this는 window를 가르킴
    • 그래서 함수와 생성자 함수를 구분하기 위해서 생성자 함수는 첫글자를 대문자로함(파스칼 케이스라고 부름)
  • new.target : 생성자 함수로서 호출되었는지 확인 가능
  • 생성자 함수로 호출되면(new 연산자로 호출되면), new.target은 함수 자신을 가르킴
    • 일반 함수로 호출되면 new.target은 undefined
    • 일반 함수로 호출되어도 생성자 함수로 호출되도록 사용하기 위해 활용됨
      1
      2
      3
      4
      5
      6
      7
      8
      9
      function Circle(radius) {
          if(!new.target) {
              return new Circle(radius); // 일반 함수로 호출되었을경우 생성자로 다시 호출
      }
       
      this.radius = radius;
      this.getDiameter = function() {return 2*this.radius;};
       
      }
      cs
    • 스코프 세이프 생성자 패턴
      • new.target은 ES6부터 도입해서, 비교적 최신 버전에서만 지원
      • 그래서 new.target 대신, this instanceof Circle 로 사용하기도 함

+ Recent posts