프로토타입 (Prototype)

I. [[Prototype]]

var myObject = Object.create(anotherObject);

myObject.a; // 2

- `myObject.a`처럼 객체 프로퍼티 참조시 `[[Get]]`이 호출되는데, 기본적으로 객체 자체의 해당 프로퍼티가 존재하는지 찾아보고 존재하면 그 프로퍼티를 사용한다.
- `myObject`에 `a`란 프로퍼티가 없으면 이 객체의 `[[Prototype]]` 링크를 따라가서 수색한다.
- 이 경우, `[[anotherObject]]`에서 2라는 값을 대신 찾아서 프로퍼티 접근의 결괏값을 반환한다.
- 만약 `anotherOBject`에서도 못찾으면 `[[Prototype]]` 연쇄를 다시 따라 올라가고 연쇄 끝에 이르러서도 프로퍼티가 발견되지 않으면 `[[Get]]`은 결괏값으로 `undefined`를 반환한다.
- `for ... in` 루프에서 객체를 순회할 때도 `[[Prototype]]` 연쇄의 검색 과정과 비슷한 방식으로 연쇄를 통해 손길이 닿는 프로퍼티라면 죄다 열거한다.

### 1. `Object.prototype`
- `[[Prototype]]` 연쇄는 결국 내장 프로토타입 `Object.prototype`에서 끝난다.
- 모든 자바스크랩트 객체는 `Object.prototype` 객체의 자손이므로 여기에는 자바스크립트에서 두루 쓰이는 다수의 공통 유틸리티가 포함되어 있다. (`toString()`, `valueOf()`, `hasOwnProperty()`, `isPrototypeOf()`, ...)

### 2. 프로퍼티 세팅과 가려짐
```js
myObject.foo = "bar";

II. 클래스

자바스크립트는 여타 클래스 지향 언어에서 제공하는 클래스라는 추상화된 패턴이나 설계가 전혀 없고, 다만 객체만 있을 뿐이다.

1. 클래스 함수

2. 생성자

function Foo() {
  // ...
}

Foo.prototype.constructor === Foo;  // true

var a = new Foo();
a.constructor === Foo;  // true

</p>

III. 프로토타입 상속

function Foo(name) {
  this.name = name;
}

Foo.prototype.myName = function() {
  return this.name;
};

function Bar(name, label) {
  Foo.call(this, name);
  this.label = label;
}

// Bar.prototype을 Foo.prototype에 연결한다.
Bar.prototype = Object.create(Foo.prototype);

// 여기서 조심! 이제 Bar.prototype.constructor는 사라졌으니까
// 이 프로퍼티에 의존하는 코드가 있다면 수동으로 일일이 해결해야한다.
Bar.prototype.myLabel = function() {
  return this.label;
};

var a = new Bar("a", "obj a");

a.myName();     // "a"
a.myLabel();    // "obj a"

1. 상속하는 방법

2. 클래스 관계 조사

b.isPrototypeOf(c);