javaScript의 모든 객체들이 메소드와 속성들을 상속받기위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다는의미.
상속되는 속성과 메소드들은 해당 객체가 아니라 prototype속성에 정의 되어 있다.
즉 prototype은 상속받은 멤버들이 정의되는 곳이다.(해당 객체가 복사되는것이 아닌 마치 체인을 타고 올라가며 접근하는것 처럼 '참조'하고 있음)
프로토타입 객체는 __proto__
속성으로 접근 가능한 내장 객체이고, 'prototype 속성'은 상속 시키려는 멤버들이 정의된 객체를 가리킨다.
Array는 클래스다. 지금가지 써왔던 배열은 Array클래스의 인스턴스였고 Array.메소드 들은 Array클래스의 prototype에서 가져온것 이다.
push, slice ... 은 Array.prototype에 구현되어있다
let plants = {
photosynthesis : true
}
let Rose = {
color: "red"
}
let flower = {
petal : 5,
__proto__ : Rose
}
console.log(Rose.photosynthesis) // undefined
Rose.__proto__ = plants; /* [[Prototype]]의 프로퍼티 값 할당.*/
console.log(Rose.photosynthesis) // true
- __proto__는 [[Prototype]]의 getter,setter 역할을 한다.
- Rose에 photosynthesis라는 프로퍼티가 없기 때문에 [[Prototype]]의 프로퍼티를 자동으로 탐색함.
console.dir(Rose) //red
console.dir(Rose.__proto__) //photosynthesis
[[Prototype]]이 Plants객체를 참조하게 만듬
즉 Rose는 Plants를 상속 받는다 라고 할 수 있음. 객체지향형 프로그래밍의 상속과 비슷.
마찬가지로 Plants에 함수가 멤버로 있다면 Rose에서도 사용이 가능해진다.
근래엔 Object.getPrototypeOf , Object.setPrototypeOf를 사용한다고함.
proto의 값은 객체나 null만 가능하다.
하위 체인에서 상위 체인의 프로퍼티를 수정할수 없다
. 수정시 해당 체인의 프로퍼티가 추가되는거로 간주한다. -> getter만 가능하다는 뜻
순회 대상에 포함
이 된다.hasOwnProperty(key)는 상속프로퍼티를 순회 대상에서 제외할 수 있다.
Object.keys, Object.values 는 기본적으로 상속 프로퍼티를 제외하고 동작한다.
let sampleobj = {};
alert ( sampleobj ) // [object Object]
let sampleobj = {
__proto__ : Object.prototype //Object를 참조 하는게 아님
}
sampleobj.toString()을 호출하면 Object.prototype의 프로퍼티
인 toString()
을 가져오게 된다.
배열의 경우도 new Array()로 Array.prototype을 [[Prototype]]이 참조하여 만들어진다.
Date, Function도 위와 같다.
모든 객체 ( Array.prototype포함 )의 상위에는 Object.prototype이 존재하고 그 상위는 null을 가리킨다.
let arr = [1, 2, 3];
arr.__proto__ === Array.prototype //true
arr.__proto__.__proto__ === Object.prototype //true
실질적으로 프로퍼티가 존재하지 않는다.
추가한 프로퍼티를 사용할 수 있게 된다.
사용을 금지시
한다.let obj = {
0: "Hello",
1: "world!",
length: 2,
};
obj.join = Array.prototype.join;
alert( obj.join(',') ); // Hello,world!
Array.prototype.join = F // join함수를 F함수로 바꿔버림 -> 배열들의 join메서드들은 F함수가 실행됨 ->프로토타입체인 특성
let plants = {
photosynthesis : true
};
let Rose = {};
Rose.__proto__ = plants; //이 과정을
let Rose = Object.create(plants); //이렇게 바꿈.
let plants = {
photosynthesis : true
};
function rose(name) {
this.name = name;
}
rose.prototype = plants; // plants를 참조하는 객체를 생성
let Rose = new rose(); // Rose.__proto__ = photosynthesis
function Rose() {}
/*
디폴트 prototype
Rose.prototype = { constructor: Rose };
*/
class Human {
constructor(name, age) {
this.name = name;
this.age = age;
}
sleep() {
console.log(`${this.name}은 잠에 들었습니다`);
}
}
let kimcoding = new Human('김코딩', 30);
Human.prototype.constructor === Human; // 결과는?
Human.prototype === kimcoding.__proto__; //결과는?
Human.prototype.sleep === kimcoding.sleep; //결과는?
https://ko.javascript.info/prototype-inheritance
https://ko.javascript.info/native-prototypes
https://ko.javascript.info/prototype-methods
https://ko.javascript.info/function-prototype
https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object_prototypes