JavaScript에 대하여 - Prototype(2)

유니·2021년 12월 14일
0
post-custom-banner

프로토타입 생성 시점

우리는 지난 글을 통하여 프로토타입과 생성자함수는 한쌍을 반드시이룬다는것을 알아보았다. 그러면 프로토타입의 생성 시점은 언제일까?

답은 "생성자 함수가 생성되는시점에 더불어 같이 생성된다." 이다.

참고로 화살표함수와 같은 경우는 non-constructor로써 프로토타입이 없다.

함수 선언문으로 생성된 생성자함수는 함수선언문 이기에 함수호이스팅이 적용된다. 그래서 자바스크립트엔진에 의해 먼저 실행된다.

console.log(Person.prototype);

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

위와 같이 실행하여도 호이스팅되었기때문에 오류없이 실행된다.

이때 생성된 프로토타입은 오직 constructor 프로퍼티만을 갖는 객체이다. 프로토타입 또한 객체란 뜻이고, 모든 객체는 프로토타입을 가지므로 프로토타입도 자신의 프로토 타입을 갖는다. 이때 프로토타입은 Object.prototype이다. 그렇기에 생성자함수와 프로토타입은 이미 객체화 하여 존재하며, 생성자 함수나 리터럴 표기법에 근거하여 객체를 생성할 경우 프로토타입의 생성된 객체는 [[Prototype]]내부슬롯에 할당되어 프로토타입을 상속받는다.

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

객체는 다양한 방식으로 생성될 수 있으나 추상연산에 의해 생성된다는 공통점이 있다. 프로토타입은 추상 연산이 전달하는 인수에 의해 결정되는데, 이때 인수는 객체의 생성방식에 의해 정해진다.

Object 생성자함수를 통해 생성되는 객체 역시 추상연산이 호출되어 Object.prototype을 전달한다.

new 연산자와 함께 생성자함수를 출하면 역시 추상연산이 호출되는데 이때의 프로토타입은 생성자함수의 prototype에 바인딩된 constructor이다.

프로토타입 체인

프로토타입에서 프로퍼티 추가/삭제를 할 수 있다. 그리고 이렇게 추가/삭제된 프로퍼티는 프로토타입 체인에 즉각 반영된다.

자바스크립트는 객체의 프로퍼티에 접근하려할때 해당 프로퍼티가 존재하지않을경우 [[Prototype]]내부슬롯을 참조하여 자신의 상위(부모)프로토타입의 프로퍼티를 순차적으로 검색하는데 이를 프로토타입 체인이라고한다.

[[Prototype]]내부슬롯을 따라 올라가다보면 최종 종착지는 Object.prototype이다. 그리고 Object.prototype의 [[Prototype]]내부슬롯은 null이다.

프로토타입 체인이란것은 결국 상속과 프로퍼티 검색을 위한 메커니즘이다. 그리고 프로퍼티가 아닌 식별자는 스코프체인에서 검색한다. 프로토타입 체인과 같이 스코프체인 역시 식별자를 검색하기위한 메커니즘이라고 볼 수 있다.

그리고 이 둘은 서로 연관없이 작동하는 것이 아닌 서로 협력하여 프로퍼티와 식별자를 찾는데 사용된다.

오버라이딩과 프로퍼티 섀도잉

오버라이딩이란? 상위클래스가 가지고있는 메소드를 하위클래스가 재정의 하여 사용하는것을 말한다. 이는 프로토타입에서도 일어나는데

const Person = (function() {
  function Person(name){
    this.name = name;
  }
  
  Person.prototype.sayHi = function(){
    console.log(`I say ${this.name}, You say Ha~`);
  }
  
  return Person;
}());

const me = new Person('John');

me.sayHi();

me.sayHi = function(){
  console.log(`I say Ha~, You Say ${this.name}~!`);
};

me.sayHi();

위 선언문을 보면 즉시실행함수 Person을 이용하여 Person생성자함수를 만들고, Person에 sayHi메소드를 추가하였다. 그리고 const me를 new Person함수로 선언하고 안의 인자값으로써 John을 주었다.

그리고 me.sayHi()하면 I say John, You say Ha~ 가 출력되는것을 볼수있는데, 이때 me의 sayHi메소드를 재선언 할 경우, 즉 다시말해 오버라이딩 할 경우 Person의 sayHi를 찾아가는것이 아닌 me가 가지고있는 sayHi를 찾아가게되어 me의 sayHi메소드를 실행하게된다. 이때 me.sayHi()로 인해 가려진 Person.prototype.sayHi를 가르켜 프로퍼티 섀도잉 이라고 한다.

profile
Prospective Junior Front-end Developer
post-custom-banner

0개의 댓글