프로토타입(Prototype) 톺아보기
자바스크립트는 객체지향 언어입니다. 하지만 C++. JAVA, PHP와 같은 언어와 다르게 클래스가 없었습니다. ES6에 class가 있지만 이는
Syntax Sugar
일뿐 내부적으로는Prototype
을 통해 상속을 흉내는 건 마찬가지입니다. 때문에 class 기반언어라고 부르지 못하고 자바스크립트를 프로토타입 기반언어라고 부릅니다.
프로토타입이란 무엇이고 자바스크립트는 어떤 방식으로 상속을 하는지 자바스크립트 내부 동작 원리에 대해서 알아보자.
프로토타입(Prototype)
자바스크립트에는 Prototype Link
와 Prototype Object
라는 것이 존재한다. 그리고 이 둘을 Prototype
이라고 부른다.
프로토타입 객체(Prototype Object)
자바스크립트는 객체지향 언어이고,
객체는 언제나 함수(Function)로 생성된다.
function Person() {} // => 함수
var personObject = new Person(); // => 함수로 객체를 생성
personObject 객체는 Person이라는 함수로 생성된 객체이다. 이렇듯 언제나 객체는 함수에서 시작된다.
var obj = {};
위 코드는 다음 코드와 같다.
var obj = new Object();
위 코드에서 Object
가 자바스크립트에서 기본적으로 제공하는 함수
이다.
Object도 함수다!
Object와 마찬가지로 Function, Array도 모두 함수로 정의되어 있다.
그렇다면 이것이 Prototype Object랑 무슨 상관이 있을까? 함수가 정의될 때는 2가지 일이 동시에 이루어진다.
-
해당 함수에 Constructor(생성자) 자격 부여
Constructor 자격이 부여되면 new를 통해 객체를 만들어 낼 수 있게 된다. 이것이 함수만 new 키워드를 사용할 수 있는 이유이다.
constructor가 아니면 new를 사용할 수 없다! -
해당 함수의 Prototype Object 생성 및 연결
함수를 정의하면 함수만 생성되는 것이 아니라 Prototype Object도 같이 생성이 된다. 함수는 prototype이라는 속성을 통해 Prototype Object에 접근할 수 있다. Prototype Object는 일반적인 객체와 같으며 기본적인 속성으로constructor
와__proto__
를 가지고 있다.
prototype 속성으로 Prototype Object에 접근
constructor
는 Prototype Object와 같이 생성되었던 함수를 가리키고 있다.
__proto__
는 프로토타입 링크 (Prototype Link)다. 아래에서 다시 확인해보자.
객체 생성시 일어나는 일
아래 새로운 Car() 함수를 생성하고 console.dir()로 car.prototype과 car.prototype.constructor를 찍어보면 아래 화면과 같이 출력된다.
function Car() {
console.log('car');
}
console.dir(Car.prototype);
console.dir(Car.prototype.constructor);
- console.dir(Car.prototype); 출력
- Car.prototype 객체는
constructor
와__proto__
가 있다.
- Car.prototype 객체는
결과를 그림으로 표현하면 아래와 같다.
여기서 중요한 핵심은 함수 객체와 프로토타입 객체는 서로를 바라보고 있다는 점(참조)이다.
프로토타입 링크 (Prototype Link)
객체 생성
function Car(name, wheels){
this.name = name;
this.wheels = wheels;
}
Car.prototype.gasoline = function(x){return x + '리터 만큼 충전완료'}
//car 객체 생성
var benz = new Car('banz', 4);
var audi = new Car('audi', 4);
객체를 생성하면 아래 그림과 같이 Car() 생성자 함수와 프로토타입 객체도 함께 생성된다.
또한 new 키워드를 이용해 var benz = new Car('banz', 4);
와 var audi = new Car('audi', 4);
benz 객체와 audi 객체를 생성한다.
여기서 두 new 객체 또한 프로토타입 객체(Prototype Object)를 참조한다.
이를 총 정리한 그림은 아래와 같다.
여기서 __proto__
는 프로토타입 링크 (Prototype Link)이며 프로토타입 객체를 연결한다.
프로토타입 체이닝(prototype chaining)
console.log(benz.gasoline(1));
과 console.log(audi.gasoline(2));
를 찍어보면 어떻게 될까?
console.log(benz.gasoline(1));
//1리터 만큼 충전완료
console.log(audi.gasoline(2));
//2리터 만큼 충전완료
두 객체에 gasoline()이 정의되어 있지 않지만 참조되어있는 프로토타입 객체의 gasoline()이 있기 때문에 gasoline을 참조 할 수 있다.
이를 프로토타입 체이닝(prototype chaining)이라고 한다.
정리
- 자바스크립트는 gasoline()을 호출할 경우 먼저 객체 내부에서 값을 스캔한다.
- 만약 값이 없을 경우
__proto__
혹은 프로토타입 링크 (Prototype Link)라고 불리는 녀석을 타고 부모 역할을 하는 프로토타입 객체를 스캔한다.
이런 과정을 통해 자바스크립트는 상속기능을 흉내내 사용할 수 있다.
프로토타입 체이닝의 핵심
__proto__
속성은 모든 객체들이 가지고 있다.__proto__
속성은 자신의 부모 역할을 하는 상위 프로토타입을 가리킨다.- 특정 속성을 찾을때 상위 프로토타입을 타고 쭉 올라가 스캔 하는데 이를 프로토타입 체이닝이라고 한다.
- 최상위 프로토타입은 Object의 Prototype Object 이다. 여기 까지 값을 스캔하고 없다면 undefind를 출력한다.
Reference
인사이드 자바스크립트
[Javascript ] 프로토타입 이해하기_오승환님의 블로그
[JS Core]JavaScript 프로토타입 체이닝(Prototype Link, Prototype Object)
Author And Source
이 문제에 관하여(프로토타입(Prototype) 톺아보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@thyoondev/프로토타입Prototype-톺아보기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)