자바스크립트는 클래스기반 언어는 아니고 프로토타입 기반 언어이다
하지만 그러한 개념과 상관없이 자바스크립트에서 클래스 방식을 사용할 수 있다.
// 리터럴 방식
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에 등록되어 있는 속성, 메소드이다.
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
를 사용할 수 있다. 이렇게 사용성이 좋은 코드를 작성할 수 있다.
훌륭한 글이네요. 감사합니다.