모던자바스크립트 DeepDive : 17장 생성자 함수에 의한 객체 생성

te-ing·2022년 4월 22일
0
post-thumbnail

타입 변환 함수를 제외한 대부분의 빌트인 함수는 new 연산자와 함께 호출했는지를 확인하는데, 이때문에 new 연산자 없이 호출하여도 new 연산자를 호출한 것 처럼 동작한다.

생성자함수

new 연산자와 함께 객체를 생성하는 함수를 말하며, 이때 생성자 함수에 의해 생성된 객체를 인스턴스 라고 한다. Object 생성자 외에도 String, Number, Boolean, Function, Array, Date, RegExp, Promise 등의 빌트인 생성자 함수가 있다.

객체 레터럴 생성방식의 장점과 단점

const circle1 = {
	radius: 5,
	getDiameter() {
		retrun 2 * this.radius;
	};
}
const circle2 = {
	radius: 10,
	getDiameter() {
		retrun 2 * this.radius;
	};
}

객체 리터럴은 직관적이고 간편하다는 장점이 있지만, 단 하나의 객체만을 생성하므로 여러 개의 객체를 생성해야 할 때에는 비효율적이다.

Object 생성자 함수의 활용

function Circle(radius) {
	this.radius = radius;
	this.getDiameter = function () {
		retrun 2 * this.radius; // return 2;  2가 아닌 this를 반환
	};
}
const circle1 = new Circle(5);
const circle2 = new Circle(10);
const circle3 = Circle(15); 
console.log(circle3); // undefined
console.log(radius); // 15

const persone = new Object(); person.name = 'Taejung'; 과 같이 사용하며 객체 리터럴을 사용하는 것이 더 간편하므로 프로퍼티 구조가 동일한 객체 여러 개를 생성하는 등의 이유가 이유가 아니면 잘 사용하지 않는다.

생성자 함수 사용 시 주의할 점

  1. 생성자 함수를 사용할 때 new를 사용하지 않으면 일반 함수로 호출되며, 일반 함수로 호출된 Circle 내의 this는 전역객체를 가리키게 된다.
  2. return 2 와 같이 this가 아닌 다른 값(원시값) 반환 시 반환이 무시되며 암묵적으로 this가 반환된다. 따라서 반드시 생성자 함수 내부에서 return문을 생략하여야 한다.

this의 동적 바인딩

this 바인딩은 함수 호출 방식에 따라 동적으로 결정되는데, 일반 함수로써 호출될 때에는 전역객체를 가리키고, 메서드일 때는 메서드를 호출한 객체(마침표 앞의 객체), 생성자 함수로서 호출할 때에는 생성자 함수가 생성할 인스턴스를 가리킨다.


생성자 함수로서 함수 호출

function foo() {}
foo(); // 일반적인 함수로서 호출, [[Call]]이 호출된다.
new foo(); // 생성자 함수로서 호출, [[Construct]]가 호출된다.

함수는 일반객체와 달리 호출할 수 있는 [[Call]], [[Construct]] 같은 내부 메서드를 추가로 가지고 있다. 하지만 모든 함수객체가 Construct를 가지진 않는데, 이에 따라 일반 함수로서 호출만 가능한 non-constructor와 생성자 함수로서 호출도 가능한 constructor로 구분한다.

메서드와 화살표 함수는 non-constructor

const arrow = () => {};
new arrow(); // TypeError: arrow is not a constuctor
const obj =  {
	x() {}
};
new obj.x9); // TypeError: obj.x is not a constuctor

자바스크립트 엔진은 함수 정의 방식에 따라 constructor와 non-constructor를 구분하는데, 함수 선언문, 함수 표현식, 클래스는 constructor, 메서드와 화살표 함수는 non-constructor로 구분한다.

new 연산자

new 연산자와 함께 호출하면 함수 객체의 [[Call]]이 호출되는 것이 아니라 [[Construct]]가 호출된다. 즉 해당 함수는 생성자 함수로 동작하는 것이다.

new.target

function Circle(radius) {
	if(!new.target) {
		return new Circle(radius);
	} ...
const circle = Circle(5); // new 연산자 없이도 new.target을 통해 생성자 함수로서 호출됨

ES6에서 지원하는 new.target은 호출 시 함수 자신을 가리키는데, new 연산자 없이 일반 함수로 호출되었다면 undefined를 반환한다. 만약 이를 지원하지 않는 IE 등에서는 instanceof 연산자를 이용한스코프 세이프 생성자 패턴을 사용하면 된다.

타입을 변환하여 반환하는 String, Number, Boolean을 제외한 대부분의 빌트인 함수는 new 연산자와 함께 호출했는지를 확인하는데, 이때문에 new 연산자 없이 호출하여도 new 연산자를 호출한 것 처럼 동작한다. ex) let obj = Object();

profile
병아리 프론트엔드 개발자🐣

0개의 댓글