Prototype 을 알기 전에 사전에 알아야 할 것들이 있습니다.
모든 자바스크립트의 함수는 함수가 생성될 때 prototype 이란 속성을 하나씩 가지고 생성됩니다.
각 함수가 소유한 prototype 속성은 해당 함수가 new 키워드가 사용된 생성자 함수로서 실행될 때 특별한 역할을 합니다. 반대로 해당 함수가 생성자 함수로 실행되지 않으면 prototype 속성은 아무런 역할을 하지 않습니다.
첫 번째는, Constructor Function, 생성자 함수입니다.
new 키워드가 사용된 어떤 함수를 실행할 경우, 이 함수를 생성자 함수라고 합니다. 생성자 함수는 함수명을 "명사" 로 짓고, 함수명의 첫 글자를 대문자로 표기합니다.
function Hyesik () {
this.name = "hyesik";
this.age = 23;
}
const sik = new Hyesik();
console.log(sik); // Hyesik {name: "hyesik", age: 23};
생성자 함수는 return 값이 명시되어 있지 않더라도 undefined가 반환되는 것이 아니라 this 가 반환됩니다. 여기서 주의할 점은 return 값에 object 를 반환하면 this 를 반환하지 않습니다.
하지만 생성자 함수는 보통 return 구문이 없습니다.
(보통 일반 함수에 return 값이 명시되어 있지 않으면 undefined 가 반환됩니다.)
const arr = [];
-> const arr = new Array(); // [];
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
const obj = {};
-> const obj = new Object(); // {};
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
const func = function() {};
-> const func = new Function();
흔히 배열이나 객체를 만들 때 -> 위와 같이 생성을 합니다.
하지만 위 예제는 -> 아래 예제와 동일합니다.
모든 자바스크립트 객체는 생성자 함수를 이용하여 만들어진다고 해도 틀린 말이 아닙니다.
new 키워드를 사용했을 때 반환해주는 값은 this 값입니다..
여기서 this는 객체입니다. 위 예제를 봤을 때 배열, 함수는 사실상 new 키워드를 사용해서 만들어집니다. 우리가 알 수 있는 사실은 배열과 함수는 객체입니다.
객체, 배열, 함수는 자바스크립트에 내장된 생성자 함수입니다.
생성자 함수가 반환해주는 빈 객체는 흔히 Instance(인스턴스) 라고 합니다.
function Hyesik (name) {
this.name = name;
}
const sik = new Hyesik("hyesik");
sik은 생성자 함수에서 반환된 객체이기 때문에 Hyesik의 instance 입니다.
자바스크립트의 모든 인스턴스 객체는 해당 객체의 프로토타입에 존재하는 속성 및 메소드에 접근하여 사용할 수 있습니다.
function Hyesik(name) {
this.name = name;
}
Hyesik.prototype.age = 23;
const sik = new Hyesik("hyesik");
console.log(sik.age)// 23;
new Hyesik("hyesik") 생성자 함수가 실행되고 실행되면 this 값을 반환해서 sik 에 담기게 됩니다.
sik 인스턴스에 age 라는 속성이 없는데도 출력이 된 이유:
자신을 반환한 Hyesik 생성자 함수의 prototype 에 age 라는 속성이 있기 때문입니다.
sik 인스턴스는 자신의 속성에 age 라는 속성이 없기 때문에 자신을 반환한 Hyesik 생성자 함수로 가서 탐색합니다. 그리고 Hyesik.prototype 에 해당 age속성이 있기 때문에 가져와 사용합니다.
주의할 점은 무조건 상위 prototype에서 가져오는 것이 아니라 먼저 자기 자신한테 속성이 있는지 탐색 후 없으면 상위 prototype 에 가서 탐색 후 가져옵니다.
자바스크립트의 모든 인스턴스 객체는 자신을 반환한 생성자 함수의 프로토타입을 가져와서 사용할 수 있습니다.
프로토타입 체인이란 쉽게 말해서 본인한테 없으면 상위 프로토타입으로 가서 찾고 거기에도 없으면 또 바로 상위 프로토타입으로 가서 찾는 것이라고 생각할 수 있습니다.
모든 함수는 prototype 이란 속성을 가지고 있습니다.
prototype 안에는 기본적으로 constructor 란 속성이 있습니다.
constructor 생성자 함수는 남편, prototype은 아내, instance는 자녀라고 생각하자
function Hyesik(name) {
this.name= name;
}
Hyesik.prototype.age = 23;
(= 아내)
Object.prototype.drink = "sikhye";
(= Hyesik.prototype.__proto__)
const sik = new Hyesik("hyesik");
(= 자녀) (= 남편)
console.log(sik.drink) // "sikhye";
__proto__ ,던더 프로토는 해당 인스턴스의 바로 상위 prototype 으로 접근 가능한 메소드입니다.
최상위 프로토타입 체인에 있는 것은 Object.prototype 입니다.
그러므로 Object.prototype.__proto__ === null 입니다.