본문 바로가기

JAVASCRIPT

[자바스크립트] 생성자함수 / 프로토타입

생성자 함수 Constructor Function

객체를 생성할 때 객체 리터럴을 이용하는 것이 가장 간단하다

그러나, 객체를 여러개 만들어야 하는 경우에는 객체 리터럴로 하나하나 만드는 것보다 생성자 함수를 사용해 만든다.

객체에 대한 템플릿을 만들어 놓고, 인스턴스를 찍어내는 방법으로 말이다. (대문자로 시작)

1) new 를 사용해 생성자 함수 직접 만드는 방법 

2) new Array();

3) new Object();

4) new Function(); 

 

* 생성자 함수의 인스턴스 

모든 생성자 함수는 this.라는 빈 객체를 리턴하는데, 생성자 함수에서 리턴하는 결과물을 인스턴스라고 함 

constructor와 prototype 사이에 생성된 자식과 같은 존재 

function B(radius) {
	this.radius = radius
    this.getDiameter = function() {
    	return 2 * this.radius; 
        }
   const circle1 = new Circle(5);
   const circle2 = new Circle(10); 
   }

1) 인스턴스 생성과 this 바인딩 

생성자 함수는 암묵적으로 빈 객체를 만들고, 생성자 함수에 이미 선언되어 있는 this를 바인딩함 

 

2) 인스턴스 초기화 

해당 생성자 함수가 실행되면, this에 바인딩되어 있는 인스턴스를 받아온 인수 or 함수 내부에 기술된 값으로 초기화 

 

3) 인스턴스 반환

위 함수에는 return.this가 생략되어있음 

생성자 함수는 this 바인딩을 하고 초기화를 끝낸 뒤에, 해당 인스턴스 바인딩 된 this를 반환함

생성자 함수는 해당 리턴문을 생략해야 하고, 명시적으로 객체를 반환해야한다면 this 대신 객체를 반환한다.

원시값을반환하면 무시하고 this를 반환한다. 

 

Dunder Proto( __proto__)

__proto__라고 표기하며, 상위 프로토타입을 가져올 때 사용한다. 

 

 


생성자 함수 vs 일반 함수 

생성자 함수와 일반함수는 선언될 때에는 근본적인 차이가 없음

호출할 때 new 와 함께 호출되는가, 아닌가에 다라서 생성자 함수가 될 수 있고 일반함수가 될 수도 있음 

함수 내부에는 일반 객체가 가지는 메서드에 대해 <call> 과 <construct>라는 내부 메서드가 추가로 만들어짐

 

new와 함께 호출될경우, construct 메서드가 실행되고,

일반함수로 호출되면 call 메서드가 실행되면서 다르게 작동

모든 함수가 construct 메서드를 가지고 있는 것은 아니며, 함수는 호출될 수 있어야 하기에 call 메서드는 반드시 가지고 있으나, construct 메서드는 가지고 있지 않을 수 있음 


프로토타입

객체지향, 상속을 구현하기 위해 사용되는 개념 

자바스크립트의 클래스는 함수이고 프로토타입을 기반으로 동작한다. 

생성자 함수를 통해 프로퍼티를 가지고 있는 인스턴스를 생성, 이 인스턴스의 프로토타입에 메서드를 할당하는 것을 통해 상속을 구현

 

생성자 함수와 프로토타입 관계

생성자 함수는 기본적으로 프로토타입이라는 프로퍼티를 가짐

프로퍼티는 함께 만들어지는 프로토타입을 가리키고, 이 프로토타입 또한 constructor 라는 프로퍼티를 가져서 생성자 함수를 가리키고 있음. (생성자 함수는 인스턴스를 생성하고, 인스턴스는 프로토타입을 상속받고 있음)

생성자 함수(constructor)와 프로토타입(prototype)은 한 쌍을 이루면서 서로가 정보를 가지고 있음 

 

 

프로토타입의 생성 시기

생성자 함수가 생성되는 시기에 함께 생성됨

빌트인 생성자 함수(Object, String, Number, Function, Array)는 생성자 함수가 만들어짐과 동시에 프로토타입이 만들어짐 

사용자 정의 생성자 함수와 다른 점은 빌트인 생성자 함수는 전역 객체가 만들어지는 시점에 만들어짐 

 

e.g. Object 생성자 함수가 생성되면서 Object.prototype 인 Object 생성자 함수와 짝을 이루는 프로토타입이 생성 

자바스크립트의 모든 데이터는 원시 타입을 제외하고 모두 객체임, 원시타입을 제외한 모든  데이터는 Obejct.prototype을 상속받음  → JS의 최상단에 존재하는 프로토타입 

 

객체 생성 방식 / 프로토타입 결정 방식 

객체 생성에는 객체 리터럴, Object 생성자 함수, 생성자 함수를 통해 작성한다.

이 세가지 방식 모두 프로토타입이 연결되는 방식이 다르다,

빌트인 객체는 프로그램이 시작되자마자 해당 생성자 함수가 만들어지고 프로토타입도 생성됨 

 

 

1) 객체 리터럴

리터럴로 값을 만들어 내기 때문에, Object.prototype을 상속받음 ( ≠ Object 생성자 함수로 만들어짐) 

상속을 위해 이미 생성된 Object 프로토타입에 연결을 하는 것

 

2) Object 생성자 함수 

Object 생성자 함수로 만들어진 객체는 Object 생성자 함수를 new 연산자와 함께 인스턴스로 만든 객체

 + 생성자 함수를 통해 만들어진 객체는 new 연산자로 호출해 만들어짐 


프로토타입 체인 & 오버라이딩

오버라이딩 : 상속받은 메서드를 재정의해서 사용, 메서드 이름이 같아야 오버라이딩 가능함

JS에서는 오버라이딩 + shadowing 이 들어감 → 상속받은 메서드를 재정의하기보다 메서드 이름이 같기 때문에, 하위 프로토타입 체인에서 먼저 메서드를 정의하면 부모의 메서드는 더 이상 참조하지 않음 

 

프로토타입 체인 :

사용자 정의 함수로 만들어진 인스턴스의 모든 위임관계를 나타냄 (이때, 오버라이딩 + 셰이딩 발생)

JS의 모든 객체는 Object.prototype 을 최상위 객체로 가짐, 상위 프로토타입에 접근해 

프로그램이 시작되자마자 만들어진 빌트인 함수인 생성자 함수 + 함께 만들어진 프로토타입

→ 특정 객체에서 프로퍼티 or 메서드를 찾으려 할 때, 가장 최하단 객체에서 이 요소가 없으면, 프로토타입 체인을 따라 올라가면서 탐색을 하기 때문 

 

 

 

참고자료

https://basemenks.tistory.com/m/180

 

 

 

 

728x90