본문 바로가기

Programming/Javascript

10. Javascript 프로토타입 체이닝 (7) - 쓰기를 할 때의 프로토타입 체이닝

javascript logo image

 

프로토타입 체이닝의 여러 특성에 대해서 알아보았는데, 마지막으로 하나 더 특징을 알아보도록 하겠습니다. 바로 '프로토타입 체이닝은 (프로퍼티)읽기 / (메서드)실행 시에만 발생한다'는 점입니다. 이거 갑자기 무슨 소리인지? 생각이 드실 분들도 있겠지만, 의외로 실수가 발생할 수 있는 지점입니다. 

 

풀어서 설명을 하다 보면 오히려 헷갈릴 수 있는 내용이니, 예제를 먼저 살펴보고 나서 설명하겠습니다. 

 

// 생성자 함수
function Rapper(rapName) {
    this.rapName = rapName;
}

Rapper.prototype.lable = 'AOMG';

var loco = new Rapper('LOCO');
var jayPark = new Rapper('JAY.PARK');

console.log(loco.lable);
console.log(jayPark.lable);

 

위의 코드를 살펴보시면, 특별할 것이 없는 흔한 생성자 함수 생성 이후의 객체 생성 ~ 프로토타입 프로퍼티의 출력 과정입니다. 이때 하나 상기해야 하는 부분은, Rapper라는 생성자 함수의 프로토타입 객체에 선언된 프로퍼티를 객체가 어떤 문법으로 호출하였는지입니다. 출력되는 값은 무엇일까요? 당연히 'AOMG'가 2회 출력될 것입니다.

 

이어서 다음 라인을 작성해 보겠습니다. 

 

jayPark.lable = 'H1GER MUSIC';

console.log(loco.lable);
console.log(jayPark.lable);

 

위의 예제에 위 세 줄의 라인을 추가로 작성하였습니다. jayPark 객체에 lable 값을 변경하고, 다시 loco / jayPark 객체의 lable 프로퍼티를 출력하는 명령을 내렸습니다. 그럼 출력 값은 어떻게 될까요? 한 번 고민해보시기 바랍니다. 우선 결과만 말씀드리면, AOMG / H1GER MUSIC 이 각각 출력됩니다. 혹시 왜 이런 결과가 나왔는지 이해가 가셨나요? 

 

우리가 객체에 대해 초반에 공부할 때 설명드렸던 내용을 기억하시는 분들이 있었다면, 이 아티클의 제목과 프로퍼티의 동적생성 규칙, 그리고 프로토타입 체이닝 규칙을 조합해 답을 얻으셨을 것 같습니다. 우선, 위에서 설명드린 원칙을 다시 한 번 짚어보겠습니다. [프로토타입 체이닝은 (프로퍼티)읽기 / (메서드)실행] 에서만 발생한다고 말씀드렸습니다. 

 

그럼 데이터를 '쓰기'를 시도할 때는 프로토타입 체이닝이 발생할까요? 답은 '아니오'입니다. 하나씩 차근차근 살펴봅시다. 우리가 loco / jayPark 객체에서 lable이라는 프로퍼티를 출력하라는 명령을 내렸을 때, Javascript에서는 어떤 일이 벌어질 지 한 번 생각해 봅시다. 우선 loco / jayPark 객체 내부에 해당 프로퍼티가 있는지 여부를 검색하게 됩니다. 그리고 해당 프로퍼티가 없을 경우에는 객체의 부모 프로토타입 객체에 대해 프로토타입 체이닝이 발생하게 됩니다. 그리고 여기서는 부모 객체인 Rapper.prototype에 해당 프로퍼티가 있는지를 검색하게 되고, 값이 있다면 그 프로퍼티의 값을 출력하게 됩니다. 

 

하지만 이와 다르게 '쓰기'를 시도할 경우를 살펴보겠습니다. 우리가 이미 객체에 대해 처음 배울 때 학습했던 내용이니, 특별한 것이 아니죠. jayPark.lable = 'H1GER MUSIC' 이라는 코드를 실행했을 때, 여기서 프로토타입 체이닝이 발생할까요? 아닙니다. 그냥 동적으로 해당 프로퍼티를 jayPark 객체에 생성해 저장을 하게 됩니다. 프로토타입 체이닝이 발생하지 않는다는 의미지요. 

 

아래 두 개의 라인을 다시 보겠습니다. 

 

jayPark.lable = 'H1GER MUSIC';

console.log(loco.lable);
console.log(jayPark.lable);

 

여기서 loco.lable을 출력했을 때는, Rapper.prototype.lable이 출력됩니다. 하지만, jayPark.lable을 실행했을 때는 jayPark 자체에 lable이 있는지를 검사했더니 존재하고 있습니다. 그래서 jayPark.lable이라는 프로퍼티의 값을 직접 출력하게 되어 두 명령어의 출력값이 달라지게 되는 것입니다. 

 

기본적인 내용이지만, 프로토타입 체이닝을 학습하다보면 헷갈리기 쉬운 내용입니다. 추후 객체지향 프로그래밍에 대해 자세히 학습하게 될 때 의외로 영향을 많이 미치는 부분이니, 당연하다 생각하지 말고 여러 번 반복해 학습하고 숙지하시기를 바랍니다.