JavaScript - 생성자 함수에 의한 객체 생성

김민재·2021년 8월 8일
2
post-thumbnail

*🔐Study Keyword :

🔑생성자 함수에 대해 배우고 🔑생성자 함수로 객체를 생성하는 과정을 이해보자이자이자이

생성자 함수에 의한 객체 생성

  • 여러 객체 생성 방식 중 생성자 함수를 사용하면 객체를 생성할 수 있다.
  • 객체 리터럴생성자 함수를 사용하여 객체를 생성하는 각각의 방식의 장단점까지 살펴보자

- Object 생성자 함수

-WHAT IS❓

생성자 함수new 연산자와 함께 호출하여 객체(인스턴스)를 생성하는 함수를 말하고 생성자 함수에 의해 생성된 객체인스턴스라한다.

-HOW TO USE❕❓

  • new 연산자와 함께 Object 생성자 함수를 호출하면 빈 객체를 생성하여 반환한다.
  • 빈 객체 생성한 이후 프로퍼티 또는 메서드를 추가하여 객체를 완성할 수 있다.
<script>
// 빈 객체 생성
const person = new Object();
// 프로퍼티 추가
person.name="jamie";
person.sayHi = function() {
  console.log(`what's up! My name is ${this.name}`);
};
console.log(person) // { name: "jamie", sayHi: f }
person.sayHi() // "what's up! My name is jamie"
</script>
  • 자바스크립트는 Object 생성자 함수 이외에도 String, Number, Boolean, Function, Array, Date, RegExp, Promise 등의 빌트인 생성자 함수를 제공한다.
<script>
// String 생성자 함수에 의한 String 객체 생성
const strObj = new String('kim'); 
console.log(typeof strObj); // object
console.log(strObj); // String {kim}
// Number 생성자 함수에 의한 Number 객체 생성
const numObj = new Number(123); 
console.log(typeof numObj); // object
console.log(numObj); // Number {123}
// Boolean 생성자 함수에 의한 Boolean 객체 생성
const boolObj = new Boolean(true);
console.log(typeof boolObj); // object
console.log(boolObj);  // Boolean {true}
// Function 생성자 함수에 의한 Function 객체(함수) 생성
const func = new Function('x', 'return x * x');
console.log(typeof func); // function
console.log(func); // f annonymous(x)
// Array 생성자 함수에 의한 Array 객체(배열) 생성
const arr = new Array(1,2,3); 
console.log(typeof arr); // object
console.log(arr); // [1,2,3]
// RegExp 생성자 함수에 의한 RegExp 객체(정규표현식) 생성
const regExp = new RegExp(/ab+c/i); 
console.log(typeof regExp); // object
console.log(regExp); // /ab+c/i
// Date 생성자 함수에 의한 Date 객체 생성
const date = new Date()
console.log(typeof date); // object
console.log(date);
</script>

- 생성자 함수

▶ 객체 리터럴에 의한 객체 생성 방식의 문제는?

  • 객체 리터럴에 의한 객체 생성 방식은 직관적이고 간편하지만 단 하나의 객체만을 생성해 동일한 프로퍼티를 갖는 객체를 여러개 생성해야하는 경우 매번 같은 프로퍼티를 기술해야하기 때문에 비효율적이다.
  • 객체프로퍼티를 통해 고유의 상태(state)를 표현한다. 그리고 메서드를 통해 상태 데이터인 프로퍼티를 참조하고 조작하는 동작(behavior)을 표현한다.
  • 프로퍼티는 객체마다 프로퍼티 값이 다를 수 있지만 메서드는 내용이 동일한 경우가 일반적이다.
<script>
function Circle = {
 radius : 5,
  getDiameter() {
    return  2 * this.radius;
  }
};
console.log(circle1.getDiameter());
const circle2 = {
 radius : 10,
  getDiameter() {
    return  2 * this.radius;
  }
};
console.log(circle2.getDiameter());
</script>
  • 원을 표현한 객체인 circle1 객체circle2 객체프로퍼티 구조가 동일하며 객체의 고유 상태 데이터인 radius 프로퍼티 값은 객체마다 다르지만 getDiameter 메서드의 경우 완전히 동일하다.
  • 객체 리터럴에 의해 객체를 생성하는 경우 프로퍼티 구조가 동일함에도 불구하고 매번 같은 프로퍼티와 메서드를 기술해야하기에 수 십개의 객체를 생성시에 문제가 크다.

▶ 생성자 함수에 의한 객체 생성 방식의 장점?

  • 생성자 함수에 의한 객체 생성 방식은 마치 객체(인스턴스)를 생성하기 위한 템플릿(클래스)처럼 생성자 함수를 사용해 프로터티 구조가 동일한 객체 여러개를 간편하게 생성할 수 있다.
  • 생성자 함수는 이름 그래도 객체(인스턴스)를 생성하는 함수로 객체 지향 언어 생상자와 다르게 형식이 정해져 있는게 아닌 일반 함수와 동일한 방법으로 생성자 함수를 정의하고 new 연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작한다.
  • new 연산자와 함께 생성자를 호출하지 않으면 일반 함수로 동작한다.
<script>
// 생성자 함수
function Circle(radius) {
 // 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
  this.radius = radius;
  this.getDiameter = function() {
  return  2 * this.radius;
  };
}
// 인스턴스 생성
const circle1 = new Circle(5); // 반지름이 5인 Circle 객체 생성
const circle2 = new Circle(10); // 반지름이 10인 Circle 객체 생성
console.log(circle1.getDiameter());
console.log(circle2.getDiameter());
const cicle3 = Circle(15); 
// new 연산자와 함께 호출 하지 않을 시 생성자 함수 동작하지 않고 일반 함수로 호출
console.log(cicle3);//undefined
// 일반 함수로서 호출된 Circle 내의 this는 전역 객체를 가리킨다.
console.log(radius);// 15
</script>

-💡THIS!두두둥장💡)

  • this객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수이다.
    • this가 가리키는 값this 바인딩함수 호출 방식에 따라 동적으로 결정된다.
<script>
// 함수는 다양한 방식으로 호출 될 수 있다.
function foo() {
	console.log(this);  
}
// 1. 일반적인 함수로 호출
// 전역 객체는 브라우저 환경에서 window, node.js 환경에는 global 가리킨다.
foo(); // window
const obj = { foo } // ES6 축약 표현 
// 2. 메서드로서 호출
obj.foo(); // obj
// 3. 생성자 함수로서 호출
const inst = new foo(); // inst
</script>

▶ 생성자 함수의 인스턴스 생성 과정

  • 생성자 함수의 함수 몸체에서 객체(인스턴스)를 생성하기 위해 수행해야하는 과정을 따라가보자!
  • 생성자 함수의 역할프로퍼티 구조가 동일한 인스턴스를 생성하기 위해 템플릿(클래스)으로서 동작하여 1>인스턴스를 생성하는 것과 2>생성된 인스턴스를 초기화(인스턴스 프로퍼티 추가 및 초기값 할당)하는 것이다.
  • 생성자 함수가 1>인스턴스를 생성하는 건 필수이고 2>생성된 인스턴스를 초기화 하는건 옵션이다.
<script>
// 생성자 함수
function Circle(radius) {
 // 2> 인스턴스 초기화
  this.radius = radius;
  this.getDiameter = function() {
  return  2 * this.radius;
  };
}
// 1> 인스턴스 생성
const circle1 = new Circle(5); // 반지름이 5인 Circle 객체 생성
</script>
  • 생성자 함수 내부엔 this에 프로퍼티를 추가하고 필요에 따라 전달된 인수를 프로퍼티의 초기값으로 할당하여 2>인스턴스를 초기화한다.
  • 반면 인스턴스를 생성하고 반환하는 코드는 보이지 않는데 자바스크립트 엔진은 '암묵적인 처리'를 통해 1>인스턴스를 생성하고 반환한다.
  • 이렇게 new 연산자와 함께 생성자 함수를 호출하면 자바스크립트 엔진은 다음의 과정(step 1, 2, 3)을 거쳐 1>인스턴스를 생성하고 2>인스턴스를 초기한 후 '암묵적'으로 인스턴스를 반환한다.

-step 1.인스턴스 생성과 this 바인딩

  • 암묵적으로 빈 객체가 생성되는데 이 빈 객체가 바로 생성자 함수가 생성한 인스턴스이다.
  • 그리고 암묵적으로 생성된 빈 객체, 인스턴스는 this에 바인딩(this와 인스턴스(빈 객체)가 연결)된다. 이 처리는 함수 몸체의 코드가 한 줄씩 실행되는 런타임 이전에 실행된다.
<script>
function Circle(radius) {
 // 1. 런타임 이전에 암묵적으로 인스턴스가 생성되고 this에 바인딩된다.
 // 이것이 생성자 함수 내부의 this가 생성자 함수가 생성할 인스턴스를 가리키는 이유이다. 
  console.log(this);// Circle {}
  this.radius = radius;
  this.getDiameter = function() {
   return  2 * this.radius;
  };
}
</script>

-💡이제는 알자!바인딩)💡

  • 바인딩이란 식별자와 값을 연결하는 과정을 의미하며 변수 선언이 변수 이름과 확보된 메모리 공간의 주소를 바인딩하는 것이라면 this 바인딩은 this와 this가 가리킬 객체를 바인딩하는 것이다.

step2. 인스턴스 초기화

  • 생성자 함수에 기술되어있는 코드가 한줄 씩 실행되어 this에 바인딩 되어있는 인스턴스를 초기화한다.
  • 즉, this에 바인딩되어 있는 인스턴스에 프로퍼티나 메서드를 추가하고 생성자 함수가 인수로 전달받은 초기값을 인스턴스 프로퍼티에 할당하여 초기화하거나 고정값을 할당하는데 이 처리는 개발자가 기술한다.
<script>
function Circle(radius) {
 // 1. 암묵적으로 인스턴스가 생성되고 this에 바인딩된다.
 // 2. this에 바인딩 되어있는 인스턴스를 초기화한다. 
  this.radius = radius;
  this.getDiameter = function() {
   return  2 * this.radius;
  };
}
</script>

step3. 인스턴스 반환

  • 생성자 함수 내부의 모든 처리가 끝나면 완성된 인스턴스가 바인딩된 this가 암묵적으로 반환된다.
<script>
function Circle(radius) {
 // 1. 암묵적으로 인스턴스가 생성되고 this에 바인딩된다.
 // 2. this에 바인딩 되어있는 인스턴스를 초기화한다. 
  this.radius = radius;
  this.getDiameter = function() {
   return  2 * this.radius;
  };
  // 3. 완성된 인스턴스가 바인딩된 this가 암묵적으로 반환된다.
}
// 인스턴스 생성. Circle 생성자 함수는 암묵적으로 this를 반환한다.
const circle = new Circle(1);
console.log(circle); // Circle {radius: 1, getDiameter: f}  
</script>
  • 만약 this가 아닌 다른 객체를 명시적으로 반환하면 this가 반환되지 못하고 return 문에 명시한 객체가 반환된다.
  • 하지만 명시적으로 원시값을 반환하면 원시 값 반환은 무시되고 암묵적으로 this가 반환된다.
<script>
function Circle(radius) {
  this.radius = radius;
  this.getDiameter = function() {
   return  2 * this.radius;
  };
  // 명시적으로 다른 객체를 반환하면 암묵적인 this 반환 무시
  return {};
  // 명시적으로 원시 값 반환하면 원시 값 무시되고 암묵적 this 반환 
  return 100
}
// 인스턴스 생성. Circle 생성자 함수는 암묵적으로 this를 반환한다.
const circle = new Circle(1);
console.log(circle); // {}
</script>

-> 생성자 함수 내부에 명시적으로 this가 아닌 다른 값을 반환하면 생성자 함수의 기본 동작을 훼손해 생성자 함수 내부엔 return문을 반드시 생략해야한다.


▶ 내부 메서드[[Call]]과[[Contruct]]

  • 함수 선언문 또는 함수 표현식으로 정의한 함수일반적인 함수로 호출할 수 있는 건은 물론 생성자 함수로서 new 연산자와 함께 호출하여 객체를 생성할 수도 있다.
  • 함수는 객체이므로 일반 객체와 동일하게 동작할 수 있는데 이는 함수 객체가 일반 객체가 가진 내부 슬롯과 내부 메서드를 모두 가지고 있기 때문이다.
<script>
// 함수는 객체
function foo() {}
// 함수는 객체이므로 프로퍼티를 소유 가능
foo.prop = 10;
// 함수는 객체이므로 메서드를 소유 가능
foo.method = function(){
    console.log(this.prop)
}
foo.method(); // 10
</script>
  • 함수는 객체이지만 일반 객체와 달리 함수는 호출 할 수 있다.
    함수 객체는 일반 객체가 가진 내부 슬롯과, 메서드는 물론 함수로서 동작하기 위해 함수 객체만을 위한 [[Enviroment]], [[FormalParmaeters]] 등의 내부 슬롯[[Call]], [Construct]] 같은 내부 메서드를 추가로 가진다.
  • 함수 일반 함수로 호출
    → 함수 객체의 내부 메서드[[Call]]이 호출된다.
  • 함수 new 연산자와 함께 생성자 함수 호출
    → 함수 객체의 내부 메서드 [[Construct]]가 호출된다.
<script>
function foo() {}
// 일반적인 함수로서 호출 :[[Call]]이 호출된다.
foo();
// 생성자 함수로서 호출 ; [[Construct]]가 호출된다.
new foo();
</script>

-내부 메서드[[Call]]을 갖는 함수 객체(함수로서 기능하는 객체)를 callable이라 하며 호출할 수 있는 객체, 즉 함수를 의미한다.
-내부 메서드 [[Construct]]를 갖는 함수 객체를 constructor이라 하며 객체를 생성자 함수로서 호출할 수 있는 함수를 의미한다.
내부 메서드[[Construct]]를 갖지 않는 함수 객체를 non-constructor라고 부르며 객체를 생성자 함수로서 호출할 수 없는 함수를 의미한다.
-모든 함수 객체는 callable이지만 모든 함수 객체가constructor인건 아님

  • 호출 할 수 없는 객체는 함수 객체가 아니므로 함수 객체는 반드시 callable이어야한다. 따라서 모든 함수 객체는 내부 메서드[[Call]]을 갖고 있으므로 호출할 수 있다.
  • 하지만 모든 함수 객체가 [[Construct]]를 갖는게 아니므로 함수 객체는 constructor 또는 non-constructor일 수 있다.

constructor VS non-constructor 구분

  • 자바스크립트 엔진은 함수 정의를 평가하여 함수 객체를 생성할 때
    함수 정의 방식에 따라 constructor VS non-constructor로 구분한다.

-constructor : 함수 선언문, 함수 표현식, 클래스(클래스도 함수)
-non-constructor : 메서드, 화살표 함수
🛑주의🛑) 이크마스크립트 사양에서 메서드로 인정하는 범위가 일반적인 의미의 메서드보다 좁다는 사실에 주의!

  • 함수를 프로퍼티 값으로 사용하면 일반적으로 메서드로 통칭하지만 이크마스크립트 사양에서 메서드란 ES6의 메서드 축약 표현만을 의미한다.
  • 함수가 어디에 할당되어있는지에 따라 메서드인지를 판단하는 것이 ❌!함수 정의 방식에 따라 constructo와 non-constructor를 구분⭕!
<script>
// 일반 함수 정의 - 함수 선언문
function foo() {}
// 일반 함수 정의 - 함수 표현식
const bar = function () {}
// 프로퍼티 x의 값으로 할당된 것은 일반 함수로 정의된 함수로 메서드로 인정하지 않는다
const baz = {
    x : function(){}
}
//  일반함수, 함수 선언문과 함수 표현식으로 정의된 함수만constructor
new foo(); // foo {}
new foo(); // bar {}
new bar.x() // x{}
// 화살표 함수와 메서드 축약 표현으로 정의된 함수는 non-constructor
// 화살표 함수 정의
const arrow = () =>{};
new arrow() // TypeError: arrow is not a constructor
// 메서드 정의 : ES6의 메서드 축약 표현만 메서드로 인정
const obj = {
  x() {}
};
new obj.x(); // TypeError: obj.x is not a constructor
</script>
  • 함수를 일반 함수로 호출
    함수 객체 내부 메서드 [[Call]]이 호출
  • new 연산자와 함께 생성자 함수로서 호출
    함수 객체 내부 메서드[[Construct]]가 호출
    하지만 non-constructor인 함수 객체를 생성자 함수로서 호출
    내부 메서드 [[Construct]]을 갖지 않아 생성자 함수로 호출하면 에러가난다.
<script>
function foo() {}
// 일반 함수로서 호출
// [[Call]]이 호출. 모든 함수 객체는 [[Call]]이 구현되어있다.
foo(); 
// 생성자 함수로서 호출
// [[Construct]]가 호출되고 [[Construct]]를 갖지 않는다면 에러 발생
new foo();
</script>

🛑주의🛑) 생성자 함수로서 호출될 것을 기대하고서
정의하지 않은 일반 함수(callble이면서 constructor)
new 연산자를 붙여 호출하면 생성자 함수처럼 동작 할 수 있다는 어마무시한 사실이다..!


▶ new 연산자

  • 일반 함수와 생성자 함수에 특별한 형식 차이가 없어
    new 연산자와 함께 함수를 호출하면 해당 함수는 생성자 함수로 동작한다.
  • new 연산자와 함께 정의하지 않은 일반 함수(callble이면서 constructor)를 호출하면 생성자 함수로서 함수 객체의 내부 메서드 [[Call]]이 호출되는 것이 아닌 [[Construct]]가 호출된다.
<script>
// 생성자 함수로서 정의하지 않는 일반 함수
function add (x, y) {
  return x + y
}
// 생성자 함수로서 정의하지 않은 일반 함수를 new 연산자와 함께 호출
let inst = new add();
// 함수가 객체를 반환하지 않았으므로 반환문이 무시 빈 객체가 생성되어 반환
console.log(inst) // {}
// 객체를 반환하는 일반 함수
function createUser(name, role) {
  return { name, role };
}
// 일반 함수를 new 연산자와 함게 호출
inst = new createUser('minjae','admin');
// 함수가 생성한 객체를 반환한다.
console.log(inst) // { name: "minjae", role: "admin" }  
</script>
  • 반대로 new 연산자 없이 생성자 함수를 호출하면 일반 함수로 호출되어 함수 객체의 내부 메서드[[Construct]]가 호출되는 것이 아닌 [[Call]]이 호출된다.
  <script>
// 생성자 함수
function Circle(radius) {
  this.radius = radius;
  this.getDiameter = function() {
   return  2 * this.radius;
  };
}
// 1>new 연산자와 함께 생성자 함수로서 Circle 함수를 호출하면 생성자 함수가 호출 
// 2>new 연산자 없이 생성자 함수를 호출하면 일반함수가 호출
const circle = Circle(5)
console.log(circle) // undefined
// 1>생성자 함수 내부의 this는 Circle 생성자 함수가 생성할 인스턴스를 가리킨다.  
// 2>일반 함수 내부의 this는 전역 객체 window를 가리킨다.
// 따라서 radius 프로퍼티와 getDiameter 메서드는 전역 객체의 프로퍼티와 메서드이다.
console.log(radius) // 5, 
console.log(getDiameter()) // 10
circle.getDiameter();
//TypeError: Cannot read property 'getDiameter' of undefined;
</script>

-> 이처럼 일반 함수와 생성자 함수의 특별한 형식적 차이는 없기에
생성자 함수는 일반적으로 첫 문자를 대문자로 기술하는 파스칼 케이스로 명명하여 일반 함수와 구별하곤한다.


▶ new.target

  • 생성자 함수가 new 연산자 없이 호출 되는 것을 방지하기 위해
    파스칼 케이스 컨벤션을 사용해도 실수가 발생할 수 있어 이런 위험성을 회피하기 위해 new.target을 지원한다.
  • new.target은 내부 this와 유사하게 constructor인 모든 함수 내부에 암묵적인 지역 변수와 같이 사용되어 메타 프로퍼티라고 부른다.
  • 함수 내부에서 new.target을 사용하면 new 연산자와 함께 생성자 함수로서 호출되었는지 확인 할 수 있다.

-<방법1> (new.targe지원O)

  • new 연산자와 함께 생성자 함수로서 호출되면 함수 내부의 new.target은 함수 자신을 가리키고 new 연산자없이 일반 함수로서 호출된 함수 내부의 new.target은 undefined가 된다.
<script>
// 생성자 함수
// 함수 내부에서 new.target을 사용해 new 연산자와 생성자 함수로서 호출했는지 확인한다.
function Circle(radius) {
  // 이 함수가 new 연산자와 함께 호출되지 않으면 new.target은 undefined
  if(!new.target){ // undefined면 new 연산자와 함께 생성자 함수로서 호출
    // new 연산자와 함께 생성자 함수를 재귀 호출을 통해 생성된 인스턴스로 반환
    return new Circle(radius)
  }
  this.radius = radius;
  this.getDiameter = function() {
   return  2 * this.radius;
  };
}
// new 연산자 없이 생성자 함수를 호출해도 new.target을 통해 생성자 함수로서 호출
const circle = Circle(5)
console.log(circle.getDiameter()) // 10
</script>

-<방법2> : 스코프 세이프 생성자 패턴(new.targe지원X)

  • new 연산자와 함께 생성자 함수에 의해 생성된 객체(인스턴스)는 프로토타입에 의해 생성자 함수와 연결되므로 이를 이용해 new 연산자 함께 호출되었는지를 확인할 수 있다.
<script>
// 생성자 함수
function Circle(radius) {
  // 생성자 함수가 new 연산자와 함께 호출되면 함수의 선두에 빈객체 생성되고
  // this에 바인딩되어 this와 Circle은 프로토 타입에 의해 연결
  // 생성자 함수가 new 연산자와 함께 호출되지 않으면 이 시점에서 this는 전역 객체 window 가리킨다
  // this와 Circle은 프로토 타입에 의해 연결되지 않는다
  if(!(this instanceof Circle)) {
     return new Circle(radius)
     }
    // new 연산자와 함께 호출하여 생성된 인스턴스 반환    return new Circle(radius)  
  this.radius = radius;
  this.getDiameter = function() {
   return  2 * this.radius;
  };
}
// new 연산자 없이 생성자 함수를 호출해도 new.target을 통해 생성자 함수로서 호출
const circle = Circle(5)
console.log(circle.getDiameter()) // 10
</script>
  • 대부분의 빌트인 생성자 함수는 new 연산자와 함께 호출되었는지를 확인한 후 적절한 값을 반환한다.
  • Object와 Function 생성자 함수는 new 연산자 없이 호출해도 new 연산자와 함께 호출했을 때와 동일하게 동작한다.
<script>
let obj = new Object();
console.dir(obj); // {}
obj = Object();
console.log(obj); // {}
let f = new Function('a', 'b', 'return a + b');
console.log(f); // /function anonymous(a,b) { return a + b }
f = Function('a', 'b', 'return a + b');
console.log(f); // /function anonymous(a,b) { return a + b }
</script>
  • String, Number, Boolean 생성자 함수는 new 연산자와 함께 호출했을 때 String, Number, Boolean 객체를 생성하여 반환하지만
    new 연산자 없이 호출하면 문자열, 숫자, 불리언 값을 반환(이를 통해 데이터 타입을 변환)한다.
<script>
const str = String(123);
console.log(str, typeof str); // "123", string
const num = Number(`123`);
console.log(num, typeof num); // 123, number
const bool = Boolean('true');
console.log(bool, typeof bool); // true ,"boolean"
</script>

*💡conclusion

  • 생성자 함수가 객체 리터럴과 객체 생성 방식이 무엇이 다른지 확실하게 알고넘어가자
  • 생성자 함수 내부의 this는 생성자 함수가 생성할 객체를 가리키며 this 바인딩이 함수 호출방식에 따라 동적으로 결정된 다는 사실을 잊지말자..!
  • 생성자 함수의 인스턴스 생성 과정의 3단계 그리고 함수는 객체로서 일반 객체와 달리 호출가능하며 일반 객체가 가진 내부 슬롯과 메서드 뿐만 아니라 함수 객체만을 위한 내부 슬롯과 내부 메서드 [[Call]] ,[[Construct]]를 가지고 있어 일반 함수와 new 연산자와 함께 생성자 함수로 호출 될때 각각 다르게 호출됨을 인지!
  • 내부 메소드 [[Construct]]를 갖고 있는 함수와 갖지 못한 함수의 구별법은 함수 정의 방식에 따라 달라진다!
  • new 연산자와 함께 함수 호출 생성자 함수로 동작해 [[Construct]]가 호출되고 new 연산자 없이 생성자 함수를 호출하면 일반 함수로 호출해 [[Call]]이 호출된다! 일반 함수와 생성자 함수의 형식저 차이를 구별하기 위해 파스칼 케이스로 명명한다는 점까지 알아두자
  • 생성자 함수가 new 연산자 없이 호출되는 것을 방지하기 위해 함수 내부에서 암죽적인 지역 변수와 같이 사용되는 메타 프로퍼티인 new.target을 사용해 new 연산자와 함께 생성자 함수로서 호출되었는지 확인할 수 있다!

#📑Study Source

  1. 책 - 모던 자바스크립트 Deep Dive (234p-248p)
profile
자기 신뢰의 힘을 믿고 실천하는 개발자가 되고자합니다.

0개의 댓글