규도자 개발 블로그

[JavaScript/자바스크립트] 프로토타입(Prototype)에 대한 이해 본문

HTML/CSS/JS/JavaScript

[JavaScript/자바스크립트] 프로토타입(Prototype)에 대한 이해

규도자 (gyudoza) 2019. 3. 25. 22:20

[JavaScript/자바스크립트] 프로토타입(Prototype)에 대한 이해

자바스크립트의 모든 객체는 자신을 생성한 객체 원형에 대한 숨겨진 연결을 갖는다. (__proto__) 이때 자기 자신을 생성하기 위해 사용된 객체원형을 프로토타입이란 한다. 자바스크립트의 모든 객체는 Object 객체의 프로토타입을 기반으로 확장 되었기때문에 이 연결의 끝은 Object 객체의 프로토타입 Object다.


function CreatePrototype(){};
let createObj = new CreatePrototype();
console.log(createObj);

당장에 위의 코드를 브라우저 콘솔창에 치면 __proto__의 constructor안에 해당 변수에 할당된 Prototype의 원형인 function CreatePrototype();을 확인할 수 있다. 이것이 바로 위에서 말한 자신을 생성한 객체 원형에 대한 숨겨진 연결이자 객체의 프로토타입이라고 한다. createObj의 프로토타입은 CreatePrototype인 것이다.

그리고 constructor와 연결돼있는 __proto__를 재차 까보면 비어있는 function을 찾을 수 있다. 자바스크립트 객체 생성자인 constuctor는 function (){};이라는 무명함수 프로토타입에 의해서 생성된 것이라는 의미이다.

그리고 또 이 function의 __proto__를 까보면 Object라는 친구가 나온다. 이것이 위에서 설명했던 연결의 끝인 프로토타입 Object이다. 그래서 우리는 만들어놓은 객체에서 선언해놓지도 않은 toString()을 마음껏 쓸 수 있는 것이다. 어떤 객체든 __proto__를 찾아 계속 올라가보면 결국 Object라는 최상위 프로토타입이 있고 이 최상위 프로토타입에 toString이라는 함수가 선언돼있기 때문에 쓸 수 있는 것이다. 이것을 프로토타입 체인이라고 부른다.


프로토타입 체인으로 인해 하위 객체는 상위객체의 프로퍼티와 메소드를 상속받는다. 그리고 동일한 이름의 프로퍼티와 메소드를 재정의 하지 않는 이상 상위에서 정의한 내용을 그대로 담습한다. 하지만! 상속받는다는 말에 약간 어폐가 있다. 위에서 console.log(createObj);를 아무리 조회해봐도 toString이라는 함수가 정의돼있지 않지만 toString을 쓰면 출력이 된다. 이것은 최상위 프로토타입인 Object프로토타입에 정의돼있는 toString을 쓰기 때문이다. 상속이 아니라 공유의 개념이라고 보면 쉽다. 그래서 위의 예제와 이어서 CreatePrototype의 프로토타입에 toString이라는 function을 추가하면 createObj.toString을 통해 해당 함수를 호출할 수 있게 된다.

 이 함수는 createObj.toString();을 콜 했을 때 계속 __proto__를 찾아들어가서 CreatePrototype에 있는 toString();과 만나 출력되고 있는 것이다. 객체지향 언어에서의 오버라이딩과 비슷한 개념이라고 생각하면 된다. 아래 코드로 확인할 수 있다.

CreatePrototype.prototype.toString = function(){ console.log('called by overwrited function');}
console.log(createObj.toString());
//called by overwrited function
//그냥 createObj를 출력해보면 toString()이라는 애는 없는 걸 확인할 수 있다.
console.log(createObj);
//__proto__
//대신 다른 변수를 추가시켜보면 그대로 출력되는 걸 확인할 수 있다.
createObj.test = 'test';
console.log(createObj);
//test : "test"
//__proto__ : 

그럼 이걸 어따 써?

자바스크립트에서 어떤 객체를 참고하고 있는 하위 객체들이 공유할 수 있는 값 혹은 함수를 만들 때 쓰면 되겠다. 선언도 하지 않은 변수나 객체에 계속 property를 쑤셔 박으려는 어줍잖은 노력도 방지할 수 있다.(맞다. 내 얘기다) 그리고 애초에 자바스크립트는 동적타입 언어인 데다가 어떤 자료형을 변수에 대입하든 __proto__에 해당 자료형의 원형인 객체들이 자리잡고 있을 뿐더러 그곳을 확인하면 toLocaleString처럼 유용한 함수가 이미 만들어져있을 때도 있으니 그것을 확인하는 용도로 쓰면 될 것이다. (toLocaleString에 대한 자세한 사용법은 내가 쓴 게시물 혹은 모질라 개발자 웹문서 : Number.prototype.toLocaleString()을 참고하면 된다.)

Comments