티스토리 뷰
프로토타입(Prototype) 이란?
자바스크립트에서는 객체를 상속하기 위해 프로토타입(prototype)이라는 방식을 사용한다.
자바스크립트의 모든 객체들은 메서드와 속성을 상속받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다. 프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메서드와 속성을 상속받을 수 있고 그 상위 프로토타입 객체도 마찬가지이다.
이를 프로토타입 체인(prototype chain)이라 부르며, 다른 객체에 정의된 메서드와 속성을 한 객체에서 사용할 수 있도록 하는 근간이 된다.
→ 상속되는 속성과 메서드들은 각 객체가 아니라 객체의 생성자의 프로토타입이라는 속성에 정의되어 있는 것이다.
자바스크립트에서는 객체 인스턴스와 프로토타입 간의 연결이 구성되며 이 연결을 따라 프로토타입 체인을 타고 올라가며 속성과 메서드를 탐색한다.
.
.
.
😮
위 내용이 MDN에 프로토타입을 검색해보면 나오는 프로토타입에 대한 설명인데 프로토타입이라는 개념이 처음이라 읽어도 잘 이해가 되지 않았다. 그래서 유튜브를 찾아보니 코딩애플님의 영상이 눈에 띄어서 들어보았는데 이 영상을 보고 다시 MDN 설명을 보니 prototype이 무엇인지 이해가 가기 시작했다.
Machine이라는 생성자 함수를 정의해보자.
function Machine() {
this.q = 'strike';
this.w = 'snowball';
}
var nunu = new Machine();
여기서 생성자 함수 Machine()은 부모로, nunu라는 Object는 자식으로 비유할 수 있다. (부모가 자식을 생산하는 느낌)
nunu는 부모에서 정의한 속성을 기본적으로 물려받는다.
그런데 여기서, prototype이라는 것을 사용해도 자식 Object에게 속성이나 메서드를 물려줄 수 있다.
나는 Machine에 prototype이라는 것을 설정해준 적이 없는데 Machine은 자동으로 prototype이라는 공간이 생긴다.
prototype은 "유전자"라고 비유해서 생각하면 이해하기 쉽다.
만약 Machine의 prototype에 무언가를 추가하면 (prototype도 일종의 object이기 때문에 .~~ = ~~ 로 데이터 수정 가능)
function Machine() {
this.q = 'strike';
this.w = 'snowball';
}
Machine.prototype.name = 'kim';
var nunu = new Machine();
Machine로부터 생성된 자식들은 모두 name = 'kim'을 사용할 수 있다.
아래 결과를 보면 우리는 nunu에 name을 직접 부여한 적은 없지만 부모의 유전자에 기록되어 있어서 가져다 쓸 수 있는데 이것이 prototype의 역할이다.
즉, 어떤 속성을 상속받아서 사용하고 싶다면 생성자 함수에 추가하거나, prototype에 추가하여 사용할 수 있다.
생성자 함수에 속성을 추가하면 자식 Object는 해당 속성을 직접 가진다.
function Machine() {
this.q = 'strike';
this.w = 'snowball';
}
var nunu = new Machine();
console.log(nunu); // {q: 'strike', w: 'snowball'}
반면, prototype을 사용하여 속성을 추가하면 부모만 {name: 'kim'}이라는 속성을 가지고 그것을 자식이 끌어다가 쓰는 개념으로 이해할 수 있다.
Machine.prototype.name = 'kim';
console.log(nunu); // {q: 'strike', w: 'snowball'}
console.log(nunu.name); // 'kim'
위 코드에서 nunu는 직접 name이라는 속성을 가지고 있지 않은데 어떻게 부모의 name을 끌어다가 쓸 수 있는 걸까?
객체에서 데이터를 하나 뽑고 싶을 때 우리는 nunu.name같이 객체 뒤에 .을 사용한다.
그럼 nunu가 name을 가지고 있으면 name값을 출력한다.
만약 nunu가 name을 가지고 있지 않다면?
nunu의 부모 유전자, 즉 부모의 prototype을 탐색하고 거기에 name이 있다면 그 값을 출력한다.
위 내용을 정리해보면 자바스크립트에서 Obejct의 자료를 뽑을 때
1) 직접 자료를 가지고 있으면 그 값을 출력한다.
2) 직접 가지고 있지 않다면 부모의 prototype을 탐색하여 값이 있다면 그 값을 출력한다.
3) 부모에도 없다면 부모의 부모 prototype을 탐색
4) 그래도 없다면 또 그 부모...
이것이 prototype chain
그럼 Array를 다룰 때를 생각해보자.
array자료에 .sort()같은 메서드를 붙일 수 있는 이유가 무엇일까?
var arr = [0, 3, 1]
우리는 array를 선언할 때 보통 위와 같이 간단하게 표현하는데 컴퓨터는 내부적으로 아래와 같이 Array를 만든다.
var arr = new Array(0, 3, 1)
그럼 우리가 위에서 봤던 new Machine()과 동일한 형태인 것을 볼 수 있다.
Array의 부모는 prototype에 sort나 length같은 메서드들을 가지고 있기 때문에 우리가 array 자료에 그런 메서드들을 사용할 수 있는 것이다.
그럼 이제 prototype을 응용하는 방법을 알아보자.
만약 내가 모든 array 자료에 '2'를 삭제하는 기능을 만들고 싶고 이 기능을 자주 사용할 것 같다고 해보자.
내가 array자료에서 '2'를 삭제하는 함수 delete2()를 만들었고 그것을 모든 array 자료에서 쓸 수 있도록 하고 싶다면
Array.prototype.delete2 = function delete2() { ... }
위와 같이 작성하면 모든 array에서 delete2라는 함수를 사용할 수 있다.
실제로 아래처럼 코드를 작성해보면 delete2라는 속성이 추가된 것을 볼 수 있다.
delete3이라는 건 없으니까 에러가 난다.
참고 자료
🔗 [코딩애플] 이거보고 prototype 이해 못하면 강의접음
'개발공부 > 🟨 JavaScript' 카테고리의 다른 글
[JS] 값(value) (0) | 2023.04.18 |
---|---|
[JS] 식별자 (Identifier) (0) | 2023.04.09 |
[JS] 자바스크립트 비동기 처리 (0) | 2023.01.29 |
[JS] 호이스팅 (Hoisting) (0) | 2023.01.18 |
[JS] 클로저 (Closure) (0) | 2023.01.09 |
프론트엔드 개발자 삐롱히의 개발 & 공부 기록 블로그