[javascript] 프로토타입(prototype)

죠현졍·2022년 6월 23일
1

TIL

목록 보기
1/6

자바스크립트는 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어다.

자바스크립트는 클래스 기반 객체지향 프로그래밍 언어보다 효율적이며, 더 강력한 객체 지향 프로그래밍 능력을 지니고 있는 프로토타입 기반의 객체지향 프로그래밍 언어다.

이러한 자바스크립트를 이루고 있는 거의 모든 것이 객체이다.

하지만, 자바스크립트에는 일반적인 다른 객체지향 프로그래밍 언어들이 가지고 있는 Class라는 개념이 없다. (ES6에서 Class가 추가되었지만, 이는 프로토타입을 이용한 다른 방법의 객체 생성이다.)

때문에, 자바스크립트는 프로토타입 객체를 기반으로 상속을 구현하였고, 이를 통해 중복을 제거한다.

프로토타입, 상속이 필요한 이유

function Chat(name, message){
	// props
	this.name = name;
	this.message = message;
	// method
	this.chat = function () {
		console.log(`${this.name} -> ${this.message}`);
	}
}

const chat1 = new Chat('1', 'hellow');
const chat2 = new Chat('2', 'World');

생성자 함수를 통해 chat1, chat2 인스턴스를 생성했다.

property의 경우 각각의 값이 모두 다르기 때문에 생성 해줘야한다.

하지만, chat 함수의 경우 동일한 함수이다.

모든 인스턴스가 동일한 함수를 재정의 하는 것은 불필요한 메모리를 낭비하며, 퍼포먼스에도 좋지 않은 영향을 끼친다.

이러한 중복 문제를 해결하기 위해 상속이 필요하며, 자바스크립트는 프로토타입을 기반으로 상속을 구현한다.

프토로타입 객체

프로토타입 객체(이하 프로토타입)는 어떤 객체의 부모 객체의 역할을 하는 객체로 다른 객체에 공유 프로퍼티와 메서드를 제공한다.

따라서, 프로토타입을 상속받은 자식 객체는 상위 객체의 프로퍼티와 메소드를 자유롭게 사용할 수 있다.

proto

proto는 프로토타입에 접근하기 위한 접근자 프로퍼티다.

  • 상호참조를 방지

직접 접근이 가능하다면 순환 참조를 만들 수 있다.

프로토타입 체인은 단방향 링크드리스트 형태로 구현되어야한다.

프로퍼티를 찾을 때 이 프로토타입 체인을 따라 상위로 올라가며 탐색을 진행하는데, 순환참조가 된 경우 무한루프에 빠질 수 있다.

이를 방지하기 위해 접근자 프로퍼티를 통해 프로토타입에 접근하고 교체하도록 구현 되었다.

  • 코드 내에서 직접 사용은 비권장
const obj = Object.create(null);

위의 경우와 같이 모든 객체가 proto를 사용할 수 있는 것은 아니기 때문에 코드 내에서 직접 사용은 권장하지 않는다.

대신, Object.getPrototypeOf과 Object.setPrototypeOf (getter, setter)의 사용을 권장한다.

prototype 프로퍼티

함수 객체만이 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다.

⇒ non-constructor인 화살표 함수와 ES6 메서드 축약 표현으로 정의한 함수는 prototype 프로퍼티를 소유하지 않으며 프로토타입도 생성하지 않는다.

prototype과 proto의 차이

proto와 prototype 프로퍼티는 결국 동일한 프로토타입을 가리킨다.

하지만, 사용하는 주체가 다르다.

구분소유사용 주체사용 목적
proto모든 객체프로토타입의 참조모든 객체객체가 자신의 프로토타입에 겁근 또는 교체하기 위해 사용
prototypeconstructor프로토타입의 참조생성자 함수새성자 함수가 자신이 생성할 인스턴스의 프로토타입을 할당하기 위해 사용

프로토타입 체인(prototype chain)

모든 객체는 프로토타입의 계층 구조인 프로토타입 체인에 묶여있다.

자바스크립트 엔진은 객체의 프로퍼티에 접근하려고 할 때 해당 객체에 프로퍼티가 없다면,

proto 프로퍼티를 따라 상위 프로토타입의 프로퍼티를 탐색한다.

즉, 프로토타입 체인은 상속과 프로퍼티의 검색을 위한 메커니즘이다.

(스코프 체인과 서로 협력하여 식별자와 프로퍼티를 검색하는 데 사용됨)

이러한 프로토타입 체인의 종점은 Object.prototype이며, 이 객체의 모든 프로퍼티와 메서드는 모든 객체에 상속된다.

function Person(name){
	this.name = name;
}

const me = new Person('me');

프로퍼티 섀도잉

같은 이름의 프로퍼티를 인스턴스에 추가하면 프로토타입 체인을 따라 프로토타입 프로퍼티를 검색하여 해당 프로퍼티를 덮어 쓰는 것이 아니라 인스턴스 프로퍼티로 추가된다.

const Person = (function() {
	function Person(name){
		this.name = name;
	}
	
	Person.prototype.sayHello = function (){
		console.log(`hello~~~~ ${name}~~~~~`);
	}
	return Person;
})();

const me = new Person('me');

me.sayHello = function(){
	console.log(`elihigh~~~~~ ${name}`);
}

me.sayHello();

이처럼 상속 관계에 의해 프로퍼티가 가려지는 현상을 프로퍼티 섀도잉이라고 한다.


출처: 모던 자바스크립트 Deep Dive

0개의 댓글