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

댓글