5. 1 JavaScript 클래스 prototype

지구·2023년 7월 20일
0

JavaScript

목록 보기
25/30

자바스크립트는 클래스기반 언어는 아니고 프로토타입 기반 언어이다

하지만 그러한 개념과 상관없이 자바스크립트에서 클래스 방식을 사용할 수 있다.

프로토타입의 역할

// 리터럴 방식
const fruits = ['Apple', 'Banana', 'Cherry']
// 원래는 new와 이미 만들어져있는 Array라는 클래스로 만들어야한다.
const fruits = new Array('Apple', 'Banana', 'Cherry')

console.log(fruits)
// 둘다 똑같이 출력됨
['Apple', 'Banana', 'Cherry']

console.log(fruits.length) // 3
console.log(fruits.includes('Banana')) // true

mdn 사이트에 Array에 대한 설명을 보면 위와 같이 메소드들 앞에 prototype이 있는 것을 볼 수 있다.

Array.prototype.jigu = function () {
	console.log(this)
}

fruits.jigu() // ['Apple', 'Banana', 'Cherry']

Array 객체에서 prototype으로 jigu라는 메소드를 등록한 코드이다.

위에서 사용한 length, includes는 자바스크립트에서 이미 prototype에 등록되어 있는 속성, 메소드이다.

💡 결론적으로 prototype은 인스턴스에서 쓸 수 있는 속성이나 메소드를 등록하는 객체이다.
  • 생성자 함수에서 반환된 것을 instance라고 한다. (위 예시에서 fruits)

프로토타입 활용 (재사용성)

const jigu = {
	firstName: 'Jigu',
	lastName: 'Kim',
	getFullName: function() {
		return `${this.firstName} ${this.lastName}`
	}
}

const neo = {
	firstName: 'Neo',
	lastName: 'Anderson'
//	getFullName: function() {
//		return `${this.firstName} ${this.lastName}`
//	}
}

console.log(jigu.getFullName()) // jigu Kim
console.log(neo.getFullName()) // Neo Anderson

neo라는 객체가 getFullName이라는 함수를 사용하고 싶다면 단순히 jigu에 있는 getFullName 코드를 복사하여 사용할 수 있지만 같은 로직을 가지고 있는 코드가 2개나 만들어지게 된다. 따라서, 아래와 같이 작성할 수도 있다.

const jigu = {
	firstName: 'Jigu',
	lastName: 'Kim',
	getFullName: function() {
		return `${this.firstName} ${this.lastName}`
	}
}

const neo = {
	firstName: 'Neo',
	lastName: 'Anderson'
}

console.log(jigu.getFullName()) // jigu Kim
console.log(jigu.getFullName.call(neo)) // Neo Anderson

이런 식으로 작성하면 getFullName이라는 함수는 한번만 만들어서 재활용을하면 원하는 대로 값을 출력할 수 있지만 재활용을 하는 코드가 여러개가 있다면 불편할 것이다. 따라서 prototype을 이용해서 이 문제를 해결할 수 있다.

function User(first, last) {
	this.firstName = first
	this.lastName = last
}

const jigu = new User('jigu', 'Kim')
const neo = new User('Neo', 'Anderson')

console.log(jigu) // {firstName: 'Jigu', lastName: 'Kim'}
console.log(neo) // {firstName: 'Neo', lastName: 'Anderson'}

위 코드를 통해서 객체 리터럴 방식을 이용해서 만드는 객체와 함수 내부에서 this라는 키워드로 각각의 속성을 만들고 new라는 키워드와 함께 호출해서생성하는 객체가 같은 것이라고 해석할 수 있다.

평소에 사용하기는 리터럴 방식으로 객체 데이터를 만드는 것이 편하기 떄문에 많이 사용하지만 getFullName이라는 메소드를 효율적으로 작성하기위해서는 바로 위 코드가 좋다.

function User(first, last) {
	this.firstName = first
	this.lastName = last
}
User.prototypes.getFullName = function() {
	return `${this.firstName} ${this.lastName}`
}

const jigu = new User('jigu', 'Kim')
const neo = new User('Neo', 'Anderson')

console.log(jigu) 
console.log(neo)

그냥 출력했을 때는 getFullName이라는 함수가 보이지 않지만 prototypes이라는 객체를 열어보면 그 안에서 getFullName을 발견할 수 있다.

console.log(jigu.getFullName()) // jigu Kim
console.log(neo.getFullName()) // Neo Anderson

따라서 이제 생성자로 만든 인스턴스에서 언제든지 getFullName를 사용할 수 있다. 이렇게 사용성이 좋은 코드를 작성할 수 있다.

profile
프론트엔트 개발자입니다 🧑‍💻

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

훌륭한 글이네요. 감사합니다.

답글 달기