상속 개념

SPANKEEE·2022년 9월 14일
0

객체 지향 프로그래밍

객체 지향 프로그래밍은 크게 두가지 요소로 나눠져 있다.

  1. 객체를 만들어내는 공장, 설계도라고 할수 있는 class
  2. class를 통해 만들어진 구체적인 객체

이번 글에서는 주류 객체 지향 언어에서의 상속이 아닌

자바스크립트에서의 상속을 설명할 것이다.

자바스크립트에서의 상속

자바스크립트에도 class라는 키워드는 있지만 장식에 불과하고 내부 동작 방식이 바뀐것도 아니다.

자바스크립트는 더욱 자유롭고 복잡하게 상속을 구현하게 되있다.

class가 상속을 받는 전통적인 방법과 달리 자바스크립트에서는

객체가 직접 다른 객체를 상속받을 수 있고, 얼마든지 상속 관계를 바꿀 수 있다.

만약 super object로부터 상속을 받고 있는 sub object가 다른 객체로부터 상속을 받고 싶다면 링크만 바꿔주면 된다.

이러한 링크를 prototype link라고 한다.

그리고 prototype link를 가리키는 객체를 prototype object라고도 한다.

proto

이번에 설명할 내용은 자바스크립트 class를 사용하지 않고 __proto__를 사용해 상속하는 방법이다.

아래 코드와 같이 간단한 객체를 만들어 상속해보자.

// 부모
var superObj = {superVal : 'super'};
// 자식
var subObj = {subVal : 'sub'};
// 객체 상속
subObj.__proto__ = superObj;
// 출력 테스트
console.log('subObj.subVal => ', subObj.subVal);
console.log('subObj.superVal => ', subObj.superVal);

결과
subObj.subVal => sub
subObj.superVal => super

객체의 속성을 바꾸면 어떻게 될까?

subObj.superVal = 'sub';
console.log('supeObj.subVal => ', superObj.superVal);

결과
supeObj.subVal => super

객체의 속성을 바꿔도 __proto__의 속성은 바뀌지 않는다.

그렇기 때문에 subObject.superVal 의 값을 바꿔도 superObj.superVal의 값은 유지된다.

Object_create

__proto__의 대체재인 Object_create()와 개발자 도구를 이용해 객체를 디버깅 해보자.
Object.create
Object.create를 사용해 객체를 상속하는 새로운 객체를 만들 수 있다.

Object.create의 인자로 부모로 지정할 객체를 넣어 준다.

var superObj = {superVal : 'super'}
var subObj = Object.create(superObj);
subObj.subVal = 'sub';
// 출력
console.log('subObj.subVal => ', subObj.subVal);
console.log('subObj.superVal => ', subObj.superVal);
// 속성 수정
subObj.superVal = 'sub';
console.log('superObj.superVal => ', superObj.superVal);

결과
subObj.subVal => sub
subObj.superVal => super
superObj.superVal => super

개발자도구를 사용하여 이전에 작성한 코드를 입력해 본다.

subObj를 보면 subVal : 'sub', superVal : 'sub'
superObj는 superVal : 'super' 인 것을 확인할 수 있다.

그리고 subObj의 __proto__를 확인하면 superObj를 가리키고 있는것을 확인할 수 있다.

subObj.__proto__가 superObj와 같은지 비교를 해보자.

참으로 나오는 것을 확인할 수 있다.

객체상속의 사용

__proto__와 Object.create()를 사용해 객체를 상속 받는 객체를 만들어보자.

kim = {
	name : 'kim',
  	first : 10, second : 20,
  	sum : function(){return this.first + this.second}
}
lee = {
	name : 'lee',
  	first : 10, second : 10,
  	avg : function(){
    	return (this.first + this.second) / 2;
    }
}
// proto
lee.__proto__ = kim;
// 출력
console.log('kim.sum() : ', kim.sum());
console.log('lee.sum() : ', lee.sum());
console.log('lee.avg() : ', lee.avg());

결과
kim.sum() : 30
lee.sum() : 20
lee.avg() : 10

lee.sum을하면 lee라는 객체에 sum이라는 메소드가 있는지 Lookup을 한다.

lee에는 해당 기능이 없으므로 자바스크립트는 객체에 proto 프로퍼티로써 sum이 있는지 확인해 보고 그 메소드를 사용한다.


위 같은 내용을 object.create()를 사용해서 만들어보자.

kim = {
	name : 'kim',
  	first : 10, second : 20,
  	sum : function(){return this.first + this.second}
}
// Object.create()
var lee = Object.create(kim);
lee.name  = 'lee';
lee.first = 10;
lee.second = 10;
lee.avg = function(){
	return (this.first + this.second) / 2;
}
// 출력
console.log('kim.sum() : ', kim.sum());
console.log('lee.sum() : ', lee.sum());
console.log('lee.avg() : ', lee.avg());

결과
kim.sum() : 30
lee.sum() : 20
lee.avg() : 10

아까와 똑같이 만들었으며 다른점은 Object.create라는 표준화된 권장적인 방법을 통해 상속을 받은 것이다.

하지만 위 방식이 지원되지 않는 브라우저도 존재한다(예 IE)

Polyfill : 기본적으로 지원하지 않는 이전 브라우저에서 최신 기능을 제공하는데 필요하는 코드
위 링크를 확인해 보자.

profile
해야되요

0개의 댓글