자바스크립트는 객체지향언어, 프로토타입 기반 언어라고 불린다
JS에는 클래스가 없다. Class
라는 예약어가 있지만 함수의 한 종류일 뿐이다.
따라서 Class가 없으니 상속기능도 없다.
상속을 구현해 사용하는 것이고 이를 함수와 new를 통해 흉내내는 것이다.
프로토타입을 기반으로 상속을 구현한다
라고 이해하면 될 것 같다.
이 프로토타입은 객체와 링크를 통해 구성되어있다. 하나씩 알아보자!
프로토타입 기반 프로그래밍 = 클래스가 없고, 상속과는 다르게 객체를 원형(프로토타입)으로 하여 복제를 통해 객체 동작방식을 다시 사용할 수 있는 것.
객체의 [[Prototype]] 은 부모의 prototype 객체를 바라보며, 이것이 반복(체인) 되다가, prototype 으로 null 을 가지고 있는 객체에서 끝이 난다.
프로토타입에 대해서 간략하게 정리했다. 체인이라는 용어와 prototype에 감이오지 않는다. 다음을 계속 알아보자.
함수에는 prototype
이라는 객체가 존재한다.
함수의 (new)통해 만들어지는 새로운 객체의 생성시점에 __proto__
라는 프로퍼티에 null이 아닌 값이 할당된다.
이 __proto__
는 부모의 prototype 객체를 바라보면서 부모로 거슬러 올라가며 반복(체인)되다가 null을 가진 객체(prototype)에서 반복이 끝이난다.
=> prototype은 부모함수가 가진 객체이고 부모를 통해 만들어진 자식객체들은 자신을 만들어낸 부모의 prototype을 가리키는 __proto__
라는 속성을 가지고 있다.
조금씩 와닿고 있다. 그럼 동작을 자세하게 알아보자.
함수
를 생성하면, Person.prototype Object
가 생성된다.
Prototype Object
는 기본 속성으로 다음 두가지(constructor, __proto__
)를 가진다
constructor
: 내가 선언한 생성자함수 Person를 가리킨다.__proto__
: [[Prototype]] Link이다. 부모의 prototype을 참조한다.prototype
: 부모로부터 생성된 모든 객체가 공유할 부모의 프로퍼티 == 원형객체다시 정리하자면, 함수를 정의할 때 두가지 일이 동시에 부여된다. 그중 하나는 생성자 자격부여, Prototype Object
생성.
constructor
자격이 부여되면 new
를 통해 객체를 만들어 낼 수 있다.Prototype Object
도 같이 생성된다.prototype Object
의 프로퍼티를 조정함으로써 새로 생성되는 객체도 이를 반영하여 생성된다. 다음 예를 보자.function Person() {}
Person.prototype.eyes = 2;
Person.prototype.nose = 1;
let me = new Person();
let you = new Person();
let who = Person(); // => who.eyes는 undefined -> Person에는 해당 프로퍼티가 없기 때문, prototype객체에 존재함.
console.log(me.eyes, you.eyes); => 2 2
//Person이 생성되면 prototype객체가 만들어진다.
//이 후 eyes, nose라는 프로퍼티를 prototype객체에 추가한다.
//2개의 프로퍼티가 추가된 prototype객체를 가진 Person 생성자를 me, you에 호출한다.
me, you
는 new
연산자를 통해 생성된 객체이다. Person
은 함수다. (typeof찍어보면됨)
prototype
속성은 함수만 가지고 있고, __proto__
는 모든 객체가 전부 갖고 있는 속성이다.
따라서 me, you
에는 __proto__
만 존재하고
Person
에는 prototype, __proto__
를 갖고 있는 것이다.
__proto__
는 객체가 생성될 때 부모 함수의 Prototype Object
를 가리킨다.
console.log(me.__proto__);// => {eyes:2, nose:1, constructor...};//가리키는 프로토타입객체 = Person.prototype
console.log(me.__proto__ === Person.prototype); // => true!
console.log(Person.__proto__); // => undefined 가리키는 부모가 없음
new연산자를 쓸수 있는 권한, prototype Object
이 생성.new
를 통해 생성된 객체는 자신의 부모를 가리키는 __proto__
속성을 지님__proto__
속성으로 상위 부모의 prototype Object
를 가리킬 수 있음.체인
이라고 표현함.prototype Object
를 가리키고, 이 prototype Object
에는 그 상위를 가리킬 수 있는 __proto__
속성과 생성자를 가짐-> 객체의 생성자는 function Object(){...}
이므로 함수를 통해 생성된 객체는 object
의 toString
과 같은 속성을 사용할 수 있는 것 => 프로토타입 체인을 통해서 가능해진 것