자바스크립트는 프로토타입기반 언어이다. 프로토타입은 원형 객체를 의미하며 자바스크립트에서 객체를 상속하기 위해 사용하는 방식이다.
모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 프로토타입 객체를 가진다는 의미이기도 하다.
--> 상속되는 속성과 메소드들은 각 객체가 아니라 객체의 생성자의 prototype
이라는 속성에 정의되어 있는것이다.
프로토타입 객체 또한 상위 프로토타입 객체들로부터 메소드 와 속성을 상속 받고 그 상위 객체들도 마찬가지이다. 이처럼 다른 객체에 정의된 메소드와 속성을 한객체에서 사용할 수 있는것이 프로토타입 체인이다.
정확히 말하자면 상속되는 속성과 메소드들은 각 객체가 아니라 객체의 생성자의 prototype이라는 속성에 정의되어 있습니다.
-출처 MDN
JavaScript에서는 객체 인스턴스와 프로토타입 간에 연결(많은 브라우저들이 생성자의 prototype 속성에서 파생된 __proto__
속성으로 객체 인스턴스에 구현하고 있습니다.)이 구성되며 이 연결을 따라 프로토타입 체인을 타고 올라가며 속성과 메소드를 탐색합니다.
Person()
생성자
function Person(first, last, age, gender, interests) {
// 속성과 메소드 정의
this.first = first;
this.last = last;
// 인스턴스 생성
var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
}
person1
의 프로토타입 객체인 Person()
에 정의된 멤버들 name, age, ...을 볼 수 있습니다. — watch, valueOf처럼 Person()의 프로토타입 객체인 Object
에 정의된 다른 멤버들도 볼 수 있습니다. 이는 프로토타입 체인의 동작을 뜻합니다.
Object
탐색위에서 person1
이 Object
에 정의된 메소드를 가져오는 방식
ex)
person1.valueOf()
person1
객체가 valueOf()
메소드를 가지고 있는지 체크합니다. --> 없음person1
의 프로토타입 객체(Person()
생성자의 프로토타입)에 valueOf() 메소드가 있는지 체크합니다.--> 없음Person()
생성자의 프로토타입 객체의 프로토타입 객체(Object()
생성자의 프로토타입)가 valueOf() 메소드를 가지고 있는지 체크합니다. --> 존재함->호출따라서 Object.prototype.watch()
, Object.prototype.valueOf()
등 생성자를 통해 새로 생성되는 인스턴스는 물론 Object.prototype을 상속 받는 객체라면 어떤 객체에서든지 접근할 수 있습니다.
모든 생성자 함수는 constructor
속성을 지닌 객체를 프로토타입 객체로 가지고 있습니다.
constructor
속성은 원본 생성자 함수 자신을 가리키고 있습니다.
function Person(first, last, age, gender, interests) {
this.name = {
first,
last
};
this.age = age;
this.gender = gender;
this.interests = interests;
};
Person.prototype.greeting = function() {
alert('Hi! I\'m ' + this.name.first + '.');
};
Person
상속받는 Teacher
클래스 만들기
function Teacher(first, last, age, gender, interests, subject) {
Person.call(this, first, last, age, gender, interests);
this.subject = subject;
}
subject
추가됨
call()
함수: 첫번재 매개변수는 다른 곳에서 정의된 함수를 현재 컨텍스트에서 실행하도록 합니다. this
로 전달하고 나머지는 실제 함수 실행에 필요한 인자들을 전달합니다.
Teacher()
의 생성자는 Person()
을 상속받았으므로 같은 매개변수들이 필요합니다. 따라서 동일한 매개변수들을 call()
의 인자로 전달하여 실행합니다.
function Teacher(first, last, age, gender, interests, subject) {
this.name = {
first,
last
};
this.age = age;
this.gender = gender;
this.interests = interests;
this.subject = subject;
}
다음과 같은 의미 (Person을 상속받은것이 아닌 그냥 동일한 인자를 정의한것)
class Human {
constructor(name, age) {
this.name = name; //class내의 constructor객체의 this는 인스턴스를 가리킴
this.age = age;
}
sleep() {
console.log(`${this.name}은 잠에 들었습니다`);
}
}
let kimcoding = new Human('김코딩', 30); // 인스턴스 객체의 이름은 김코딩 age는 30
// 실습해보세요
Human.prototype.constructor === Human;
Human.prototype === kimcoding.__proto__;
Human.prototype.sleep === kimcoding.sleep
Human클래스 객체생성
sleep()
사용할 수 있음 --> 프로토타입체이닝
같은 주소값담겨있기 때문에 sleep()
사용 가능
같은 주소값담겨있기 때문에 sleep()
사용 가능
Human.prototype === kimcoding.__proto__
Human.prototype.constuctor === Human
Human
자체에 constructor
가 담겨있기 때문에 Human.prototype
은 저장소고
__proto__
는 저장소의 주소가 담겨있는 주소값이다.