본 내용은 이웅모 님의 모던 "자바스크립트 DeepDive" 책을 보고 정리한 내용입니다. 저작권 보호를 위해 책의 내용은 요약되었습니다.
○ 생성자 함수란?
- new 연산자와 함께 호출하여 새로운 객체(인스턴스)를 생성하는 함수
- 생성자 함수 호출시 함수 내의 코드가 실행된다.
- 일반적으로 대문자로 시작한다.
- 생성자 함수 내에서 this 키워드를 사용하여 객체의 속성과 메서드를 정의할 수 있다.
○ 생성자 함수를 사용하는 이유
- 객체 리터럴은 한 번에 하나의 객체만 생성할 수 있지만 생성자 함수를 사용하면 동일한 구조와 동작을 가진 여러 개의 객체를 생성할 수 있다.
- 생성자 함수를 사용하면 객체의 초기화 과정을 분리할 수 있는데 생성자 함수 내에서 객체의 속성을 초기화하고, 생성자 함수 외부에서는 초기화된 객체를 사용할 수 있다.
// 생성자 함수 정의
function Person(name, age) {
this.name = name;
this.age = age;
}
// 생성자 함수의 프로토타입에 메서드 추가
Person.prototype.sayHello = function() {
console.log(`안녕하세요, 저는 ${this.name}입니다.`);
};
// 객체 생성
var person1 = new Person("John", 25);
var person2 = new Person("Jane", 30);
// 객체의 속성과 메서드 사용
console.log(person1.name); // "John"
console.log(person2.age); // 30
person1.sayHello(); // "안녕하세요, 저는 John입니다."
person2.sayHello(); // "안녕하세요, 저는 Jane입니다."
○ 생성자의 인스턴스 생성과정
1. 인스턴스 생성과 this 바인딩
- 암묵적으로 새로운 빈 객체가 생성된다.
- 생성자 함수의 실행 컨텍스트가 생성되고, 빈 객체 즉, 인스턴스는 this에 바인딩한다.
( this 바인딩에 대한 내용은 해당 링크 참조 )
2. 인스턴스 초기화
- 생성자 함수에 기술되어 있는 코드가 실행되며 this에 바인딩되어 있는 인스턴스를 초기화한다.
3. 인스턴스 반환
- 생성자 함수 내부의 모든 처리가 끝나면 완성된 인스턴스가 바인딩된 this를 암묵적으로 반환한다.
function Person(name) {
this.name = name;
// 인스턴스 속성 설정 등의 처리...
// return 문이 없음
}
var person = new Person("John");
console.log(person); // Person { name: "John" }
- this가 아닌 다른 객체를 명시적으로 반환하면 return 문에 명시한 객체가 반환된다.
function Person(name) {
this.name = name;
// 인스턴스 속성 설정 등의 처리...
return { greeting: "Hello" };
}
var person = new Person("John");
console.log(person); // { greeting: "Hello" }
- 명시적으로 원시값을 반환하면 원시값은 무시되고 this가 반환된다.
function Person(name) {
this.name = name;
// 인스턴스 속성 설정 등의 처리...
return "Hello";
}
var person = new Person("John");
console.log(person); // Person { name: "John" }
- 생성자함수에서 this가 아닌 다른 값을 반환하는 것은 생성자의 기본동작을 훼손하므로 함수 내부에서 return문은 반드시 생략해야 한다.
○ [[Call]] 메서드와 [[Construct]] 메서드
1. [[Call]] 메서드
- 함수 객체에 내장된 메서드로, 일반 함수 호출을 처리한다.
- [[Call]] 메서드는 함수 객체가 호출될 때 호출되며, 함수의 실행을 담당한다.
- 함수 호출 시 this 바인딩, 인수 전달, 스코프 결정 등의 동작을 처리한다.
- 모든 함수 객체는 [[Call]] 메서드를 가지고 있습니다.
2. [[Construct]] 메서드
- 생성자 함수로서 호출될 때의 동작을 정의하는 메서드이다.
- 생성자 함수가 new 키워드와 함께 호출될 때, [[Construct]] 메서드가 호출된다.
- [[Construct]] 메서드는 새로운 빈 객체를 생성하고, 이 객체를 생성자 함수의 this로 바인딩한다.
- 생성자 함수 내에서 this를 통해 속성을 초기화하거나 다른 초기화 작업을 수행한다.
- 생성자 함수 내에서 명시적으로 return문을 사용하지 않으면 [[Construct]] 메서드가 암묵적으로 this를 반환한다.
- 함수의 정의 방식에 따라 함수를 constructor와 non-constructor로 나눈다.
ⓐ constructor : 함수선언문, 함수 표현식, 클래스
// 일반 함수 정의 : 함수 선언문, 함수 표현식
function foo() {}
const bar = function () {};
// 프로퍼티 x의 값으로 할당된 것은 일반 함수로 정의된 함수로 이는 메서드롤 인정하지 않는다.
const baz = {
x: function () {}
}
// 일반 함수로 정의됝 함수만이 constructor다.
new foo(); // → foo {}
new bar(); // → bar {}
new baz.x(); // → x {}
ⓑ non-constructor : 메서드(ES6 메서드 축약 표현), 화살표 함수
// 화살표 함수 정의
const arrow = () => {};
new arrow(); // TypeError: arrow is not a constructor
// 메서드 정의: ES6의 메서드 축약표현만 메서드롤 인정한다.
const obj = {
x () {}
};
new obj.x(); // TypeError: obj.x is not a constructor
○ 자바스크립트에서 제공하는 빌트인 생성자 함수의 활용
1. 객체 생성
빈 객체, 배열, 날짜 객체 등의 기본적인 객체를 생성해야 할 때 빌트인 생성자 함수를 사용할 수 있다.
var obj = new Object(); // 빈 객체 생성
var arr = new Array(); // 빈 배열 생성
var date = new Date(); // 현재 날짜와 시간을 가지는 날짜 객체 생성
2. 데이터 변환
빌트인 생성자 함수를 사용하여 데이터를 특정 타입으로 변환할 수 있다.
var num = new Number("42"); // 문자열을 숫자로 변환
var str = new String(123); // 숫자를 문자열로 변환
3. 기능 확장
빌트인 생성자 함수를 확장하여 원하는 동작을 구현할 수 있다.
function CustomArray() {
Array.apply(this, arguments); // Array 생성자 함수를 호출하여 기본 동작을 상속받음
// 추가적인 동작 구현
}
var customArr = new CustomArray(1, 2, 3);
4. 예외 처리
빌트인 생성자 함수를 사용하여 오류 객체를 생성하여 예외 처리에 활용할 수 있다.
try {
// 오류가 발생할 수 있는 코드
} catch (error) {
var customError = new Error("Custom error message");
throw customError;
}
○ new.target이란?
new.target은 JavaScript에서 ES6부터 지원하는 클래스 또는 생성자 함수 내부에서 사용되는 특별한 메타 프로퍼티이다. 이 프로퍼티는 new 연산자와 함께 생성자 함수로서 호출되면 함수 내부의 new.target은 함수자신을 가리킨다. new 연산자 없이 일반 함수로서 호출된 함수 내부의 new.target은 undefined다.
1. 스코프 세이프 생성자 패턴
- 생성자를 new와 함께 호출하면 this는 새로 생성된 객체를 가리키며 이 객체는 실행한 생성자가 정의하는 타입의 인스턴스가 되므로 instanceof를 사용하면 함수를 호출할 때 new를 사용했는지 확인가능하다.
일반적인 스코프 세이프 생성자 패턴의 예시는 다음과 같다:
function MyConstructor() {
// new.target을 이용하여 생성자 함수가 직접 호출되었는지 확인
if (!new.target) {
throw new Error("MyConstructor must be called with 'new'");
}
// 프라이빗 멤버 변수
var privateVariable = 10;
// 프라이빗 멤버 메서드
function privateMethod() {
console.log(privateVariable);
}
// 퍼블릭 멤버 메서드
this.publicMethod = function() {
privateMethod();
};
}
// 객체 생성
var myObject = new MyConstructor();
myObject.publicMethod(); // 출력: 10
// 생성자 함수를 직접 호출할 경우 에러 발생
var myObject2 = MyConstructor(); // Error: MyConstructor must be called with 'new'
- Object와 Function 생성자 함수는 new 연산자 없이 호출해도 new 연산자와 함께 호출했을 때와 동일하게 동작한다.
'JavaScript' 카테고리의 다른 글
[자바스크립트] 함수와 일급객체 (0) | 2023.05.24 |
---|---|
[자바스크립트] 함수호출에 따른 this 바인딩 방식 (0) | 2023.05.16 |
[자바스크립트] 프로퍼티 어트리뷰트(Property Attribute) (0) | 2023.05.10 |
쿠키(Cookie), 세션(Session), 웹 스토리지(Web Storage), 캐시(Chache) 차이점 (0) | 2023.05.05 |
[자바스크립트] var, let, const의 차이점 (0) | 2023.05.03 |