JS 중급 | 상속, prototype

uoah·2023년 2월 2일
0

자바스크립트

목록 보기
29/33
post-thumbnail

🚀 오늘의 학습 목표

  • 상속
  • Prototype
  • instansof

14. 상속 / prototype

14.1 상속

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 에서 프로퍼티를 탐색한다.


14.2 상속 사용

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..'),
  },
};
  
  1. 상위 개념의 car 변수를 만들어 준다.
const car = {
  wheels : 4,
  drive(){
    console.log('drive..');
  },
}
  1. 이전 만들었던 객체에서 wheels 와 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

14.3 상속은 계속 이어질 수 있다.

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 값을 준다.

<프로토타입 체인(Prototype Chain)>


for...in() 반복문을 사용하여 객체 프로퍼티를 순회해 보자.

for(p in x5){
  console.log(p);
}

// 프로퍼티가 모두 나온다.
/*
"color"
"name"
"navigation"
"wheels"
"drive"
*/

🔗 for...in()반복문 복습하러 가기


Object.keys() 나 Object.value() 는 어떻게 나올까?

키 또는 값과 관련된 객체 내장 메서드는 상속된 프로퍼티는 나오지 않는다.

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"
*/

14.4 생성자 함수를 이용한 상속

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!'

🔗 생성자 함수 복습하러 가기


14.5 instansof 연산자

생성자 함수가 새로운 객체를 만들어 낼 때 그 객체는 생성자 함수의 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

14.6 closuer 이용

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'

🔗 closure 복습하러 가기


0개의 댓글

관련 채용 정보