이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

게시글

강좌17 - JavaScript - 2년 전 등록 / 일 년 전 수정

객체 상속

조회수:
0
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

이번 시간에는 지난 시간에 생성자 함수를 만든 것에 이어 상속에 대해 설명하겠습니다. 

상속

상속은 부모 생성자의 기능을 물려받으면서 새로운 기능도 추가하는 것을 의미합니다. 외국에서는 상속 대신 확장(extend)이라는 말을 쓴다고 했죠? 사실 확장이 더 어울리기도 하고요. 어쨌든, 다음의 코드를 보시죠.

function Vehicle(name, speed) {
  this.name = name;
  this.speed = speed;
}
Vehicle.prototype.drive = function () {
  console.log(this.name + ' runs at ' + this.speed)
};
var tico = new Vehicle('tico', 50);
tico.drive(); // 'tico runs at 50'
function Sedan(name, speed, maxSpeed) {
  Vehicle.apply(this, arguments)
  this.maxSpeed = maxSpeed;
}
Sedan.prototype = Object.create(Vehicle.prototype);
Sedan.prototype.constructor = Sedan;
Sedan.prototype.boost = function () {
  console.log(this.name + ' boosts its speed at ' + this.maxSpeed);
};
var sonata = new Sedan('sonata', 100, 200);
sonata.drive(); // 'sonata runs at 100'
sonata.boost(); // 'sonata boosts its speed at 200'

처음보는 분들은 대혼란에 빠질 만한 코드네요. 사실 위의 코드가 모든 사람들이 쓰는 코드는 아닙니다. 상속하는 수 많은 방법이 있는데 에러가 거의 없는 방법 중 하나입니다. 보시면 Vehicle 생성자와 prototype에 메소드를 넣는 것까지는 아실 겁니다. 지난 시간의 코드를 그대로 썼습니다. tico라는 Vehicle도 만들었고요. 그 후에는 Sedan이라는 Vehicle을 상속하는 생성자를 만들었습니다.

그 다음에 나오는 Vehicle.apply(this, arguments);는 Vehicle의 this들을 그대로 받으란 뜻입니다. apply라는 함수는 이름 그대로 적용하는 메소드입니다. 즉 해석하면 Vehicle 생성자에 this와 arguments를 적용하라는 코드죠? arguments는 매개변수를 의미합니다. Sedan은 매개변수로 name과 speed, maxSpeed가 있죠? 이게 그대로 Vehicle과 연결됩니다. 다만, maxSpeed는 Vehicle이 갖고 있지 않기 때문에 무시되고요. 그 후에 이제 Sedan만 갖고 있는 maxSpeed 속성을 따로 추가한거죠. 이렇게 Vehicle의 속성을 상속(또는 확장)받았고, 이제 메소드를 처리하는 부분입니다.

생성자 아래의 Sedan.prototype = Object.create(Vehicle.prototype);은 Sedan의 prototype과 Vehicle의 prototype을 연결하는 겁니다. 그래야 Vehicle의 메소드였던 drive를 쓸 수 있겠죠? Object.createVehicle.prototype을 상속하는 새로운 객체를 만드는 메소드입니다. 그 상속한 객체를 Sedan.prototype에 대입하니까 Sedan이 Vehicle을 상속하게 되는 거죠.

여기서 Object.create(Vehicle.prototype)new Vehicle()의 차이를 알아두시면 좋습니다. Object.create는 객체를 만들되 생성자는 실행하지 않는 겁니다. 즉 그냥 프로토타입만 넣는거죠.

참고로 Sedan.prototype.constructor = Sedan;은 오류를 수정하는 코드입니다. 전 시간에 생성자.prototype.constructor === 생성자여야한다는 말을 드렸었죠? 생성자의 부모의 자식을 찾아라 하면 당연히 원래 생성자가 나와야겠죠. 하지만, 이 줄을 빼고 제가 한 방법대로 상속을 하면 Sedan.prototype.constructor === Vehicle이 됩니다. 이건 어쩔 수 없는 자바스크립트의 문제입니다. 그래서 이것을 고치기 위해 Sedan.prototype.constructor에 Sedan을 다시 넣어주는 겁니다. 다른 상속 방법이 더 자신에게 맞고 그에 따른 문제점은 적절히 처리할 수 있다면 그 방법을 쓰시면 됩니다.

그 다음에 Sedan.prototype.boost 로 boost라는 메소드를 Sedan에 만들었습니다. 이제 Sedan은 Vehicle에게 상속받은 drive와 Vehicle 생성자를 확장한 자신의 boost 메소드를 쓸 수 있습니다!

내친김에 Truck 생성자도 만들어보죠. boost 대신에 load라는 짐을 싣는 메소드를 만들어봅시다.

function Truck(name, speed, capacity) {
 Vehicle.apply(this, arguments);
 this.capacity = capacity;
}
Truck.prototype = Object.create(Vehicle.prototype);
Truck.prototype.constructor = Truck;
Truck.prototype.load = function (weight) {
 if (weight > this.capacity) {
   return console.error('아이고 무거워!');
 }
 return console.log('짐을 실었습니다!');
};
var boongboong = new Truck('boongboong', 40, 100);
boongboong.drive(); // 'boongboong runs at 40'
boongboong.load(120); // '아이고 무거워!'

capacity는 적재량입니다. load 메소드를 보면, 적재량보다 무거운 짐을 실으면 무겁다고 메시지가 뜨죠?

다음 시간에는 지금까지 배운 것을 활용해서 게임을 또 만들어봅시다. 사실 게임이야말로 가장 어려운 프로그래밍입니다. 자바스크립트에 대해 더 알아가면서 점점 진화하는 게임을 만들어보죠! 이제는 콘솔은 졸업하고 화면에 직접 표시해봅시다.

투표로 게시글에 관해 피드백을 해주시면 많은 도움이 됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright © 2016- 무단 전재 및 재배포 금지

댓글

9개의 댓글이 있습니다.
3일 전
질문 있습니다. Sedan의 prototype과 Vehicle의 prototype을 연결했으니까 반대로 Sedan의 메소드 boost 도 Vehicle에서 사용 가능한 거죠?
3일 전
아뇨 안 됩니다. 일방적인 상속이에요
3달 전
와 정말 책보다 이설명이 확실히 도움이 되네요.. 짱이다.
책을 보면..
상속에서 Object.create의 설명이 부족했는데..

"Object.create는 객체를 만들되 생성자는 실행하지 않는 겁니다."

이거 하나로.. 이해가 됐습니다.
3달 전
블로그 널리 홍보해주세요 ㅎㅎ
9달 전
'만족해요'정도로만 투표할 수 있다는 게 안타까울 정도로 훌륭한 강의입니다.
9달 전
'감사합니다' 정로도만 답할 수 있다는 게 안타까울 정도의 극찬이십니다 ㅠㅠ
일 년 전
첫번째 예제 6번째 & 11번째 줄 마지막에 ;(세미콜론) 빠진거 같아요.
일 년 전
세미콜론은 옵션입니다~
일 년 전
Object.create(something.prototype) 에서 막혀서 unikys님 강좌랑 같이 봤어요. 설명도 명쾌하고 잘보고 갑니다.
일 년 전
많은 도움이 됩니다. 감사합니다. 저보다 나이도 어리신데 저보다 잘하시는걸보면 정말 열심히해야겠습니다.
일 년 전
예제도 재미있고 설명도 잘되있어서 이해가 잘되네요 오늘도 잘보고 갑니다.
일 년 전
참 재밌는 예제이군요!!
일 년 전
재밌으셨다니 다행이네요 ㅎㅎ
일 년 전
오타발견입니다.
function Truck(name, speed, capacity) {
Vehicle.apply(this, argument)
this.capacity = capacity;
}
------------------위의 부분에서
Vehicle.apply(this, argument) => Vehicle.apply(this, arguments) 로
argument => arguments 로 s 빠져서 오류가 나네용
일 년 전
감사합니다~