- ES6 이전에는 클래스 개념이 없어 객체를 만드는 역할을 함수가 전담.
- 특정 객체를 만들기 위한 일종의 템플릿과 같은 개념으로 이해할 수 있으며, 특정한 형태의 객체를 반복적으로 만들기 위해 사용되는 것.
- 객체를 만드는 데 필요한 데이터, 이를 조작하는 코드를 추상화해 객체 생성을 더욱 편리.
/* 클래스 예제 */
class Cat {
// constructor는 생성자. 최초 생성 시 어떤 인수를 받을지 결정, 객체 초기화
constructor(name) {
this.name = name
}
//메서드
meow() {
console.log(`${this.name}이 야옹`)
}
//정적 메서드
static hello() {
console.log("나는 고양이")
}
//setter 생성
set age(value) {
this.catAge = value
}
//getter 생성
get age(value) {
this.catAge
}
}
// Cat 클래스를 활용 객체 생성
const myCat = new Cat("호야")
// 메서드 호출
myCat.meow()
// 정적 메서드는 클래스에서 직접 호출
Cat.hello()
//정적 메서드는 클래스로 만든 객체에서는 호출 불가.
myCat.hello() // Uncaught TypeError: myCat.hello is not a function
//setter 값 할당
myCat.age = 1
//getter 값 가져오기
console.log(myCat.name, myCat.age) // 호야, 1
: 객체를 생성하는데 사용하는 메서드로 단 하나만 존재. 여러개 사용시 에러 발생하나, 별다르게 수행할 작업이 없으면 생략 가능.
/* constructor 예제 */
class Cat {
constructor (name) {
this.name = name
}
// SyntaxError: A class may only have one constructor
constructor (name) {
this.name = name
}
}
// constructor 없이도 가능
class Cat {
}
: 클래스로 인스턴스 생성 시 내부에 정의할 속성값.
/* property 예제 */
class Cat {
constructor (name) {
// 값을 받으면 내부에 프로퍼티로 할당.
this.name = name
}
}
// 프로퍼티 값 전달
const myCat = new Cat("호야")
- 기본적으로 인스턴스 생성 시 constructor 내부에는 빈 객체가 할당. 해당하는 빈 객체에 프로퍼티 키와 값을 넣어서 활용.
- 다른 언어 처럼 접근 제한자가 완벽하게 지원되지는 않지만 #을 붙여서 private을 선언하는 방법이 ES2019에 추가.
- 타입스크립트 사용 시 private, protected, public을 사용할 수 있지만, 자바스크립트에서는 기본적으로 public. 과거에는 _를 붙여 접근하지 말라는 컨벤션은 존재했었지만, 기능적으로는 private와 다름.
: getter란 값을 가져오기 위해 사용되며, get을 앞에 붙여야 하고 뒤이어서 getter의 이름을 선언해야 함.
/* getter 예제 */
class Cat {
constructor (name) {
this.name = name
}
get firstCharacter() {
return this.name[0]
}
}
const myCat = new Cat("호야")
myCat.firstCharacter // 호
: 클래스 필드에 값을 할당할 때 사용, set 뒤에 이름을 선언해야 함.
/* setter 예제 */
class Cat {
constructor (name) {
this.name = name
}
get firstCharacter() {
return this.name[0]
}
set firstCharacter(char) {
return this.name = [char, ...this.name.slice(1)].join("")
}
}
const myCat = new Cat("호야")
myCat.firstCharacter // 호
myCat.firstCharacter = "야" // "야" 를 할당
console.log(myCat.firstCharacter, myCat.name) // 야, 야야
: 클래스 내부에서 선언한 메서드로 실제로 자바스크립트의 prototype에 선언되므로 프로토타입 메서드라고도 불림.
class Cat {
constructor(name) {
this.name = name
}
// 인스턴스 메서드
hello() {
console.log(`안녕! 내 이름은 ${this.name}`)
}
}
const myCat = new Cat('호야')
myCat.hello() // 안녕! 내 이름은 호야
Object.getPrototypeOf(myCat) // {constructor: f, hello: f}
/* prototype 확인방법 첫번째 */
Object.getPrototypeOf(myCat) === Cat.prototype // true
/* prototype 확인방법 두번째 */
myCat.__proto__ = Cat.prototype // true
- 메서드가 prototype에 선언되었기 때문에 새롭게 생성한 객체에서 클래스에서 선언한 hello 라는 인스턴스 메서드에 접근이 가능하다.
- prototype을 확인하는 두번째 방법은 되도록 사용하지 말자. 표준은 아니지만 과거 브라우저가 이를 사용했기 때문에 호환성을 지키기 위해서만 존재하는 기능 (typeof null === 'object' 참고)
- 프로토타입 체이닝: 직접 객체에 선언하지 않았지만 프로토타입에 있는 메서드를 찾아 실행. 모든 객체는 프로토타입을 보유. 특정 속성을 찾을때 자기 자신부터 최상위 객체인 Object까지 훑음. "myCat -> Cat -> hello"의 순서를 거침. 이와 비슷하게 toString이 존재.
- 프로토타입과 프로토타입 체이닝이라는 특성으로 생성한 객체에서도 직접 선언하지 않은 hello() 메서드 호출 가능하며 메서드 내부에서 this도 접근해 사용 가능.
: 클래스의 인스턴스가 아닌 이름으로 호출할 수 있는 메서드.
class Cat {
// 정적 메서드
static hello() {
console.log("안녕!")
}
}
const myCat = new Cat()
myCat.hello() // Uncaught TypeError: myCat.hello is not a function
Cat.hello() // 안녕!
- 정적 메서드 내부의 this는 클래스로 생성된 인스턴스가 아닌 클래스 자신을 가르키기 대문에 다른 메서드에서 일반적으로 사용하는 this가 사용불가.
- this에 접근할 수 없지만 인스턴스를 생성하지 않아도 사용 가능. 따라서 여러 곳에서 재사용이 가능하므로 전역에서 사용하는 유틸 함수를 정적 메서드로 많이 활용함.
: 기존의 클래스에서 확장하는 개념.
class Cat {
constructor(name) {
this.name = name
}
meow() {
console.log(`${this.name} 야옹!`)
}
}
class Animal extends Cat {
constructor(name) {
// Cat의 consturctor 호출
super(name)
}
eat() {
console.log("쿰척")
}
}
const myCat = new Cat("호야")
mtCat.meow() // 호야 야옹!
const animal = new Animal("양이")
animal.meow() // 양이 야옹!
animal.eat() // 쿰척
- Cat을 extends한 Animal이 생성한 객체에서도 따로 정의하지 않는 meow 메소드 사용 가능. 기본 클래스를 기반으로 파생된 클래스 생성 가능.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
Classes - JavaScript | MDN
Classes are a template for creating objects. They encapsulate data with code to work on that data. Classes in JS are built on prototypes but also have some syntax and semantics that are unique to classes.
developer.mozilla.org
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
Object.prototype.__proto__ - JavaScript | MDN
The __proto__ accessor property of Object instances exposes the [[Prototype]] (either an object or null) of this object.
developer.mozilla.org
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
Inheritance and the prototype chain - JavaScript | MDN
In programming, inheritance refers to passing down characteristics from a parent to a child so that a new piece of code can reuse and build upon the features of an existing one. JavaScript implements inheritance by using objects. Each object has an interna
developer.mozilla.org
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends
extends - JavaScript | MDN
The extends keyword is used in class declarations or class expressions to create a class that is a child of another class.
developer.mozilla.org
| 클로저 (0) | 2024.04.22 |
|---|---|
| 클래스와 함수의 관계 (0) | 2024.04.21 |
| 함수를 만들 때 주의사항 - 3. 이름은 간단명료하게 (0) | 2024.04.21 |
| 함수를 만들 때 주의사항 - 2. 가능한 작게 만들자 (0) | 2024.04.21 |
| 함수를 만들 때 주의사항 - 1. 부수효과를 억제하자 (0) | 2024.04.21 |