자바스크립트에서는 함수를 new로 생성하여 객체를 생성할 수 있다.
function A(){
this.a = 1;
this.hi = function() {
console.log("hi")
}
}
const a = new A();
console.log(a)
함수가 이렇게 객체를 생성하는 방식으로 사용될 때 이 함수를 생성자 함수라고 부른다.
자바스크립트에서는 생성자 함수에 대한 구별이 없다.
그냥 함수를 new로 생성하면 생성자 함수가 되는 것이다.
( 이를 구분하기 위해 생성자 함수로 사용될 함수는 첫글자를 대문자로 쓰는 컨벤션이 있다. )
그럼 모든 함수가 다 생성자 함수가 될 수 있을까? 아니다.
함수에 대해 더 알아보자.
함수
함수도 객체다.
따라서 객체가 가지는 내부슬롯( [[Environment]], [[FormalParameters]] )과 내부 메서드를 모두 가지고 있다.
거기에 더해, 함수로서 동작하기 위한 내부슬롯 [[Call]],[[Construct]] 같은 내부메서드를 추가로 가지고 있다.
함수가 일반 함수로 호출되면 [[Call]]이 호출되고,
생성자 함수로 호출되면 [[Construct]]가 호출된다.
[[Construct]]를 갖는 객체를 constructor, 갖지 않는 객체를 non-constructor라고 한다.
[[Call]]을 갖는 객체를 callable이라고 한다.
생성자함수로 사용할 수 있는 함수
constructor는 생성자함수로 사용할 수 있지만, non-constructor는 생성자 함수로 사용할 수 없다.
constructor : 함수선언문, 함수표현식, class
non-constructor : 메서드(축약 함수), 화살표함수
// 메서드(축약)
const obj = {
x(){}
}
new obj.x(); // Error
일반적으로 함수를 프로퍼티 값으로 사용하면 메소드라고 한다. 하지만 ECMAScript 사양에서의 메서드는 메서드 축약 표현만을 의미한다.
new.target
추가로 new.target에 대한 이야기이다.
new로 생성하면 [[Construct]]가 불린다.
new 없이 생성하면 [[Call]]이 불리기 때문에 이 오류를 방지하기 위해서 ES6부터 new.target이 생겼다. (IE에서는 안됨)
function이 생성자함수로 생성되면 내부에서 new.target에 값이 바인딩된다. 이를 체크하여 인스턴스를 new로 생성해 return할 수 있다.
function Circle(radius){
if(!new.target){
return new Circle(radius);
}
...
}
const circle = Circle(5); //가능
new.target을 쓸 수 없는 경우에는 아래와 같이 사용할 수 있다.
function Circle(radius){
if(!(this instance of Circle)){
return new Circle(radius);
}
...
}
const circle = Circle(5); //가능
'javascript' 카테고리의 다른 글
[javascript] 클래스 필드란 (0) | 2022.04.05 |
---|---|
[javascript] static 사용하기, class, static method (0) | 2022.04.05 |
[javascript] Method Chaining Pattern (0) | 2022.04.01 |
[javascript] 옵셔널체이닝(optional chaining), null병합 연산자(nullish coalescing) (0) | 2022.03.24 |
[javascript] 상속 구현하기 (0) | 2021.12.30 |