[JavaScript] 자바스크립트 클래스와 객체
[JavaScript] 자바스크립트 클래스와 객체
본격적인 코드를 작성하면 많이 드는 단어가 '클래스'와 '객체'입니다. 저는 공부를 하면서 많이 헷갈린부분이 '함수가 있는데 굳히 클래스가 필요한건가?' 였습니다. 이번 포스트에서는 객체와 클래스에 대해 알아보도록 하겠습니다.
▶ 객체 (Object)
const name = 'ITnual'
const age = 20
const country = 'korea'
변수를 선언하는건 가장 쉽습니다. 'let'이나 'const'(상수)를 작성하고, 변수 이름을 선언한 다음, 값을 넣어 초기화를 해주면 됩니다. 허나, 관련된 데이터를 하나로 묶어서 표현할 필요가 생깁니다. 예를들면, 어떤 사람의 이름이나, 나이, 국가 같은 데이터를 묶어서 표현하는것이 아닌, 따로따로 기본 데이터 타입으로 저장을 한다면, 데이터를 묶어서 표현을 하기가 힘들껍니다. 이럴때 필요로 하는것이 바로 '객체'입니다.
constructor(name, age, country) { // constructor : 생성자
this.name = name
this.age = age
this.country = country
}
// constructor(매개변수, 매개변수, 매개변수) { // constructor : 생성자
// this.속성명 = 매개변수
// this.속성명 = 매개변수
// this.속성명 = 매개변수
// }
위의 코드는 '생성자'코드입니다. 객체를 생성할때 필요로하는 코드인데 함수(function)을 생성하는 방식과 많이 비슷합니다. 그런데, 이 코드만 사용할 수가 없습니다.
constructor(name, age, country) { // constructor : 생성자
this.name = name
this.age = age
this.country = country
}
let result = constructor('ITnual',20,'korea')
console.log(result)
// 터미널 결과
// constructor(name, age, country) { // constructor : 생성자
// ^
// SyntaxError: Unexpected token '{'
// at wrapSafe (internal/modules/cjs/loader.js:988:16)
// at Module._compile (internal/modules/cjs/loader.js:1036:27)
// at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
// at Module.load (internal/modules/cjs/loader.js:937:32)
// at Function.Module._load (internal/modules/cjs/loader.js:778:12)
// at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
// at internal/main/run_main_module.js:17:47
함수 생성과 비슷하다고 해서, 함수같이 사용을 하게 되면, 다음과 같이 에러가 발생하게 됩니다. 이 '생성자'는 '클래스'와 같이 사용을 해야됩니다.
▶ 클래스 (class)
class 클래스명 {
코드 작성
}
클래스는 객체를 만들고자 할때 설계도처럼 사용하는것입니다. 즉, 클래스는 템플릿, 객체는 템플릿을 구체화한 것이라고도 표현을 합니다. 클래스명은 함수명이나 변수명처럼 표현하고자 하는 데이터를 나타낼수 있는 이름으로 작성을 해주시면 됩니다.
class people {
constructor(name, age, country) { // constructor : 생성자
this.name_property = name
this.age_property = age
this.country_property = country
}
}
객체를 설명할때 '생성자'라는것을 잠시 보여드렸습니다. 이 생성자를 '클래스'안에 넣어서 사용을 하면 됩니다. 이 생성자 코드를 보면, 'this'라는 키워드가 있는데요. 이 'this'키워드의 경우, 클래스를 사용해 만들어질 객체가 자기 자신을 의미하게 됩니다. 그리고 this뒤에 붙어있는 'name_property','age_property','country_property'는 해당 객체의 속성이라 보면 됩니다. 즉 'this.name_property = name'은 매개변수 'name'을 이 객체의 속성인 'name_property'에 넣는다는 뜻이 되겠죠? 이 코드에서는 구분이 잘 되도록 보이기위해 속성명 뒤에 '_property'를 붙였는데요. 'this.name = name'으로 작성을 하는게 코드를 읽는데 더 깔끔하게 볼 수 있습니다. 클래스를 생성하고, 그 안에 생성자를 만드는것까지는 알겠는데, 그렇다면 '객체 생성'은 어떻게 해야되는걸까요?
▶ 객체 생성
class people {
constructor(name, age, country) { // constructor : 생성자
this.name = name
this.age = age
this.country = country
}
}
// 객체 생성, new 키워드를 사용후 클래스명(매개변수) 작성 , let 변수를 사용가능
const result = new people('ITnual',20,'korea')
console.log(result)
// 터미널 출력 결과
// people { name: 'ITnual', age: 20, country: 'korea' }
클래스 코드 밑에 코드를 추가한것을 볼 수 있습니다. 변수를 선언한 다음, 해당 클래스에 매개변수를 넣은건데요. 근데 함수의 경우 'function 함수명 (매개변수)'로 선언을 했지만, 클래스의 경우 'class 클래스명'으로 선언을 하고 소괄호'()'가 보이지 않습니다. 그런데, 코드를 작성한것을 보면, 'new 클래스명 (매개변수)'로 적혀있는 모습을 볼 수 있습니다. 이 매개변수는 객체를 생성할 때 클래스안에 'constrctor(매개변수)'메소드를 자동으로 불러오기 때문에, 해당 메소드안에 객체의 속성안에 매개변수를 넣는겁니다.
// JS 객체
const result = new people('ITnual',20,'korea')
console.log(result.name) // 객체.속성명
# Python 딕셔너리
# result = { name: 'ITnual', age: 20, country: 'korea' }
# result['name]
# 파이썬 출력 결과 : ITnual
// JS 터미널 출력 결과
// ITnual
참고
파이썬을 공부하신 분들이라면, 해당 결과가 '딕셔너리 (Dictionary)' 랑 똑같은 모습을 볼 수 있습니다. '딕셔너리'의 경우 'key,value'로 구성이 되어있는데요. 파이썬의 경우 '딕셔너리명['key명']을 작성하면 'value'를 확인할 수 있는데, JS에서는 '객체명.속성명'을 작성하면, 해당 값을 확인할 수 있습니다. 다르지만 비슷하니 참고하세요!
▶ 메소드 (Method)
class people {
constructor(name, age, country) { // constructor : 생성자
this.name = name
this.age = age
this.country = country
}
// 새로운 메소드 생성
printInfo() {
console.log(`이름 : ${this.name} | 나이 : ${this.age} | 나라 : ${this.country}`)
}
}
// 객체 생성
let result = new people('ITnual',20,'korea')
// 메소드 호출
result.printInfo() // 이전 코드 : console.log(result)
// 터미널 출력 결과
// 이름 : ITnual | 나이 : 20 | 나라 : korea
클래스안에 함수같은 녀석들이 있지만, 이 코드들은 '메소드(Method)'라 부릅니다. 클래스의 특정 코드를 실행할수 있도록 메소드를 정의한다고 하는데요. 코드를 보게되면, 생성자(constructor) 밑에 메소드를 정의 해놓았는데요. 위에서 보여드린 코드랑 다른점은 객체 생성후 'console.log(result)'로 터미널에 결과를 출력한 것이 아닌, 'result.printInfo()'로 메소드를 호출해서, 해당 메소드 안에 코드를 실행하는 방법입니다. 즉 클래스라는 템플릿안에 속성을 지정할 수 있고, 메소드를 작성해 클래스의 메소드를 호출할 수도 있습니다.
▶ 객체 리터럴 (Object Literal)
const 변수명 = {
속성명: 데이터,
메소드명: function () { 메소드 호출시 실행할 코드들 }
}
그런데 객체를 생성할때 꼭 클래스를 만들어야될까요? 아닙니다. '객체 리터럴'을 활용해서 바로 객체를 만들수도 있는데요. 클래스를 선언하지 않더라도 속성과 메소드를 가질수가 있습니다.
const people = {
name : 'ITnual', // name = 'ITnual' 이 아니라는점을 주의하자!
age : 20,
country : 'korea',
printInfo: function () {
console.log(`이름 : ${this.name} | 나이 : ${this.age} | 나라 : ${this.country}`)
}
}
people.printInfo()
// 터미널 결과 출력
// 이름 : ITnual | 나이 : 20 | 나라 : korea
코드 작성 방식은 다르지만, 결과는 같은걸 볼 수 있습니다. 다만, 코드를 보게 되면, '매개변수'가 없고, 속성안에 바로 값을 넣어주기 때문에, '재사용성'이 불가능하다는걸 볼 수 있습니다. 즉, 클래스의 경우 객체를 생성할 때 마다 속성의 값을 다르게해서 생성할 수 있지만, '객체 리터널'의 경우, 속성값이 고정되어있기 때문에, 속성값을 다르게 생성할 수가 없습니다.