js prototype!

자바스크립트는 프로토타입 기반 언어라고 불린다.
프로토타입에 대해 개념을 확실하게 하기 위해 알아보았다.

프로토타입

모든 객체들이 메소드와 속성을 상속받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다는 의미이다.

상속되는 속성과 메소드들은 각 객체의 생성자의 prototype라는 속성에 정의되어 있다.

프로토타입 속성

객체의 prototype 속성은 생성자가 존재하는 함수객체에만 존재한다.

인스턴스를 생성하게 되면 해당 객체의 prototype속성 내부의 멤버들을 상속받는다.

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

생성자가 존재하는 함수객체의 인스턴스를 생성하게 되면 객체의 프로토타입은 해당 인스턴스의 __proto__로 참조하게 된다.

아래의 코드는 문자열의 프로토 타입을 확인하는 코드이다.

1
2
3
4
5
6
let str = "hihi";
//인스턴스 생성
str.__proto__;
// 인스턴스의 __proto__ 확인(String의 prototype)
str.constructor.prototype;
// 생성자의 prototype 확인(String의 prototype)

프로토타입 체인

프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속받을 수 있다. 이는 null을 프로토타입으로 가지는 오브젝트에서 끝난다. null은 프로토타입 체인의 종점 역할을 한다.

아래의 코드는 String()에 존재하는 메소드인 toUpperCase()를 호출하는 코드이다.

1
2
3
4
let str = "hihi";
str.toUpperCase();
//"HIHI"
// 프로토타입에 정의된 함수를 호출할 수 있다.

실행 순서는 다음과 같다.

  1. 브라우저가 str 객체가 toUpperCase 메소드를 가지고 있는지 체크한다.
  2. 없으므로 str.__proto__를 통해 객체의 프로토타입 객체(String() 생성자의 프로토타입)를 참조하여 toUpperCase()메소드가 있는지 확인 후 존재하므로 실행한다.

String() 생성자의 프로토타입인 Object에만 존재하는 valueOf() 메소드를 호출했을 경우의 코드는 다음과 같다.

1
2
3
let str = "hihi";
str.valueOf();
//hihi

실행 순서는 다음과 같다.

  1. 브라우저가 str 객체가 toUpperCase 메소드를 가지고 있는지 체크한다.
  2. 없으므로 str.__proto__를 탐색하여 str의 프로토타입 객체에 toUpperCase() 메소드가 있는지 확인한다.
  3. 존재하지 않으므로 String.prototype.__proto__Object()에서 해당 메소드를 찾는다. 존재하므로 실행한다.

아래의 코드는 존재하지 않는 메서드를 실행했을 때의 코드이다.

1
2
3
let str = "hihi";
hi.asdf();
//error

실행 순서는 다음과 같다.

  1. 브라우저가 str 객체가 toUpperCase 메소드를 가지고 있는지 체크한다.
  2. 없으므로 str.__proto__를 탐색하여 str의 프로토타입 객체에 toUpperCase() 메소드가 있는지 확인한다.
  3. 존재하지 않으므로 String.prototype.__proto__(str.__proto__.__proto) 즉 Object() 생성자에서 해당 메소드를 찾는다.
  4. 존재하지 않으므로 Object() 생성자의 프로토 타입도 확인해야 하지만 Object.protoType은 항상 체인의 끝으로 null이므로 해당 함수는 실행되지 않는다.

아래 코드를 통해 객체간의 프로토타입 체인을 확인해 볼 수 있다.

1
2
3
4
String.prototype.__proto__;
// Object
Object.protoType.__proto__;
// null

create()

Object.create() 메소드는 새 인스턴스를 생성한다.
정확히는 create() 메소드는 주어진 객체를 프로토타입 객체로 삼아 새로운 객체를 생성하는 함수이다.

1
2
3
let person2 = Object.create(person1);
person2.__proto__;
//person1

정리

자바스크립트는 프로토타입 기반의 언어이고
선형리스트 탐색과 유사하게 __proto__를 통해 상위 프로토타입(편의상 정의한 단어이다.)의 메소드를 탐색한다.

주의사항

위의 코드는 예시일 뿐 실제 개발환경에서 __proto__를 확인해야 할 경우 Object.getProtoTypeOf()함수를 이용해야 한다..!

ref

Object prototypes
자바스크립트 생각보다 간단했던 프로토타입
Inheritance_and_the_prototype_chain