객체의 프로퍼티를 사용할 때, 처음에는 객체 내에서 프로퍼티를 탐색을하여 찾고, 없는 경우에는 프로토타입에서 프로퍼티를 찾는다.
const user = {
name: '엥엥츈',
};
user.name; // '엥엥츈'
user.hasOwnProperty('name') // true
name이라는 프로퍼티는 존재한다. 그래서 '엥엥츈'이라는 결과가 나오는 것이다.
hasOwnProperty 함수는 객체 안에 프로퍼티가 있는지 검사해서 boolean값으로 알려준다.
그런데 생각해보니까 우리는 name객체안에 hasOwnProperty 프로퍼티를 만든적이 없다. 대체 어디서 온 녀석인걸까?
바로 Prototype( __proto__
)이라는 객체 안에 존재한다! 객체 안에 존재하지 않는 프로퍼티는 이곳에서 찾는것이다!
user.hasOwnProperty = function(){
console.log('와우!!')
}
// user.hasOwnProperty() // '와우!!'
방금 만든 메소드로 작동한다. 객체에 해당하는 프로퍼티가 존재한다면, 거기서 찾고 탐색을 멈추기 때문이다. 객체에 없을 경우에만 프로토타입에서 탐색을 한다.
const Joonyoung {
age: 26,
glasses: 1,
say(){
console.log('안녕');
},
}
const Dopal {
age: 3,
say(){
console.log('안녕');
},
}
glasses를 제외하고 나머지 프로퍼티들은 동일한 객체가 두개가있다. 그럼 저렇게 사람이 늘어나면 새로운 변수를 선언해야하는데, 공통된 부분을 어떻게 처리해야할까?
Protoype을 이용하여 해결할 수 있다.
// 상위객체
const user {
say(){
console.log('안녕');
},
}
const Joonyoung {
age: 26,
glasses: 1,
}
const Dopal {
age: 3,
}
// 프로토콜을 이용해 공통된 프로퍼티 처리
Joonyoung.__proto__ = user;
Dopal.__proto__ = user;
위의 코드를 보면 user라는 상위개념의 객체를 만들어주고, 공통된 프로퍼티들을 만들어 주고, 맨 아래와 같이 작성을 해주면 user는 왼쪽의 Joonyoung, Dopal을 위해 프로토타입이 되는 것이다.
다르게 말하면 Joonyoung과 Dopal은 user의 상속을 받는 것이다.
Dopal.say(); // '안녕'
프로토타입에 say() 메소드를 상속받아 존재하기 때문에, 객체내의 프로퍼티를 탐색 후, 프로토타입에서 메소드를 찾아 say() 메소드가 동작하는 것이다.
const Engchoon {
ring: 1,
};
Engchoon.__proto__= Dopal;
Engchoon.age; // 3
user의 상속을 받은 Dopal을 상속한 Engchoon이다.
그림으로 나타내면 아래와 같다. 👇
이런것을 프로토타입 체인(Prototype Chain)이라고 한다.
이번에는 생성자 함수를 이용해보려고 한다. 생성자 함수를 이용하면 비슷한 객체들을 간단하게 만들 수가 있다.
const user = function(age){
this.age = age;
};
user.prototype.glasess = 1;
user.prototype.say(){
console.log('하이~ 에이치 아이')
}
const Joonyoung = new user(26)
// Joonyoung.__proto__ = user;
위의 코드와 같이 생성자 함수에 .prototype은 객체의 __proto__
를 glasess와 say()와 같이 설정한다는 의미이다.
이렇게 프로토타입을 이용하면 중복코드를 줄일 수 있다. 한번만 작업을 해준다면, 생성자로 만들어진 모든 객체내에 작업을 해 줄 필요가 없는 것이다.
.__proto__
를 생성할 때마다 사용을 한다면, 생성자 함수를 사용할 이유가 없다