클래스

ES6는 다른 프로그래밍 언어의 클래스와 달리 JavaScript에 '클래스'라는 개념을 도입했습니다. 여기서 클래스는 이미 데이터, 해당 데이터와 연결된 속성, 데이터 조작과 관련된 메서드를 포함하는 객체를 만들기 위한 템플릿 역할을 하는 특수 함수입니다. 이러한 객체, 속성, 메서드를 통칭하여 클래스의 '구성원'이라고 합니다.

클래스를 정의하려면 class 키워드를 사용합니다. 자바스크립트의 기본 제공 생성자 함수에서 설정한 권장사항과 규칙에 따라 클래스의 식별자는 대문자로 시작합니다.

class MyClass {}

클래스는 프로토타입 및 생성자 함수의 고급 기능을 사용하여 작업하기 위한 보다 액세스 가능한 방법을 제공하기 위한 것입니다.

class MyClass {}

typeof MyClass;
> "function"

클래스는 고급 JavaScript 기능을 더 쉽고 매력적으로 사용할 수 있도록 부분적으로 추가되었으므로 '구문 코드'라고도 합니다. 하지만 클래스는 프로토타입 상속 작업에 유용한 약식을 제공하는 것 외에도 많은 작업을 수행합니다. 이전 버전과의 호환성 문제를 일으키지 않고 자바스크립트의 오랜 디자인 문제를 해결할 수 있는 클래스 문법 생성 기회를 도입합니다. 한 가지 예로, 클래스 본문 내의 모든 코드는 항상 엄격 모드에서 평가됩니다.

클래스의 인스턴스를 만들려면 new 연산자를 사용합니다.

class MyClass {}

const myClassInstance = new MyClass();

myClassInstance;
> Object { }

클래스 본문 내에 정의된 함수는 클래스의 각 인스턴스에 대한 메서드로 노출됩니다.

class MyClass {
    classMethod() {
        console.log( "My class method." );
    }
}

const myClassInstance = new MyClass();

myClassInstance.classMethod();
> "My class method."

클래스 내에 정의된 메서드는 결과 인스턴스의 프로토타입의 메서드가 됩니다. 프로토타입 체인의 특성으로 인해 결과 객체에서 직접 이러한 메서드를 호출할 수 있습니다.

class MyClass {
  classMethod() {
    console.log( "My class method." );
  }
}

const myClassInstance = new MyClass( "A string." );

myClassInstance;
> Object { }
    <prototype>: Object { … }
        classMethod: function classMethod()
        constructor: class MyClass { constructor(myPassedValue) }
        <prototype>: Object { … }

myClassInstance.classMethod();
> "My class method."

클래스 인스턴스를 만들면 새로 생성된 인스턴스에 필요한 '설정'을 실행하고 연결된 속성을 초기화하는 특수 constructor() 메서드가 호출됩니다. 인스턴스가 만들어질 때 클래스에 전달되는 모든 인수는 constructor() 메서드에서 사용할 수 있습니다.

class MyClass {
  constructor( myPassedValue ) {
    console.log( myPassedValue );
  }
}

const myClassInstance = new MyClass( "A string." );
> "A string."

클래스 본문 내에서 this 값은 인스턴스 자체를 참조하며, this에 정의된 모든 속성은 클래스의 각 인스턴스 속성으로 노출됩니다.

class MyClass {
  constructor( myPassedValue ) {
    this.instanceProperty = myPassedValue;
  }
}

const myClassInstance = new MyClass( "A string." );

myClassInstance;
> Object { instanceProperty: "A string." }

다음 속성은 클래스 본문에 있는 모든 메서드에서도 사용할 수 있습니다.

class MyClass {
  constructor( myPassedValue ) {
    this.instanceProp = myPassedValue;
  }
  myMethod() {
    console.log( this.instanceProp );
  }
}

const myClassInstance = new MyClass( "A string." );

myClassInstance.myMethod();
> "A string."

클래스의 constructor()를 정의하지 않으면 JavaScript 엔진은 비어 있는 '기본' constructor를 가정합니다. 각 클래스에는 constructor()라는 특수 메서드가 하나만 있을 수 있습니다.

class MyClass {
  constructor() {}
  constructor() {}
}
> Uncaught SyntaxError: A class may only have one constructor

클래스 선언 또는 클래스 표현식을 사용하여 클래스를 정의할 수 있습니다. 앞의 예는 모두 클래스 선언이었습니다. 클래스 선언은 new를 사용하여 이름을 호출해야 합니다. 클래스 표현식의 이름을 지정하거나 지정하지 않고 '익명' 클래스를 만들 수 있습니다.

let ClassExpression = class {
    constructor() {}
};

ClassExpression;
> class  {}

익명 클래스 표현식을 사용할 수 있는 한 가지는 '즉시' 클래스를 생성하는 함수입니다.

function classMaker() {
  return class {
    constructor() {}
  };
}

let MyVariable = classMaker();

MyVariable;
> class  {}

클래스 선언을 사용하여 클래스를 다시 선언하면 구문 오류가 발생합니다.


class MyClass {
    constructor( ) {
        console.log( "My class." );
    }
};

class MyClass {
    constructor() {
        console.log( "My new class." );
    }
};
> Uncaught SyntaxError: redeclaration of class MyClass

그러나 클래스 표현식을 사용하면 클래스를 재정의할 수 있습니다.

let ClassExpression = class MyClass { };

ClassExpression = class MyOtherClass {
    constructor( myString ) {
        this.myProp = myString;
    }
};

new ClassExpression( "String." );
> MyOtherClass {myProp: 'String.'}

클래스 선언과는 달리 이름이 지정된 클래스 표현식을 이름으로 호출할 수 없습니다. 하지만 클래스 표현식의 할당된 이름은 생성된 인스턴스의 속성으로 사용할 수 있으며, 이는 주로 디버깅을 더 쉽게 하기 위해서입니다.

let MyVariable = class MyClass {};

MyClass;
> Uncaught ReferenceError: MyClass is not defined

MyVariable;
> class MyClass {}

MyVariable.name;
> "MyClass"

클래스 표현식을 사용하여 변수를 초기화하면 해당 변수의 호이스팅 규칙이 예상대로 적용됩니다. 클래스 선언은 letconst와 동일한 '일시적인 사각지대' 규칙을 따르며 현재 범위 상단으로 호이스팅되지 않은 것처럼 동작합니다. 즉, 클래스 선언 전에 클래스를 호출하면 오류가 발생합니다.

{
    let myVar = new MyClass( "Property string." );

    class MyClass {
        myProp;

        constructor( myString ) {
            this.myProp = myString;
        }
    };
};
> Uncaught ReferenceError: Cannot access 'MyClass' before initialization

이해도 테스트

다음 중 클래스를 올바르게 정의하는 것은 무엇인가요?

class MyClass {}
myClass = class {}
new class()

클래스에는 constructor() 메서드가 몇 개나 있을 수 있나요?

One
없음
무제한