[Javascript]03-5. 프로토타입 체이닝

Elen li·2021년 10월 29일
0
post-thumbnail

자바와는 다르게 자바스크립트에서는 클래스의 기능이 없다.
대신 객체 리터럴이나 생성자 함수로 객체를 생성하는데, 이렇게 생성된 객체의 부모 객체가 '프로토타입 객체'다.
상속 개념과 마찬가지로 자식 객체는 부모 객체가 가진 프로퍼티 접근이나 메서드를 상속받아 호출하는 것이 가능하다.

프로토 타입의 두가지 의미

  • 자바스크립트는 프로토타입 기반의 객체지향 프로그래밍을 지원합니다.
  • 자바스크립트의 모든 객체는 자신의 부모 프로토타입 객체를 가리는 참조 링크 형태의 숨겨진 프로퍼티가 있다.이러한 링크를 '암묵적 프로토타입 링크 (implicit prototype link)' 라고 부르며 이것은 모두 [[Prototype]] 프로퍼티에 저장됩니다. 이러한 링크를 [[Prototype]] 링크라고 부릅니다.

함수 객체의 prototype 프로퍼티 vs [[Prototype]] 링크

  • 이 둘을 잘 구분해야 하는데, 구분하기 위해서는 자바스크립트의 객체 생성 규칙을 알아야 합니다.

    <생성규칙>
    자바스크립트에서 모든 객체는 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 프로토타입 객체를 자신의 부모 객체로 설정하는 [[Prototype]]링크로 연결한다.

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

// foo 객체 생성
var foo = new Person('foo');

console.dir(Person);
console.dir(foo);

객체 리터럴 방식으로 생성된 객체의 프로토타입 체이닝

특정 객체의 프로퍼티나 메서드에 접근하려고 할 때, 해당 객체에 접근하려는 프로퍼티 또는 메서드가 없다면 [[Prototype]]링크를 따라 자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티를 차례대로 검색하는 것을 '프로토타입 체이닝'이라고 합니다.

  • 아래 코드로 프로토타입 체이닝을 이해할 수 있습니다.
    1) myObject에 정의되지 않은 hasOwnProperty()가 정상동작합니다.
    2) 같은 방법으로 정의되지 않은 myObject.sayNickName()을 호출하면 에러가 표시됩니다.
var myObject = {
  name: 'foo',
  sayName: function() {
    console.log('My Name is ' + this.name);
  }
};

myObject.sayName(); // (출력값) My Name is foo
console.log(myObject.hasOwnProperty('name')); // (출력값) true
console.log(myObejct.hasOwnProperty('nickName')); // (출력값) false
myObject.sayNickName(); // Uncaught TypeError: Object #<Object> has no method 'sayNickName'
  • 위의 결과가 나오는 이유는 아래와 같습니다.
    1) 객체 리터럴로 객체 생성한 객체는 Object()라는 생성자로 생성됨
    2) 이 Object() 생성자도 prototype 이라는 프로퍼티 속성을 갖고 있음
    3) myObject는 Object() 생성자 함수의 prototype 프로퍼티가 가리키는 Object.prototype 객체를 자신의 프로토 타입 객체로 연결합니다.

생성자 함수로 생성된 객체의 프로토타입 체이닝

생성자 함수로 객체 리터럴 방식과 약간 다른 프로토 타입 체이닝이 이뤄집니다.
그러나, “객체가 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 객체를 자신의 프로토타입 객체(부모 객체)로 취급한다” 라는 기본 원칙은 잘 지켜집니다.

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

// foo 객체 생성
var foo = new Person(‘foo’, 30, ‘tennis’);

// 프로토타입 체이닝
console.log(foo.hasOwnProperty(‘name’));

// Person.prototype 객체 출력
console.log(Person.prototype);

프로토타입 체이닝의 종점 (Object.prototype)

프로토타입 체이닝의 종점은 Object.prototype 이다.
Object.protytpe에는 hasOwnProperty() 나 isPrototypeOf() 등과 같이 모든 객체가 호출 가능한 표준 메서드들이 정의되어 있습니다.

기본 데이터 타입 확장

기본 데이터 (숫자, 문자열, 배열 등)에서 사용되는 표준 메서드들의 경우 이들의 프로토타입인 Number.prototype, String.prototype, Array.prototype 등에 정의되어 있다. 이들 역시 최상위 Object.prototype을 자신의 프로토타입으로 가지고있어서 프로토타입 체이닝으로 연결된다.

표준 빌트인 프로토타입에 직접 정의한 메서드 추가하기

String.prototype.testMethod = function() {
  console.log(‘This is the String.prototype.testMethod());
}

var str =this is test”;
str.testMethod(); // (출력값) ‘This is the String.prototype.testMethod()

console.dir(String.prototype);
profile
Android, Flutter 앱 개발자입니다.

0개의 댓글