[240325] 19장 프로토타입 (2)

19장 프로토타입 (2)

함수 객체의 prototype 프로퍼티

// 함수 객체는 prototype 프로퍼티를 소유한다.
(function () {}).hasOwnProperty('prototype'); // true
// 일반 객체는 prototype 프로퍼티를 소유하지 않는다.
({}).hasOwnProperty('prototype'); // false
  • 함수 객체만이 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다.
  • non-constructor , 화잘표 함수, ES6 메서드 축약 표현으로 정의한 메서드는 prototype 프로퍼티를 소유하지 않고, 프로토타입도 생성하지 않는다.
// 화살표 함수
const Person = name => {
	this.name = name;
}

// 메서드 축약 표현
const obj = {
	foo() {} 
}

console.log(obj.foo.hasOwnProperty('prototype)); // false
console.log(obj.foo.prototype); // undefined
  • 모든 객체가 가지고 있는 (Object.prototype 으로부터 상속 받은) proto 접근자 프로퍼티와, 함수 객체만이 가지고 있는 prototype 프로퍼티는 결국 동일한 프로토타입을 가리킨다. 하지만 프로퍼티를 사용하는 주체가 다르다.
  • TODO 노션 괜찮아지면 사진 업로드

프로토타입의 constructor 프로퍼티와 생성자 함수

  • 모든 프로토타입은 constructor 프로퍼티를 갖는다.
  • constructor 프로퍼티는 prototype 프로퍼티로 자신을 참조하고 있는 생성자 함수를 가리킨다.
  • 이 연결은 생성자 함수가 생성될 때, 이뤄진다.
function Person(name) {
	this.name = name;
}

const me = new Person('Lee');
console.log(me.constructor === Person); // true

4. 리터럴 표기법에 의해 생성된 객체의 생성자 함수와 프로토타입

  • 생성자 함수에 의해 생성된 인스턴스는 프로토타입의 constructor 프로퍼티에 의해 생성자 함수와 연결된다.
const obj = new Object(); 
console.log(obj.constructor === Object); // true
  • 리터럴 표기법은, 추상 연산을 통해 OrdinaryObjectCreate를 호출하여 Object.protorype을 프로토타입으로 갖는 빈 객체를 생성한다.
  • 객체 리터럴에 생성된 객체는 Object 생성자 함수가 생성한 객체가 아니다.
    • new.target 의 확인이나 프로퍼티를 추가하는 처리 등 세부 내용은 다르다.
  • 리터럴 표기법에 의해 생성된 객체도 가상적인 생성자 함수를 갖는다.
  • 프로토타입과 생성자 함수는 단독으로 존재할 수 없고 언제나 쌍으로 존재한다.
  • 생성자 함수를 리터럴 표기법으로 생성한 생생성자 함수로 생각해도 크게 무리는 없다.
리터럴 표기법 생성자 함수 프로토타입
객체 리터럴 Object Object.prototype
함수 리터럴 Function Function.prototype
배열 리터럴 Array Array.prototype
정규 표현식 리터럴 RegExp RegExp.prototype

5. 프로토타입 생성 시점

  • 리터럴 표기법에 의해 생성된 객체도 생성자 함수와 연결된다.

→ 객체는 리터럴 표기법 or 생성자 함수에 의해 생성되므로, 결국 모든 객체는 생성자 함수와 연결되어 있다.

  • 프로토타입은 생성자 함수가 생성되는 시점에 더불어 생성

→ 언제나 쌍으로 존재해야 함

1. 사용자 정의 생성자 함수

  • 일반 함수로 정의한 함수는 new 연산자와 함께 생성자 함수로서 호출 가능
  • 생성자 함수로서 호출할 수 있는 함수, 즉 constructor 는 함수 정의가 평가되어 함수 객체를 생성하는 시점에 프로토타입도 더불어 생성된다.
    • 함수 호이스팅 되어, 함수 선언문으로 정의된 Person 생성자 함수는 먼저 평가되어 함수 객체가 됨
    • 프로토타입도 더불어 생성
    • 생성된 프로토타입은 Person 생성자 함수의 prototype 프로퍼티에 바인딩된다.
  • 생성된 프로토타입의 프로토타입은 Object.prototype 이다.
console.log(Person.prototype); // {constructor: f}

// 생성자 함수
function Person(name){
	this.name = name;
}

2. 빌드인 생성자 함수

  • Object, String, Number, Function, Array, RegExp, Date, Promise
  • 빌드인 함수도 일반함수와 마찬가지로 빌트인 생성자 함수가 생성되는 시점에 프로토타입 생성
  • 모든 빌트인 생성자 함수는 전역 객체가 생성되는 시점에 생성된다.
  • 생성된 프로토타입은 빌트인 생성자 함수의 protype 프로퍼티에 바인딩된다.
  • 생성자 함수 또는 리터럴 표기법으로 객체를 생성하면 프로토타입은 생성된 객체의 [[Prototype]] 내부 슬롯에 할당된다.

6. 객체 생성 방식과 프로토타입의 결정

생성 방법

  • 객체 리터럴
  • Object 생성자 함수
  • 생성자 함수
  • Object.creat 메서드
  • 클래스

→ 세부적인 객체 생성 방식 차이는 있으나 추상연산 OrdinaryObectCreate 에 의해 생성된다는 공통점이 있다.

추상연산

  • 자신이 생성할 객체의 프로토타입을 인수로 전달 받음 자신이 생성할 객체에 추가할 프로퍼티 목록을 옵션으로 전달할 수 있음
  • 빈 객체를 생성 후, 객체에 추가할 프로퍼티 목록이 인수로 전달된 경우 프로퍼티 객체에 추가
  • 인수로 전달 받은 프로토타입을 자신이 생성한 객체의 [[Prototype]] 내부 슬롯에 할당한 다음, 생성한 객체를 반환
  • 즉, 프로토타입은 추상 연산에 전달되는 인수에 의해 결정된다. 인수는 객체가 생성되는 방식에 의해 결정됨

1. 객체 리터럴에 의해 생성된 객체의 프로토타입

const obj = { x:1 };

위 객체 리터럴이 평가되면 추상 연산에 의해 Object 생성자 함수와 Object.prototype 과 생성된 객체 사이에 연결이 만들어진다.

  • Object.prototype 프로토타입을 갖게됨
  • obj 객체는 constructor 프로퍼티, hasOwnProperty 메서드 등을 소유하지 않지만, 자신의 프로토타입인 Object.prototype 의 constructor 를 자신의 자산인 것처럼 사용할 수 있다.

2. Object 생성자 함수에 의해 생성된 객체의 프로토타입

const obj = new Object(); 
  • Object.prototype 전달 받음
  • 객체 리터럴과 동일한 구조
  • 차이는 프로퍼티를 추가하는 방식에 있음
    • 객체 리터럴 : 객체 리터럴 내부에 프로퍼티 추가
    • Object 생성자 함수: 일단 빈 객체 생성하고 프로퍼티 추가

3. 생성자 함수에 의해 생성된 객체의 프로토타입

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

const me = new Person('Lee');
  • new 연산자와 함께 사용하면 추상 연산 호출
  • 생성자 함수의 prototype 프로퍼티에 바인딩 되어 있는 객체 전달

7. 프로토타입 체인

  • 자바스크립트는 객체의 프로퍼티에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없다면 [[Prototype]] 내부 슬롯의 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다. 이를 프로토타입 체인이라 한다.
  • 프로토타입 체인의 최상위에 위치하는 객체는 언제나 Object.prototype
    • 체인의 종점 (end of prototype chain)
    • [[Prototype]] 내부 슬롯의 값은 null
    • Object.prototype 에서도 검색할 수 없으면 undefined 반환
  • 프로토타입 체인 (상속과 프로퍼티 검색을 위한 메커니즘)
  • 스코프 체인 (식별자 검색을 위한 메커니즘)
  • 스코프 체인과 프로토타입 체인은 서로 연관없이 별도로 동작하는 것이 아니라 서로 협력하여 식별자와 프로퍼티를 검색하는 데 사용

Categories:

Updated:

Leave a comment