17.1 Object 생성자 함수
-
생성자 함수(constructor)란 new 연산자와 함께 호출하여 객체(인스턴스)를 생성하는 함수를 말함
-
생성자 함수에 의해 생성된 객체를 인스턴스(instance)라 함
-
new 연산자와 함께 Object 생성자 함수를 호출하면 빈 객체를 생성하여 반환
const person = new Object();
person.name = 'Son';
person.sayHello = function () {
console.log('Hi! My name is ' + this.name);
};
console.log(person);
person.sayHello();
- 빈 객체 생성 후 프로퍼티 또는 메서드 추가하여 객체 정의
-
Object 생성자 함수 이외에 String, Number, Boolean, Function, Array, Date, RegExp, Promise 등 빌트인(built-in) 생성자 함수 제공
const strObj = new String('Son');
console.log(typeof strObj);
console.log(strObj);
const numObj = new Number(123);
console.log(typeof numObj);
console.log(numObj);
const boolObj = new Boolean(true);
console.log(typeof boolObj);
console.log(boolObj);
const func = new Function('x', 'return x * x');
console.log(typeof func);
console.dir(func);
const arr = new Array(1, 2, 3);
console.log(typeof arr);
console.log(arr);
const regExp = new RegExp(/ab+c/i);
console.log(typeof regExp);
console.log(regExp);
const date = new Date();
console.log(typeof date);
console.log(date);
17.2 생성자 함수
17.2.1 객체 리터럴에 의한 객체 생성 방식의 문제점
17.2.2 생성자 함수에 의한 객체 생성 방식의 장점
-
생성자 함수에 의한 객체 생성 방식은 객체(인스턴스)를 생성하기 위한 템플릿(클래스)처럼
생성자 함수를 사용하여 프로퍼티 구조가 동일한 객체를 여러개 생성 가능
function Circle(radius) {
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
const circle1 = new Circle(5);
const circle2 = new Circle(10);
console.log(circle1.getDiameter());
console.log(circle2.getDiameter());
-
new 연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작하고, 반대의 경우 일반 함수로 동작.
const circle3 = Circle(15);
console.log(circle3);
console.log(radius);
+ this
this는 객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수
this가 가리키는 값. 즉 this 바인딩은 함수 호출 방식에 따라 동적으로 결정
| 함수 호출 방식 | this가 가리키는 값 (this 바인딩) |
|---|
| 일반 함수로서 호출 | 전역 객체 |
| 메서드로서 호출 | 메서드를 호출한 객체(마침표 앞의 객체) |
| 생성자 함수로서 호출 | 생성자 함수가 (미래에) 생성할 인스턴스 |
17.2.3 생성자 함수의 인스턴스 생성 과정
17.2.4 내부 메서드 [[Call]]과 [[Construct]]
- 함수 선언문, 함수 표현식으로 정의한 함수는 일반적인 함수와 생성자 함수로 호출 가능
- 함수는 객체이므로 일반 객체와 동일하게 동작 가능
- 함수 객체는 일반 객체가 가지고 있는 내부 슬롯, 내부 메서드를 가지고 있기에 가능
- 일반 객체는 호출 불가. 함수는 호출 가능
- 함수는
[[Environment]]과 [[FormalParameters]] 내부 슬롯과 [[Call]], [[Construct]] 내부 메서드를 추가로 가지고 있음
- 함수가 일반 함수로 호출되면 내부 메서드
[[Call]] 호출
new 연산자와 함께 생성자 함수로 호출되면, 내부 메서드 [[Construct]] 호출
- 함수 객체는 callable(호출할 수 있는 객체)이면서 constructor(
[[Construct]]를 갖는)이거나, callable이면서 non-constructor([[Construct]]를 갖지 않는)이다.
⇒ 즉, 모든 함수 객체는 호출할 수 있지만 모든 함수 객체를 생성자 함수로서 호출할 수 있는 것이 아니다!
17.2.5 constructor와 non-constructor의 구분
- 자바스크립트 엔진에서는 함수 정의를 평가하여 함수 객체를 생성할 때 함수 정의 방식에 따라 다름
- constructor: 함수 선언문, 함수 표현식, 클래스
- non-constructor: 메서드(ES6 메서드 축약 표현), 화살표
함수
- 주의) ECMAScript 사양에서 메서드로 인정하는 범위가 일반적인 의미의 메서드보다 좁음
function foo() {}
const bar = function () {};
const baz = {
x: function () {},
};
new foo();
new bar();
new baz.x();
const arrow = () => {};
new arrow();
const obj = {
x() {},
};
new obj.x();
- 일반적으로는 함수를 프로퍼티 값으로 사용하면 메서드로 통칭
하지만 ECMAScript 사양에서 메서드란 ES6 메서드 축약 표현만 의미
const obj = {
func() {}
}
17.2.6 new 연산자
function Circle(radius) {
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
const circle = Circle(5);
const noCircle = Circle(4);
console.log(noCircle);
console.log(radius);
console.log(getDiameter());
noCircle.getDiameter();
new 연산자와 함께 함수를 호출하면 생성자 함수로 동작
- 내부 메서드
[[Construct]] 호출
- constructor여야 함.
new 연산자 없이 생성자 함수로 호출하면 일반 함수로 호출
- 생성자 함수는 일반적으로 첫 문자를 대문자로 기술하는 파스칼 케이스로 명명
17.2.7 new.target
- 함수 내부에서
new.target을 사용하면 new 연산자와 함께 생성자 함수로 호출되었는지 확인 가능
- 생성자 함수로 호출되었을때는 함수 자신을 가리킴
- 일반 함수로 호출 시에는
undefined
- IE에서는
new.target을 지원하지 않음. "스코프 세이프 생성자 패턴"(instanceof 연산자 활용) 사용
17.1 Object 생성자 함수
생성자 함수(constructor)란
new연산자와 함께 호출하여 객체(인스턴스)를 생성하는 함수를 말함생성자 함수에 의해 생성된 객체를 인스턴스(instance)라 함
new연산자와 함께Object생성자 함수를 호출하면 빈 객체를 생성하여 반환Object생성자 함수 이외에String,Number,Boolean,Function,Array,Date,RegExp,Promise등 빌트인(built-in) 생성자 함수 제공17.2 생성자 함수
17.2.1 객체 리터럴에 의한 객체 생성 방식의 문제점
객체는 프로퍼티를 통해 객체 고유의 상태 (state)를 표현하고
메서드를 통해 상태 데이터인 프로퍼티를 참조하고 조작하는 동작(behavior)을 표현함
[문제점] 프로퍼티는 객체마다 프로퍼티 값이 다를 수 있지만 메서드는 내용이 동일한 경우가 일반적임
17.2.2 생성자 함수에 의한 객체 생성 방식의 장점
생성자 함수에 의한 객체 생성 방식은 객체(인스턴스)를 생성하기 위한 템플릿(클래스)처럼
생성자 함수를 사용하여 프로퍼티 구조가 동일한 객체를 여러개 생성 가능
new연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작하고, 반대의 경우 일반 함수로 동작.+ this
this는 객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수this가 가리키는 값. 즉this바인딩은 함수 호출 방식에 따라 동적으로 결정this가 가리키는 값 (this바인딩)17.2.3 생성자 함수의 인스턴스 생성 과정
인스턴스 생성과
this바인딩 → 인스턴스 초기화 → 인스턴스 반환인스턴스 생성 시 명시적으로 반환할 경우
this반환이 무시됨this반환17.2.4 내부 메서드 [[Call]]과 [[Construct]]
[[Environment]]과[[FormalParameters]]내부 슬롯과[[Call]],[[Construct]]내부 메서드를 추가로 가지고 있음[[Call]]호출new연산자와 함께 생성자 함수로 호출되면, 내부 메서드[[Construct]]호출[[Construct]]를 갖는)이거나, callable이면서 non-constructor([[Construct]]를 갖지 않는)이다.⇒ 즉, 모든 함수 객체는 호출할 수 있지만 모든 함수 객체를 생성자 함수로서 호출할 수 있는 것이 아니다!
17.2.5 constructor와 non-constructor의 구분
하지만 ECMAScript 사양에서 메서드란 ES6 메서드 축약 표현만 의미
17.2.6 new 연산자
new연산자와 함께 함수를 호출하면 생성자 함수로 동작[[Construct]]호출new연산자 없이 생성자 함수로 호출하면 일반 함수로 호출[[Call]]호출17.2.7 new.target
new.target을 사용하면new연산자와 함께 생성자 함수로 호출되었는지 확인 가능undefinednew.target을 지원하지 않음. "스코프 세이프 생성자 패턴"(instanceof연산자 활용) 사용