우테코 프리코스 1주차를 하면서 클래스를 사용해서 코드를 구현하는데, 애매하게 알고 있는 상태에서 쓴다는 느낌이 들어, 확실하게 알아가고자 한다! 아래 내용들은 모던 js 딥다이브를 보고 정리하였다.
중간 중간 개념들을 추가로 정리해놓고 반복적으로 볼것이다.
💡 자바스크립트는 강력한 객체 지향 프로그래밍 능력을 지니고 있다.
클래스와 생성자 함수의 차이
- 클래스를 new 연산자 없이 호출하면 에러가 발생한다.
- 클래스는 상속을 지원하는 extends 와 super 키워드를 제공한다.
- 클래스는 호이스팅이 발생하지 않는 것처럼 동작한다.
1. 클래스 정의
클래스는 class 키워드를 사용하여 정의한다. 파스칼 케이스를 사용하는 것이 일반적이다.
class Person {}
클래스는 표현식으로도 정의할 수 있다.
const Person = class {}
클래스를 표현식으로 정의할 수 있다는 것은 클래스가 값으로 사용할 수 있는 일급 객체라는 것을 의미한다.
즉, 클랫는 일급 객체로서 다음과 같은 특징을 갖는다.
- 무명의 리터럴로 생성할 수 있다.
- 변수나 자료구조에 저장할 수 있다.
- 함수의 매개변수에 전달할 수 있다.
- 함수의 반환 값으로 사용할 수 있다.
2. 정적 메서드
정적 메서드는 특정 클래스의 인스턴스가 아닌 클래스 ‘전체’에 필요한 기능을 만들 때 사용한다.
class Person {
//생성자
constructor(name){
//인스턴스 생성 및 초기화
this.name = name;
}
static sayHi() {
console.log('Hi');
}
}
3. 클래스의 호이스팅
클래스는 함수로 평가 된다.
- 단, 클래스는 클래스 정의 이전에 참조할 수 없다.
- 클래스 선언문은 호이스팅이 발생한다.(let , const 처럼 호이스팅된다.)
4. 인스턴스 생성
클래스는 생성자 함수이며, new 연산자와 함께 호출되어 인스턴스를 생성한다.
class Person {}
const me = new Person();
이 때 new 연산자와 함께 호출하지 않으면 타입 에러가 발생한다.
5. 메서드
클래스의 몸체에는 메서드만 선언할 수 있다.
- constructor
- 프로토타입메서드
- 정적메서드
를 선언할 수 있다.
6. constructor
constructor는 인스턴스를 생성하고 초기화 하기 위한 특수한 메서드이다. constructor는 이름을 변경할 수 없다.
class Person{
//생성자
constructor(name){
//인스턴스 생성 및 초기화
this.name = name;
}
}
constructor는 메서드로 해석되는 것이 아니라 클래스가 평가되어 생성한 함수 객체 코드의 일부가 된다.
프로퍼티가 추가되어 초기화 된 인스턴스를 생성하려면 constructor 내부에서 this에 인스턴스 프로퍼티를 추가한다.
class Person{
constructor() {
*//고정값으로 인스턴스 초기화*
this.name = 'Lee';
this.address = 'Seoul';
}
}
const me = new Person();
console.log(me);//Person {name:"Lee", address:"Seoul"}
7. 인스턴스를 생성할 때 클래스 외부에서 인스턴스 프로퍼티의 초기 값을 전달하기
- constructor에 매개변수를 선언
- 인스턴스를 생성할 때 초기 값을 전달한다.
이 때 초기 값은 constructor의 매개변수에 전달된다.
class Person {
constructor(name, address) {
//고정값으로 인스턴스 초기화
this.name = name;
this.address = address;
}
}
}
//인수로 초기 값을 전달한다. 초기 값은 constructor에 전달된다.
const me = new Person('Lee', 'Seoul');
8. 프로토타입 메서드
생성자 함수
- 명시적으로 프로토타입에 메서드를 추가 해야함
function Person(name) {
this.name = name;
}
//프로토타입 메서드
Person.prototype.sayHi = function() {
console.log(`Hi! My name is ${this.name}`);
};
const me = new Person('Lee');
me.SayHi();
클래스
- prototype 프로퍼티에 메서드를 추가하지 않아도 기본적으로 프로토타입 메서드가 됨.
class Person {
//생성자
constructor(name){
//인스턴스 생성 및 초기화
this.name = name;
}
//프로토타입 메서드
sayHi(){
console.log(`Hi! My name is ${this.name}`);
}
}
const me = new Person('Lee');
me.SayHi();
8. 객체 지향 프로그래밍에서의 캡슐화란?
- 비슷한, 관련된 역할을 하는 속성과 메소드를 하나의 클래스 안에 담는 것을 의미한다.
- 서로 연관 있는 속성과 기능들을 하나의 캡슐로 만들어 데이터를 외부로 부터 보호하는 것을 말한다.
캡슐화를 하는 이유
- 캡슐화를 하는 이유는 정보 은닉 때문이다.
정보 은닉이란, 객체에 대한 구체적인 정보를 노출시키지 않도록 하기 위한 기법이다.
어떻게 캡슐화를 해야할까?
Java 같은 경우에는 public, default, protected, private 총 4가지 종류의 접근 제어자를 통해 제어가 가능하다.
하지만 js는 따로 접근 제어자가 존재하지 않는다.
따라서 인스턴스 프로퍼티는 인스턴스를 통해 클래스 외부에서 언제나 참조할 수 있다. 즉, 언제나 public하다.
class Person {
constructor(name){
this.name = name;
}
}
const me = new Person('Lee');
console.log(me.name)//인스턴스 프로퍼티에 접근 가능하다.
클래스 필드 정의 제안을 사용하더라도 클래스 필드는 기본적으로 public하기 때문에 외부에 그대로 노출된다.
class Person{
name = 'Lee';
} //클래스 필드 -> public
//인스턴스 생성
const me = new Person();
console.log(m.name);
private한 필드를 만들기 위해서는 private 선두에 #를 붙여준다. 참조할 때도 #를 붙여 준다.
class Person{
//private 필드 정의
#name ='';
constructor(name) {
this.#name = name;
}
}
const me = new Person('Lee');
console.log(me.#name); //외부에서 참조할 수 없다.
정리
언제 쓰는지
- 외부에 노출시키고 싶지 않은 데이터를 다룰 때: 클래스 내부에서만 사용되거나 보호해야하는 데이터를 외부에서 접근하지 못하도록 할 때 사용한다.
- 객체의 무결성을 유지하고 싶을 때: 외부에서 클래스의 특정 속성이나 메서드를 함부로 바꾸지 못하게 해, 예상치 못한 동작이나 버그를 방지한다.
- 캡슐화(Encapsulation): 객체 지향 프로그래밍에서 캡슐화는 내부의 세부 구현을 숨기고, 외부에는 꼭 필요한 인터페이스만 공개하는 원칙이에요. #private을 통해 내부 구현을 감출 수 있다.
9. static 필드 정의 제안
정적 메서드
정적 메서드는 클래스의 인스턴스 없이 호출이 가능하며 클래스가 인스턴스화 되면 호출할 수 없다.
정적 메서드는 종종 어플리케이션의 유틸리티 함수를 만드는데 사용된다.
- 정적 메서드의 호출
동일한 클래스 내의 다른 정적 메서드 내에서 정적 메서드를 호출하는 경우 this 를 사용할 수 있다.
class StaticMethodCall {
static staticMethod() {
return "Static method has been called";
}
static anotherStaticMethod() {
return this.staticMethod() + " from another static method";
}
}
StaticMethodCall.staticMethod();
// 'Static method has been called'
StaticMethodCall.anotherStaticMethod();
10.접근자 프로퍼티
접근자 프로퍼티는 자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수로 구성된 프로퍼티 이다.
class Person {
constructor(firstName, lastName){
this.fistName = firstName;
this.lastName = lastName;
}
}
get fullName(){
return `${this.firstName} ${this.lastName}`
}
set fullName(name){
[this.firstName, this.lastName] = name.split('');
}
const me = new Person('Ungmo', 'Lee');
console.log(`${me.firstName} ${me.lastName}`);
//접근자 프로퍼티를 통한 프로퍼티 값의 저장
//접근자 프로퍼티 fullName에 값을 저장하면 setter 함수가 호출된다.
me.fullname = 'Heegun Lee';
//접근자 프로퍼티를 통한 프로퍼티 값의 참조
//접근자 프로퍼티 fullName에 접근하면 getter함수가 호출된다.
console.log(me.fullName);
'java script' 카테고리의 다른 글
js: 자바스크립트 입력받는 방법 (0) | 2024.08.02 |
---|---|
js : var 와 let의 차이 그리고 const (1) | 2024.01.09 |