prototype
*prototype은 '원형'이라는 뜻을 가지고 있다.
javascript에서 원시 타입(Primitives)을 제외한 나머지 값들은 모두 객체로 이루어져 있다.
javascript는 객체를 상속하기 위해 class가 아닌 prototype이라는 방식을 쓰기 때문에 prototype 기반 언어로 불린다.
2021/01/28 - [개발/Javascript] - 객체(object)
프로토타입 기반 언어(prototype-based language)
=> 모든 객체들이 메서드와 속성들을 상속받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다는 의미
프로토타입 체인(prototype chain)
=> 프로토타입 객체도 또다시 상위 프로토타입 객체로부터 메서드와 속성을 상속받고, 그 상위 프로토타입 객체도 마찬가지로
상속받듯이 계속해서 상위의 prototype객체로 연결되는 방식
function Ultra(){}
Ultra.prototype.ultraProp = true;
function Super(){}
// Super.prototype에 Ultra생성자 함수의 prototype속성이 상속된다.
Super.prototype = new Ultra();
function Sub(){}
//Sub.prototype에 Super생성자 함수의 prototype속성이 상속된다.
Sub.prototype = new Super();
// 인스턴스 o는 Sub.prototype의 속성을 상속받는다.
var o = new Sub();
console.log(o.ultraProp);
//true
-
객체 o에서 ultraProp를 찾는다.
-
없다면 Sub.prototype.ultraProp를 찾는다.
-
없다면 Super.prototype.ultraProp를 찾는다.
-
없다면 Ultra.prototype.ultraProp를 찾는다
프로토타입 체인에서 한 객체의 메서드와 속성들이 다른 객체로 복사되는 것이 아니다.
위에서 보다시피 체인을 타고 올라가며 접근할 뿐이다.
prototype객체 참고
- 모든 객체는 [[prototype]]이라는 인터벌 슬롯(Internal slot)을 가지게 되는데 [[prototype]]의 값은 null 또는 객체이다.
- [[Prototype]]의 값은 Prototype(프로토타입) 객체이며 '__proto__' accessor property로 접근할 수 있다.
- 함수 객체는 일반 객체와는 달리 prototype이라는 속성(property)도 따로 소유하게 된다.
- prototype속성은 상속하고자 하는 속성과 메서드를 담아두는 버킷으로 사용되게 된다.
- 버킷으로 사용된 prototype은 prototype chain을 통해 전달된다.
*인터널 슬롯이라는 것은 내부 속성, 혹은 은닉 속성이라고 이해하면 될 것 같다.
*상속되는 속성과 메서드들은 각 객체가 아니라 객체의 생성자의 prototype속성에 정의되어 있다.
function Human(name) {
this.name = name;
}
let fff = new Human("JJ");
// Human의 [[prototype]] 값
console.log(Human.__proto__) //[Function]
console.log(Human.__proto__ === Function); //false
console.log(Human.__proto__ === Function.prototype); //true
console.log(Human.prototype);
//{constructor: ƒ}
//constructor: ƒ Human(name)
//__proto__: Object
// fff의 [[prototype]] 값
console.log(fff.__proto__);
//{constructor: ƒ}
//constructor: ƒ Human(name)
//__proto__: Object
//prototype속성은 함수객체에만 존재한다.
console.log(fff.prototype); //undefined
[[prototype]]
- 함수를 포함한 모든 객체가 가지고 있는 인터벌 슬롯
- 객체의 입장에서는 자신의 부모역할을 하는 prototype객체를 가리키며 함수 객체의 경우 Function.prototype을 가리킨다.
prototype속성
- 함수 객체만 갖고 있는 속성이다.
- 함수 객체가 생성자로 사용될 경우, 생성된 인스턴스들은 함수명. prototype에 정의된 멤버들을 상속받는다.
constructor
모든 생성자 함수는 constructor 속성을 지닌 객체를 prototype객체로 가지고 있다.
이 constructor 속성은 원본 생성자 함수 자신을 가리킨다.
function Human(name) {
this.name = name;
}
let fff = new Human("JJ");
let hhh = new Human("GG");
console.log(Human.prototype.constructor)
//ƒ Human(name) {
// this.name = name;
//}
console.log(fff.constructor);
//ƒ Human(name) {
// this.name = name;
//}
console.log(hhh.constructor);
//ƒ Human(name) {
// this.name = name;
//}
prototype 변경
생성자의 prototype속성을 직접 변경도 가능하다.
function Human(name) {
this.name = name;
}
let hhh = new Human("GG");
Human.prototype.introduce = function(){
return `Hello my name is ${this.name}`;
}
console.log(hhh.introduce());
//Hello my name is GG
console.log(Human.prototype)
//{introduce: ƒ, constructor: ƒ}
//introduce: ƒ ()
//constructor: ƒ Human(name)
//__proto__: Object
*일반적인 방식으로는 속성은 생성자에서, 메서드는 prototype에서 정의한다.
=> 가독성 측면에서도 더욱 낫다.
참고
'개발 > Javascript' 카테고리의 다른 글
Event (0) | 2021.02.06 |
---|---|
데이터 타입, 표준 내장 객체(Standard Built-in Object), 타입 변환 (0) | 2021.02.03 |
this (0) | 2021.01.29 |
객체(object) (0) | 2021.01.28 |
arguments, rest parameter (0) | 2021.01.28 |