const user = {
name : 'mike'
}
undefined
user.name // 'mike'
user.hasOwnProperty('name') // true
user.hasOwnProperty('age') // false
만약, 객체 안에 hasOwnProperty
가 있다면 어떻게 될까?
const user = {
name : 'mike',
hasOwnProperty : function(){
console.log('haha');
},
}
undefined
user.hasOwnProperty() // haha
방금 만든 메서드가 동작한다.
객체에 프로퍼티가 있으면 탐색을 멈추고, 없을 경우에만 prototype
에서 프로퍼티를 탐색한다.
const bmw = {
color: 'red',
wheels: 4,
navigation: 1,
drive(){
console.log('drive..');
},
};
const benz = {
color : 'black',
wheels: 4,
drive(){
console.log('drive..');
},
};
const audi = {
color : 'blue',
wheels: 4,
drive(){
console.log('drive..'),
},
};
const car = {
wheels : 4,
drive(){
console.log('drive..');
},
}
const car = {
wheels : 4,
drive(){
console.log('drive..');
},
}
const bmw = {
color: 'red',
navigation: 1,
};
const benz = {
color : 'black',
};
const audi = {
color : 'blue',
};
// car 에 상속을 받는다.
bmw.__proto__ = car;
benz.__proto__ = car;
audi.__proto__ = car;
console.log(bmw);
prototype
안에 drive 와 wheels 가 들어간 것을 볼 수 있다.
console.log(bmw.color); // 'red'
console.log(bmw.wheels); // 4
x5 객체를 하나 더 추가하여 x5 에 bmw 를 상속하여 보자.
const car = {
wheels : 4,
drive(){
console.log('drive..');
},
}
const bmw = {
color: 'red',
navigation: 1,
};
const x5 = {
color: 'white',
name: 'x5',
};
bmw.__proto__ = car;
x5.__proto__ = bmw;
console.log(x5.name); // 'x5'
console.log(x5.color); // 'white'
console.log(x5.navigation); // 1
x5 객체에 navigation 이 없으나 상속된 bmwprototype
을 탐색하여 navigation 값을 준다.
for(p in x5){
console.log(p);
}
// 프로퍼티가 모두 나온다.
/*
"color"
"name"
"navigation"
"wheels"
"drive"
*/
키 또는 값과 관련된 객체 내장 메서드는 상속된 프로퍼티는 나오지 않는다.
console.log(Object.keys(x5)); // ["color","name"]
console.log(Object.values(x5)); // ["white","x5"]
🔗 Object.keys() / Object.value() 복습하러 가기
for...in 으로 구분하고 싶다면 hasOwnProperty
를 이용하면 된다.
객체가 직접 가지고 있는 프로퍼티만 true
를 반환한다.
for(p in x5){
if(x5.hasOwnProperty(p)){
console.log('o', p);
} else {
console.log('x', p);
}
}
/*
"o" "color"
"o" "name"
"x" "navigation"
"x" "wheels"
"x" "drive"
*/
const Bmw = function (color){
this.color = color;
this.wheels = 4;
this.drive = function() {
console.log('drive..');
};
};
const x5 = new Bmw('red');
const z4 = new Bmw('blue');
여기에서 wheels 와 drive 는 동일하기 때문에 상속을 이용할 수 있다.
const car = {
wheels : 4,
drive(){
console.log('drive..');
},
};
const Bmw = function (color){
this.color = color;
};
const x5 = new Bmw('red');
const z4 = new Bmw('blue');
x5.__proto__ = car;
z4.__proto__ = car;
console.log(x5.wheels); // 4
매번 생성사 함수를 추가할 때 마다 넣어야 하는 번거로움이 있기 때문에 아래와 같이 코드를 짜면 생성자로 만들어진 모든 객체에 적용되기 때문에 중복 코드를 줄일 수 있다.
const Bmw = function (color){
this.color = color;
};
// 생성자 함수가 생성하는 객체에 __proto__ 를 아래와 같이 설정한다는 코드
Bmw.prototype.wheels = 4;
Bmw.prototype.drive = function() {
console.log('drive..');
};
Bmw.prototype.navigation = 1;
Bmw.prototype.stop = function(){
console.log('STOP!');
};
const x5 = new Bmw('red');
const z4 = new Bmw('blue');
console.log(x5.wheels); //4
x5.stop(); // 'STOP!'
생성자 함수가 새로운 객체를 만들어 낼 때 그 객체는 생성자 함수의 instance
라고 한다.
자바스크립트에서는 이를 편리하게 확인할 수 있는 instanceof
연산자가 있다.
isntanceof
연산자를 이용해서 객체와 생성자를 비교할 수 있고 이는 해당객체가 그 생성자로 부터 생성된 것인지를 판단하여 true
혹은false
를 반환한다.
위의 예제를 활용하여 보자.
const Bmw = function (color){
this.color = color;
};
Bmw.prototype.wheels = 4;
Bmw.prototype.drive = function() {
console.log('drive..');
};
Bmw.prototype.navigation = 1;
Bmw.prototype.stop = function(){
console.log('STOP!');
};
const x5 = new Bmw('red');
const z4 = new Bmw('blue');
console.log(z4);
/*
{
"color": "blue"
}
*/
console.log(z4 instanceof Bmw); // true
console.log(z4.constructor === Bmw); // true
z4 는 Bmw 로 생성되었기 때문에 Bmw 의 instance
이다.
이렇게 하면 Bmw 를 이용해서 z 를 만들었는지 알려주며, true
를 반환한다.
생성자로 만들어진 instance
객체에는 constructor
라는 프로퍼티가 존재 이건 생성자 즉 Bmw 를 가르키며 true
가 나온다.
위의 예제 코드를 간결하게 정리해 보자.
단, 아래와 같이 코드를 바꾸면 constructor
가 사라진다. (flase
반환)
const Bmw = function (color){
this.color = color;
};
Bmw.prototype = {
wheels : 4,
drive(){
console.log('drive..');
},
navigation : 1,
stop(){
console.log('STOP!');
},
};
console.log(z4);
/*
{
"color": "blue"
}
*/
console.log(z4 instanceof Bmw); // true
console.log(z4.constructor === Bmw); // flase
이런 현상을 방지하기 위해 하나씩 추가하거나 constructor
를 수동으로 명시해 줘도 된다.
const Bmw = function (color){
this.color = color;
};
Bmw.prototype = {
wheels : 4,
drive(){
console.log('drive..');
},
navigation : 1,
stop(){
console.log('STOP!');
},
};
console.log(z4);
/*
{
"color": "blue"
}
*/
console.log(z4 instanceof Bmw); // true
console.log(z4.constructor === Bmw); // true
const Bmw = function (color){
this.color = color;
};
const x5 = new Bmw('red');
x5.color = 'black';
console.log(x5.color);
이렇게 자동차의 색깔을 아무나 바꾸면 안 되기 때문에 Closure
를 사용하여 초기에 셋팅했던 color 값만 얻을 수 있도록 할 수 있다. (값을 바꿀 수 없음)
const Bmw = function (color){
const c = color;
this.getColor = function() {
console.log(c);
}
};
const x5 = new Bmw('red');
x5.getColor(); // 'red'