6-2 프로토타입 체이닝

var 어레이 = [4, 2, 1];
어레이.sort();

위와같은 array 자료형에서 sort()같은 함수를 사용할 수 있는 이유가 무엇일까?

var 어레이 = new Array(4, 2, 1);
// var 아이폰 = new 공장();

배열을 생성하는 코드는 내부적으로 위와 같이 동작한다.

그림-4

Array.prototype에 sort() 함수가 정의되어 있기 때문에, 어레이 인스턴스에서도 sort() 함수를 사용할 수 있는 것이다.

그림-5

이제 MDN문서에서 보던 Array.prototype의 의미를 이해할 수 있다.

isArray, from 등 prototype 프로퍼티에 포함되어 있지 않은 메서드는 인스턴스에서 직접 호출할 수 없다.생성자 함수에서 직접 접근해야 한다.

var 어레이 = [4, 2, 1];
어레이.forEach(() => {});
Array.isArray(어레이); // instance를 매개변수로 받음

isArray를 이렇게 정의한 것은 null.isArray(), undefined.isArray()를 호출하면 TypeError가 발생하기 때문이다.

만약 모든 array 자료형에서 사용할 수 있는 함수를 추가하고 싶다면 다음과 같이 Array.prototype에 함수를 추가하면 된다.

Array.prototype.함수이름 = function () {
  // 함수 내용
};

var 어레이 = [4, 2, 1];
어레이.함수이름();

만약 어레이 인스턴스에서 prototype에 정의한 함수와 동일한 이름의 함수를 정의하면 어떻게 될까?

Array.prototype.함수이름 = function () {
  console.log("Array prototype");
};

var 어레이 = [4, 2, 1];
어레이.함수이름 = function () {
  console.log("Array instance");
};

그림-6

프로토타입 체인에서 가장 먼저 찾은 함수가 호출되기 때문에, 인스턴스에서 정의한 함수가 호출된다.

클래스 기반 언어에서는 상속을 사용하지만, 자바스크립트와 같은 프로토타입 기반 언어에서는 객체를 원형(prototype)으로 삼고 이를 복제함으로써 상속과 비슷한 효과를 얻는다.

var 어레이 = [4, 2, 1];
어레이(.__proto__).push(3);
어레이(.__proto__)(.__proto__).hasOwnProperty(2); // true

proto 는 생략할 수 있으므로 프로토타입 체이닝에 의해 배열 인스턴스에서도 Object의 prototype 메서드를 사용할 수 있다.

var Grade = function () {
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i < args.length; i++) {
    this[i] = args[i];
  }
  this.length = args.length;
};

var g = new Grade(100, 80);

Grade의 인스턴스 g 는 유사배열객체이다.

g { 0: 100, 1: 80, length: 2 }

따라서 배열 메서드를 사용할 수 없다.

이를 가능하게 하고 싶다면, 인스턴스 g의 proto, 즉 Grade.prototype 이 배열의 인스턴스를 바라보게 해주면 된다.

Grade.prototype = [];

g.pop();
g.push(90);

results matching ""

    No results matching ""