Javascript prototype

uoM·2021년 2월 26일
1

객체 형태의 데이터 집합으로, 원형(prototype)객체를 위임하여 객체지향 프로그래밍을 가능하게 해준다.
간단하게 객체가 가진 속성의 모임이 프로토타입이다.

자바스크립트는 초기에 Class를 지원하지 않았고 객체지향 프로그래밍을 구현하기 위해 prototype을 이용하 였다.

prototype이라는 프로퍼티는 function에서만 존재한다.

프로토 타입은 어떤 식으로 이루어져있는지 먼저 살펴보면

function Person (name) {
    this.name = name
}

console.dir(Person)

/* 
f Person(name)
...
prototype:
	constructor: f Person (name)
	__proto__ : Object
__proto__ : f ()
...
*/

다음과 같은 결과를 확인 할 수 있다.

Person 이라는 함수는 Function 의 Prototype을 상속 받았으며, 프로토 타입을 상속해 줄수 있다

let dave = new Person('dave')

console.dir(dave)
/*
Person
	name: "dave",
	__proto__: 
		constructor: ƒ Person(name)
		__proto__:object
		....
*/

실제로 new 키워드를 통해 상속받은 dave라고 하는 객체는 __proto__의 객체가 Person.prototype과 같다

dave.__proto__ === Person.prototype

class를 상속하여 확장하는데 있어서 중요한 역할을 하게 된다.

function Book (name, author) {
	this.name = name;
	this.author = author;
}

Book.prototype.sell = function () { console.log('++$$') }
Book.prototype.fame = function () { console.log('~ing') }
console.dir(Book)
/*
...
..
prototype:
	constructor: f Book()
	fame: f()
	sell: f();
	__proto__: ...
...
*/
const comics = new Book('comics', 'owner');

comics.name // 'comics'
comics.sell // '++$$'
comics.fame // '~ing'

console.dir(comics)
/*
name : 'comics',
author:
...
__proto__: 
	fame: f()
	sell: f()
	constructor: f Book()
	__proto__: ...
*/

prototype에는

constructorBook이라는 함수,

sell 이라는 메서드와

fame이라는 메서드가 존재한다.

상속을 받은 객체는 (comics) 실제로 함수(Book)의 prototype을 상속 받게 된다.

실제로 인스턴스를 생성할 때도 일어나지만 다른 클래스를 만들때도 같은 방식으로 작동하게 된다.

다른 클래스를 생성할 때

// 부모 클래스
function Book (name, author) {
	this.name = name; // name 속성
	this.author = author; // author 속성
}

Book.prototype.sell = function () { console.log('++$$') } // sell 메서드
Book.prototype.fame = function () { console.log('~ing') } // fame 메서드

// 부모를 상속받을 새로운 클래스
function Comics (name, author, genre) {
	Book.call(this, name, author) // 상속받은 속성
	this.genre = genre; // 새로운 속성 추가
}

Comics.prototype = Object.create(Book.prototype) // prototype 상속
Comics.prototype.constructor = Comics // 생성자 함수 설정

Comics.prototype.sell = function () {
	Book.prototype.sell.apply(this) // 상속받은 클래스의 기능 실행
	console.log('+++++++++$$$$'); // 확장 기능 추가
}
Comics.prototype.laugh = function () { console.log('hahaha!!!') }  // 새로운 메서드

코믹스를 객체가 아닌 새로은 클래스를 생성하는 코드를 작성해 보았다.

실제로 constructor를 설정해 주기 위해

comics function을 구현하고 이번엔 genre를 추가 해주었다.
Book클래스를 상속을 위해 Book.call(this,name,author)를 통해 this.genre로 새로운 속성을 추가해 주었다.

프로토타입 상속을 위해

Comics.prototype = Object.create(Book.prototype)

을 추가해서 Comics가 Book의 프로토타입을 상속하도록 구현할 수 있다.

Comics.prototype.constructor = Comics

생성자를 Comics로 설정해

실제로 어떤 클래스로 인스턴스를 생성하는지 어떤 클래스로 부터 상속 받는지 명시해 주게 된다.

실제로 Class 키워드를 사용하면 더 쉽게 구현이 가능하다.

클래스키워드로 구현하기

class Book {
	constructor(name, author) {
		this.name = name;
		this.author = author;
	} 

	sell () {
		console.log(`${this.name}++$$`) // 이번엔 인스턴스의 이름을 출력하게 변경
	}

	fame () {
		console.log('~ing') 
	}
}

// Comics는 Book을 상속받은 클래스 입니다.
class Comics extends Book {
	constructor(name,author,genre) {
		super(name,author) // 기존 생성자 속성을 가지고 옵니다.
		this.genre = genre; // 새로운 속성을 추가 합니다.
	}
	
	sell () {
		super.sell.apply(this) // 상속받은 메서드를 실행합니다.
		console.log('++++++++++$$$$$$$$') // 기능을 추가해 확장 합니다.
	}

	laugh () {
		console.log('hahahahahaha') // 새로운 기능 입니다.
	}
}

자바스크립트는 ES6부터 class 키워드를 통해 클래스 생성을 지원 하였고 이전에는 prototype 기반 프로그래밍을 통해 클래스를 구현하여 객체지향 프로그램밍을 구현했다.

현재는 class를 통해 객체지향 프로그래밍을 하고 있는 추세지만 아직 prototype을 사용 할 수 있으니 알아 두는게 좋다.

reference

https://www.nextree.co.kr/p7323/

0개의 댓글