본문으로 건너뛰기
김신건의 로그

[Javascript] Class

· 수정 · 📖 약 1분 · 220자/단어 #javascript #class #oop #fundamentals
JS Class, JavaScript class, ES6 class

정의

ES6 classprototype chain 위의 문법 설탕. C++/Java 스타일 OOP 와 닮았지만 내부는 JS Prototype Chain.

class Animal {
    constructor(name) {
        this.name = name;
    }
    speak() { return `${this.name} makes a sound`; }
    static create(name) { return new Animal(name); }
}

const a = new Animal('Cat');
a.speak();             // 'Cat makes a sound'
Animal.create('Dog');  // static

구조

class Foo {
    // 인스턴스 필드
    x = 0;

    // 정적 필드
    static y = 1;

    // private 필드 (ES2022)
    #secret = 42;
    static #STATIC_SECRET = 99;

    constructor(arg) { ... }

    method() { ... }
    static staticMethod() { ... }

    get prop() { return this.x; }
    set prop(v) { this.x = v; }

    static {
        // static initialization block (ES2022)
        Foo.y = compute();
    }
}

상속

class Dog extends Animal {
    constructor(name, breed) {
        super(name);             // 부모 constructor
        this.breed = breed;
    }
    speak() {
        return super.speak() + ' (woof)';
    }
}

super 의 의미

  • super(...) : 부모 constructor 호출
  • super.method() : 부모 메서드 (현재 this 로)

자식 constructor 에서 super() 호출 전에 this 접근 시 ReferenceError.

private (ES2022)

class Counter {
    #count = 0;

    increment() {
        this.#count++;
    }

    get value() {
        return this.#count;
    }
}

const c = new Counter();
c.#count       // ❌ SyntaxError (외부 접근 불가)

# prefix 가 진짜 private. Symbol 흉내가 아닌 언어 차원의 강제.

static 메서드 / 필드

class MathUtils {
    static PI = 3.14159;
    static circle(r) {
        return MathUtils.PI * r * r;
    }
}

MathUtils.circle(5);   // ✓
new MathUtils().circle(5);   // ❌ (인스턴스에는 없음)

getter / setter

class Temperature {
    #celsius = 0;
    get fahrenheit() { return this.#celsius * 9/5 + 32; }
    set fahrenheit(f) { this.#celsius = (f - 32) * 5/9; }
}

const t = new Temperature();
t.fahrenheit = 100;
t.fahrenheit;          // 100

class expression

const MyClass = class {
    method() { ... }
};

const Named = class FooClass {
    // FooClass 는 내부에서만 사용 가능
};

instanceof

const d = new Dog();
d instanceof Dog       // true
d instanceof Animal    // true (chain)
d instanceof Object    // true

class vs function

function constructorclass
호이스팅✓ (var 처럼)✗ (TDZ)
호출new Foo() 또는 Foo()new 필수
strict mode명시자동
super직접 구현 어려움자연스러움
// function 으로 같은 동작
function Animal(name) {
    this.name = name;
}
Animal.prototype.speak = function() { ... };

class 가 깔끔하고 권장.

자주 만나는 패턴

추상 클래스 흉내

class Shape {
    constructor() {
        if (new.target === Shape) {
            throw new Error('Shape is abstract');
        }
    }
    area() { throw new Error('Must implement'); }
}

class Circle extends Shape {
    constructor(r) { super(); this.r = r; }
    area() { return Math.PI * this.r ** 2; }
}

mixin

const Serializable = Base => class extends Base {
    toJSON() { return JSON.stringify(this); }
};

class User extends Serializable(Object) {
    constructor(name) { super(); this.name = name; }
}

함수가 class 를 받아 새 class 반환.

함정

1. 호이스팅 안 됨

new Foo();      // ❌ ReferenceError
class Foo {}

2. this 바인딩

class Foo {
    method() { return this.x; }
}
const f = new Foo();
const m = f.method;
m();    // this 가 undefined (strict 자동)

해법: bind 또는 arrow function 필드.

class Foo {
    method = () => this.x;     // bound to instance
}

3. new 없이 호출 금지

class Foo {}
Foo();    // ❌ TypeError

4. extends null

class Foo extends null { ... }
// Object.prototype 도 상속 안 함, 거의 안 씀

참고

이 글의 용어 (3개)
[Javascript] functionjavascript
정의 은 JavaScript 에서 함수를 만드는 가장 기본적인 키워드. 호이스팅, 동적 바인딩, 객체, 호출 등 과 구분되는 고유한 특성을 가진다. 함수가 값 으로 다뤄지는 의 …
[Javascript] Objectjavascript
정의 JavaScript 의 는 key-value 쌍의 컬렉션. 거의 모든 non-primitive 값이 객체. 함수, 배열, 정규식도 객체. 생성 접근 수정 / 삭제 Objec…
[Javascript] Prototype Chainjavascript
정의 JavaScript 의 모든 객체는 (내부 슬롯) 을 가진다. 속성 lookup 시 자신에게 없으면 prototype chain 을 따라 올라가며 검색. 접근 함수의 pro…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기