Prototype이란?
자바스크립트에는 constructor(객체 찍어내는 기계)말고도 상속을 해주는 장치가 하나 더 있다!
바로 prototype 이다.
기계를 만들면, 우리가 모르게 prototype 이라는 게 생성된다.
function 기계(){
this.name = 'Kim';
this.age = 15;
}
var 학생1 = new 기계();
var 학생2 = new 기계();
console.log(기계.prototype);
'기계.prototype' 은 기계의 부모유전자입니다.
기계.prototype 에 변수나 함수가 들어있다면 기계로부터 생성되는 오브젝트(자식)들은 모두 그것들을 물려받아 쓸 수 있습니다.
function 기계(){
this.name = 'Kim';
this.age = 15;
}
기계.prototype.gender = '남';
var 학생1 = new 기계();
var 학생2 = new 기계();
console.log(학생1.gender); //'남'이 출력됩니다
기계.prototype.gender = '남'; 를 해석하자면 기계의 부모에 gender라는 키와 '남'이라는 키의값을 부여해준 것입니다.
이때, 학생1은 본인이 gender 속성을 가지지 않았지만, 기계의 prototype(부모유전자)이 gender 라는 속성을 가지고 있기때문에 가져다 씁니다.
prototype 의 작동원리
도대체 왜 prototype에 추가한 데이터는 자식들이 자유롭게 가져다 쓸 수 있을까?
console.log(학생1.gender); //'남'이 출력됩니다
자바스크립트에서 오브젝트를 출력할때 이런 순서를 거칩니다.
(1) 학생1 본인안에 gender 라는 속성이 있는가? ㄴㄴ
(2) 그럼 부모유전자(prototype)에 gender 라는 속성이 있는가? ㄴㄴ
(3) 그럼 부모의 부모유전자(prototype)에 gender 라는 속성이 있는가? ㄴㄴ
(4) 그럼 부모의 부모의 부모유전자(prototype)에 gender 라는 속성이 있는가? ....
내가 직접 가지고 있는지 검사하고, 만약 내가 가지고 있지 않으면 부모 유전자들을 차례로 검사하는구나!
prototype으로 설명하는,
자바스크립트 toString()을 쓸 수 있는 이유
자바스크립트에는 sort, push, toString, map, forEach 등 array나 object 에 붙여쓸 수 있는 내장함수들이 있습니다
어떻게 이것이 가능할까요?
var arr = [1,2,3];
console.log( arr.toString() ); //가능
이것이 가능한 이유는 arr의 부모유전자가 toString()을 가지고 있기 때문입니다 (혹은 부모의 부모가)
사실 아래의 코드 두가지는 같은 코드입니다.
차이점은 위에는 인간이, 아래는 컴퓨터가 만드는 방식이지요.
var arr = [1,2,3];
var arr = new Array(1,2,3);
사람은 그냥 보기 편하게 []를 써서 바로 만들지만, 컴퓨터는 항상 new를 이용해서 기계(Array)에서 객체를 뽑아내는 (상속)방식으로 객체를 만들어냅니다.
console.log(Array.prototype);
constructor: ƒ, at: ƒ, concat: ƒ, copyWithin: ƒ, fill: ƒ, …]at: ƒ at()concat: ƒ concat()constructor: ƒ Array()copyWithin: ƒ copyWithin()entries: ƒ entries()every: ƒ every()fill: ƒ fill()filter: ƒ filter()find: ƒ find()findIndex: ƒ findIndex()findLast: ƒ findLast()findLastIndex: ƒ findLastIndex()flat: ƒ flat()flatMap: ƒ flatMap()forEach: ƒ forEach()includes: ƒ includes()indexOf: ƒ indexOf()join: ƒ join()keys: ƒ keys()lastIndexOf: ƒ lastIndexOf()length: 0map: ƒ map()pop: ƒ pop()push: ƒ push()reduce: ƒ reduce()reduceRight: ƒ reduceRight()reverse: ƒ reverse()shift: ƒ shift()slice: ƒ slice()some: ƒ some()sort: ƒ sort()splice: ƒ splice()toLocaleString: ƒ toLocaleString()toReversed: ƒ toReversed()toSorted: ƒ toSorted()toSpliced: ƒ toSpliced()toString: ƒ toString()unshift: ƒ unshift()values: ƒ values()with: ƒ with()Symbol(Symbol.iterator): ƒ values()Symbol(Symbol.unscopables): {at: true, copyWithin: true, entries: true, fill: true, find: true, …}[[Prototype]]: Object
undefined
console.log(Array.prototype); 를 입력하면, 위의 코드처럼 다양한 메소드를 이미 보유하고 있습니다
Object 자료형도 똑같이 new Object() 이런 식으로 만들어주기 때문에 부모의 prototype에 있던 함수들을 자유롭게 사용가능합니다.
이것이 내장함수들의 비밀이었습니다.
constructor 와 prototype의 차이
자식들이 값을 직접 소유하게 만들고 싶으면 constructor로 상속시키시면 되고
부모만 가지고 있고 그걸 참조해서 쓰게 만들고 싶으면 prototype으로 상속시키면 되겠쥬?
보통은 그래서 상속할 수 있는 함수 같은 것들은 prototype으로 많이 만들어놓습니다.
'Javascript' 카테고리의 다른 글
Beesbeesbees 과제풀이 (2) | 2023.03.16 |
---|---|
'__proto__' (=유전자 검사, 내 뿌리를 찾고 싶다면?) (0) | 2023.03.15 |
OOP 4가지 개념 (0) | 2023.03.15 |
객체지향 프로그래밍: 클래스와 인스턴스 (0) | 2023.03.15 |
배열 반복문 3인방 ( filter(), map(), reduce() ) (0) | 2023.03.14 |