밝을희 클태

[ JavaScript ] Prototype은 뭘까? 본문

JavaScript

[ JavaScript ] Prototype은 뭘까?

huipark 2024. 4. 21. 21:05

JavaScript의 프로토타입이 무엇인지 궁금해서 MDN 사이트에 정리된 내용을 조금 더 간추려서 정리를 해보아야겠다.

 

프로토타입 기반 언어?

JavaScript는 흔히 프로토타입 기반 언어(prototype-based language)라 불립니다.— 모든 객체들이 메서드와 속성들을 상속받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다는 의미입니다. 프로토타입 객체도 또다시 상위 프로토타입 객체로부터 메서드와 속성을 상속받을 수도 있고 그 상위 프로토타입 객체도 마찬가지입니다. 이를 프로토타입 체인(prototype chain)이라 부르며 다른 객체에 정의된 메서드와 속성을 한 객체에서 사용할 수 있도록 하는 근간입니다.

정확히 말하자면 상속되는 속성과 메서드들은 각 객체가 아니라 객체의 생성자의 prototype이라는 속성에 정의되어 있습니다.

 

프로토타입 체인?

JavaScript에서는 객체 인스턴스와 프로토타입 간에 연결(많은 브라우저들이 생성자의 prototype 속성에서 파생된 __proto__ 속성으로 객체 인스턴스에 구현하고 있습니다.)이 구성되며 이 연결을 따라 프로토타입 체인을 타고 올라가며 속성과 메서드를 탐색합니다.

 

function Person(first, last, age, gender, interests) {
	this.name = {
		first: first,
		last: last,
	};
	this.age = age;
	this.gender = gender;
	this.interests = interests;
    ...
}

let person1 = new Person("Tammi", "Smith", 32, "neutral", [
	"music",
	"skiing",
	"kickboxing",
]);

 

여기서 person1의 프로토타입 객체는 Person.prototype이 된다.

"person1." 을 입력하게 되면 Person의 메서드(age, bio, gender)외에도 hasOwnProperty(), isPrototypeOf(), valueOf()Person()의 프로토타입 객체인 Object에 정의된 다른 메서드들도 볼 수 있다. 이는 프로토타입 체인이 제대로 동작한다는 증거다.

 

그러면 Object에 정의되어 있는 메서드를 person1에서 호출하면 어떻게 동작할까?!

person1.valueOf();
  • 브라우저는 우선 person1 객체가 valueOf() 메서드를 가지고 있는지 체크
  • 없으므로 person1의 프로토타입 객체(Person() 생성자의 프로토타입)에 valueOf() 메서드가 있는지 체크
  • 여전히 없으므로 Person() 생성자의 프로토타입 객체의 프로토타입 객체(Object() 생성자의 프로토타입)가 valueOf() 메서드를 가지고 있는지 체크합니다. 여기에 있으니 호출하며 끝

프로토타입 체인 작동 순서

상속받은 멤버는 어디에 저장이 돼 있을까?

Object래퍼런스 사이트에 들어가보면 많은 속성과 메서드가 있다. person1이 상속받는 멤버들보다 훨씬 많다. 저 중에 prototype 속성만 상속을 받는다.Object. 가 아니라 Object.prototype.로 시작하는 것들이다.

prototype도 하나의 객채이며 프로토타입 체인을 통해 상속하고자 하는 속성과 메서드들을 담아두는 버킷이다.

 

Object.prototype.watch()Object.prototype.valueOf()등등은, 생성자를 통해 새로 생성되는 인스턴스는 물론 Object.prototype을 상속받는 객체라면 어떤 객체에서든지 접근할 수 있다.

Object.is()Object.keys()등 prototype 버킷에 정의되지 않은 멤버들은 상속되지 않습니다. 이 것들은 Object() 생성자에서만 사용할 수 있는 멤버들이다.

 

프로토타입을 아래와 같이 확인을 해볼 수 있다. 

위의 예제에서 확인했듯이 Object를 상속받은 객체에서 사용 가능한 수 많은 메서드들이Object의 prototype 속성에 정의되어 있음을 알 수 있습니다.

 

전역 객체인 String, Number, Date, Array의 프로토타입 객체에 많은 메서드들이 저장이 되어있어 아래와 같이 문자열 객체를 생성했을 때 

var myString = "This is my string.";

split()indexOf()replace()등의 문자열을 위한 유용한 메서드들을 사용할 수 있는 이유이다.

 

프로토타입 수정하기

Person.prototype.farewell = function () {
  alert(this.name.first + " has left the building. Bye for now!");
};

Person에 프로토타입을 추가하고 아래의 코드를 실행하면

person1.farewell();

생성자에서 지정했던 person의 name이 alert 창으로 출력되는 것을 확인할 수 있다.

예제에서는 생성자를 정의하고, 객체를 생성하였으며, 그 이후에 프로토타입에 새 메서드를 추가하였습니다.

function Person(first, last, age, gender, interests) {
  // 속성과 메서드 정의
}

var person1 = new Person("Tammi", "Smith", 32, "neutral", [
  "music",
  "skiing",
  "kickboxing",
]);

Person.prototype.farewell = function () {
  alert(this.name.first + " has left the building. Bye for now!");
};

프로토타입 객체는 모든 인스턴스에서 공유하기 때문에 정의하는 즉시 별도의 갱신 과정 없이 접근이 가능하다.

 

 

여기까지가 MDN의 프로토타입에 대한 주요 내용이다.

그렇다면 프로토타입을 어떻게 활용을 해야 할까?

두 인스턴스의 프로토타입 객체는 Person.prototype이고, greeting() 메서드는 Person의 생성자 함수의 메서드, farewell()Person.prototype.farewell()이다. 일반적인 메서드는 인스턴스를 새로 생성을 할 때마다 함께 생성이 되기 때문에 메모리가 낭비된다 하지만 prototype.method()는 모든 인스턴스가 공유하는 prototype객체에  한 번만 저장이된다. 인스턴스를 생성한다고 해서 프로토타입 객체가 새로 만들어지지 않는다. 이렇게 모든 인스턴스에 공통적으로 사용이 되는 멤버들을 프로토타입 멤버로 만들면 메모리를 효과적으로 사용할 수 있다.

 

 

 

MDN

 

Object prototypes - Web 개발 학습하기 | MDN

Javascript에서는 객체를 상속하기 위하여 프로토타입이라는 방식을 사용합니다. 본 문서에서는 프로토타입 체인이 동작하는 방식을 설명하고 이미 존재하는 생성자에 메소드를 추가하기 위해 프

developer.mozilla.org