js prototype!
자바스크립트는 프로토타입 기반 언어라고 불린다.
프로토타입에 대해 개념을 확실하게 하기 위해 알아보았다.
프로토타입
모든 객체들이 메소드와 속성을 상속받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다는 의미이다.
상속되는 속성과 메소드들은 각 객체의 생성자의 prototype
라는 속성에 정의되어 있다.
프로토타입 속성
객체의 prototype
속성은 생성자가 존재하는 함수객체에만 존재한다.
인스턴스를 생성하게 되면 해당 객체의 prototype
속성 내부의 멤버들을 상속받는다.
즉 prototype
속성도 하나의 객체이며 프로토타입 체인을 통해 상속하고자 하는 속성과 메소드를 담아두는 버킷이다.
생성자가 존재하는 함수객체의 인스턴스를 생성하게 되면 객체의 프로토타입은 해당 인스턴스의 __proto__
로 참조하게 된다.
아래의 코드는 문자열의 프로토 타입을 확인하는 코드이다.
1 | let str = "hihi"; |
프로토타입 체인
프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속받을 수 있다. 이는 null
을 프로토타입으로 가지는 오브젝트에서 끝난다. null
은 프로토타입 체인의 종점 역할을 한다.
아래의 코드는 String()
에 존재하는 메소드인 toUpperCase()
를 호출하는 코드이다.
1 | let str = "hihi"; |
실행 순서는 다음과 같다.
- 브라우저가
str
객체가toUpperCase
메소드를 가지고 있는지 체크한다. - 없으므로
str.__proto__
를 통해 객체의 프로토타입 객체(String()
생성자의 프로토타입)를 참조하여toUpperCase()
메소드가 있는지 확인 후 존재하므로 실행한다.
String()
생성자의 프로토타입인 Object
에만 존재하는 valueOf()
메소드를 호출했을 경우의 코드는 다음과 같다.
1 | let str = "hihi"; |
실행 순서는 다음과 같다.
- 브라우저가
str
객체가toUpperCase
메소드를 가지고 있는지 체크한다. - 없으므로
str.__proto__
를 탐색하여 str의 프로토타입 객체에toUpperCase()
메소드가 있는지 확인한다. - 존재하지 않으므로
String.prototype.__proto__
즉Object()
에서 해당 메소드를 찾는다. 존재하므로 실행한다.
아래의 코드는 존재하지 않는 메서드를 실행했을 때의 코드이다.
1 | let str = "hihi"; |
실행 순서는 다음과 같다.
- 브라우저가
str
객체가toUpperCase
메소드를 가지고 있는지 체크한다. - 없으므로
str.__proto__
를 탐색하여 str의 프로토타입 객체에toUpperCase()
메소드가 있는지 확인한다. - 존재하지 않으므로
String.prototype.__proto__
(str.__proto__.__proto
) 즉Object()
생성자에서 해당 메소드를 찾는다. - 존재하지 않으므로
Object()
생성자의 프로토 타입도 확인해야 하지만Object.protoType
은 항상 체인의 끝으로 null이므로 해당 함수는 실행되지 않는다.
아래 코드를 통해 객체간의 프로토타입 체인을 확인해 볼 수 있다.
1 | String.prototype.__proto__; |
create()
Object.create()
메소드는 새 인스턴스를 생성한다.
정확히는 create()
메소드는 주어진 객체를 프로토타입 객체로 삼아 새로운 객체를 생성하는 함수이다.
1 | let person2 = Object.create(person1); |
정리
자바스크립트는 프로토타입 기반의 언어이고
선형리스트 탐색과 유사하게 __proto__
를 통해 상위 프로토타입(편의상 정의한 단어이다.)의 메소드를 탐색한다.
주의사항
위의 코드는 예시일 뿐 실제 개발환경에서 __proto__
를 확인해야 할 경우 Object.getProtoTypeOf()
함수를 이용해야 한다..!
ref
Object prototypes
자바스크립트 생각보다 간단했던 프로토타입
Inheritance_and_the_prototype_chain