자바스크립트의 상속

·2023년 2월 16일
0

개발 지식

목록 보기
30/96
post-thumbnail
post-custom-banner

자바스크립트의 상속

자바스크립트는 다른 프로그래밍 언어의 클래스 기반 상속과는 다른 생성자 함수를 활용한 프로토 타입 기반 상속을 사용한다. 자바스크립트의 모든 객체는 객체가 상속하는 속성과 메서드의 템플릿 역할을 하는 프로토타입 객체를 가지고 있으며, 만약 객체 자체에 해당 속성과 메서드가 존재하지 않는 경우, 프로토타입으로부터 속성이나 메서드를 찾는 과정이 진행된다. (프로토타입 체이닝)

여기에서는 상속과 관련된 이야기를 쓰려고 한다. 프로토 타입에 대한 자세한 내용은 이 곳을 참조하자.
프로토타입이 뭔가요?

Object.create

기존 객체의 속성들을 상속받는 새로운 객체를 생성할 때 사용하는 메서드이다.

Object.create(proto[, propertiesObject])
// proto : 새로만들 객체의 프로토타입이 될 객체
// propertiesObject : 새로 만든 객체에 추가될 속성

new 인스턴스로 받는 것과 굉장히 유사하다. 단 Object.create 로 생성하는 경우 constructor 가 설정되지 않고 객체만 생성한다는 것이다. 다음 예제를 살펴보자.

function Character(name, forceUser) {
	this.name = name;
	this.forceUser = forceUser;
}

function Jedi(name, lightsaberColor) {
	Character.call(this, name, true);
	this.lightsaberColor = lightsaverColor;
}

Jedi.prototype = new Character();
// Jedi.prototype = Object.create(Character.prototype);
Jedi.prototype.constructor = Jedi;

console.log(Jedi.prototype);

// new Character();
// Jedi {
// 	name : undefined,
// 	forceUser: undefined,
// 	constructor : [Function: Jedi]
// }

// Object.create(Character.prototype);
// Jedi {
// 	constructor : [Function: Jedi]
// }

new 인스턴스의 경우, name , forceUser 를 가지고 있으나, Object.create 의 경우는 가지고 있지 않다. new 를 통한 인스턴스의 경우, prototype 에 대한 Character 의 속성값을 그대로 가져오게 된다. 현재 Jedi 의 경우이미 Character.call 을 통해 본인의 name 값을 가지고 있기 때문에, 프로토 타입의 name 은 불필요한 속성이 된다.

이를 Object.create 를 활용한다면, Character.prototype 만 받아오도록 할 수 있다.

이렇게 작성했어도, 아직까지 잘 모르겠는 부분이 많다. 아직까지 이렇게 까지 프로토타입을 써야할 경우가 없어서 그런가 싶다. 일단은 new 인스턴스 보다는 Object.create 를 활용하여 상속하는 것을 추천한다고 하니, 이쪽을 더 공부해보자.

Mixin

믹스인은 객체가 단일 클래스나 프로토타입이 아닌 여러 소스로부터 속성과 메서드를 상속할 수 있도록 하는 설계 패턴이다.

프로토타입 기반 상속을 사용하는 자바스크립트의 경우, 모든 객체에 대한 프로토타입 속성은 하나로 분류되기 때문에 단일 상속만을 지원하고 있다. 이는 재사용을 강조하는 객체 지향 프로그래밍에서 큰 단점으로 여겨진다. 이러한 부분을 자바스크립트에서는 믹스인을 사용하여, 다중 상속과 유사하도록 만드는 것이 가능하다.

const walkMixin = {
  walk() {
    console.log(`${this.name} is walking`);
  }
};

const runMixin = {
  run() {
    console.log(`${this.name} is running`);
  }
};

const swimMixin = {
  swim() {
    console.log(`${this.name} is swimming`);
  }
};

function Athlete(name) {
  // Add any additional properties to the object
  this.name = name;

	// 이렇게 mixin 함수를 따로따로 불러오는 것도 가능
  // walkMixin.walk.call(this);
  // runMixin.run.call(this);
  // swimMixin.swim.call(this);
}

// Object.assign 통해 하나의 새로운 객체로 병합한 후 이를 상속 객체로 지정하는 것이다.
Object.assign(Athlete.prototype, walkMixin, runMixin, swimMixin);

const athlete = new Athlete("John");
athlete.walk(); // output: "John is walking"
athlete.run(); // output: "John is running"
athlete.swim(); // output: "John is swimming"
profile
새로운 것에 관심이 많고, 프로젝트 설계 및 최적화를 좋아합니다.
post-custom-banner

0개의 댓글