JS
는 C
C++
와는 다르게 클래스 기반이 아닌 프로토타입 객체 지향 언어 이다.
JS
의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결되어 있다.
그리고 이것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티 또는 메소드를
상속받아 사용할 수 있게 한다. 이러한 부모 객체를 프로토타입 이라고 합니다.
⭐ 클래스 기반 객체지향 언어와 다른점
클래스 기반 객체지향 프로그래밍 언어는 객체 생성 이전에 클래스를 정의하고 이를 통해
객체(인스턴스)를 생성한다.
하지만JS
는 프로토타입을 기반으로 하는 객체지향 언어이기에 클래스가 없어도 객체를
생성할 수 있다. (ECMAScript 6에서는 클래스가 추가되었다)
⭐ 프로토타입을 사용하는 이유
부모 객체에 자주 사용하는 메서드를 프로퍼티로 등록하면, 다른 객체들은 프로퍼티를
생성할 필요 없이 부모객체만 프로토타입으로 참조하여 필요한 메서드를 상속받아서
간편하게 사용할 수 있기 때문입니다.
JS
의 객체는 [[Prototype]] 라는 숨김 프로퍼티를 갖습니다. 이 숨김 프로퍼티의 값은null
이거나 다른 객체에 대한 참조가 되는데, 다른 객체를 참조하는 경우에는아래 그림에서
object
에서 프로퍼티를 읽으려고 하는데, 프로퍼티가 존재하지
않습니다. 이런 경우 자동으로JS
에서는object
가 참조하는 프로토타입에서
프로퍼티를 검색하게 됩니다. 이런 방식을 프로토타입 상속 이라고 합니다.
[[Prototype]] 프로퍼티는 내부 프로퍼티면서 숨겨진 프로퍼티지만
__proto__
를
사용하면 개발자가 값을 설정할 수 있습니다.
rabbit
객체에는eats
라는 프로퍼티가 없지만animal
객체를 프로토타입으로
참조 함으로써 참조 대상(animal)에서eats
라는 프로퍼티를 검색해서 상속받습니다.
__proto__
라는 특성을 참조합니다.arr 배열을 살펴보면
push()
메서드를 생성한적이 없지만 사용할 수 있습니다.
그 이유는 부모객체(프로토타입)으로 부터push()
메서드를 상속받았기 때문에
따로 메서드를 만들지 않아도 언제든지 사용할 수 있습니다.
Array.prototype
배열에 관한 프로토타입 확인
/* 문자열에 관련된 프로토 타입 */
String.prototype.yell = function () {
console.log(this); // 자신을 호출하는 문자열을 참조합니다.
}
"hello".yell() // * 출력 : [String: 'hello']
/*
동작 원리
1. 문자열 프로토타입의 객체의 프로퍼티로 yell 특성 추가
2. 해당 특성은 자신을 호출하는 문자열을 출력합니다. (this)
3. "hello" 문자열이 yell() 메서드를 호출하므로, this가 자신을 호출한 문자열을 출력 합니다.
*/
문자열 프로토타입에
yell()
특성이 추가 된 것을 확인
사용자가 생성한 메서드와 기존에 프로토타입에 생성되있던 메서드를 범용해서 사용
prototype
은 메서드나 특성을 추가하는 실제 객체로 작동합니다.
__proto__
는 특성 이름으로 피연산자의 프로토타입을 참조하는 특별한 이름입니다.
prototype을 이용하면 객체에 메서드를 추가할 수 있고,
__proto__
프로퍼티는
피 연산자가 참조하는 객체를 출력하거나, 참조 대상 프로토타입을 변경할 수 있습니다.