[JS] class

_sqrlkoo·2023년 8월 7일
2

JavaScript series

목록 보기
5/5

최근 취업을 하면서 업무에 적응하느라 개인적인 공부시간이 부족했다.
내가 소속된 팀은 바닐라 자바스크립트(순수 자바스크립트)로 프로젝트를 구상할 예정이라고 한다..

취업 전 React만 사용해본 나로써 순수 JS로 서비스를 만들어 낸다는 것은 엄청난 도전이지만 평소에 JS공부를 하고싶다 생각만 하고있었던 찰나에 정말 많은 성장을 할 수 있을 거 같아 한편으론 기뻤다..

그래서 오늘은 class를 공부하려고 한다.

class

es6 이전에는 비슷한 종류의 객체를 만들어내기 위해 생성자를 사용했다고 한다.

function Person ({name, age}) {
  this.name = name ;
  this.age = age;
}
Person.prototype.introduce = function () {
	return `안녕하세요, 제 이름은 ${this.name}입니다.`;
}

const person = new Person({name : "군밤", age : 1});

console.log(person.introduce()); // 안녕하세요, 제 이름은 군밤입니다.
console.log(typeof Person); // function
console.log(typeof Person.prototype.constructor); // function
console.log(typeof Person.prototype.introduce); // function
console.log(person instanceof Person); // true

하지만 es6에서 도입된 클래스는 생성자의 기능을 대체한다. class 표현식을 사용하면, 생성자와 같은 기능을 하느 함수를 훨씬 더 깔끔한 문법으로 정의할 수 있다.

class Person {
	constructor({name, age}) {
      this.name = name;
      this.age = age;
    }
  introduce() {
    return `안녕하세요, 제 이름은 ${this.name}입니다.`;
  }
}

const person = new Person({name : "군밤", age : 1});

console.log(person.introduce()); // 안녕하세요, 제 이름은 군밤입니다.
console.log(typeof Person); // function
console.log(typeof Person.prototype.constructor); // function
console.log(typeof Person.prototype.introduce); // function
console.log(person instanceof Person); // true

그리고 class는 javascript의 다른 곳에서는 사용되지 않은 별도의 문법으로 코드를 작성해야 한다.
함수 혹은 객체의 내부에서 사용하는 문법은 적용되지 않는다.

class Person {
	console.log("hi")
}
// error: Unexpected token
class Person {
	prop1 : 1,
	prop2 : 2
}
// error: Unexpected token

추가로 알아야 될 점

  • 클래스의 메소드 안에서 super 키워드를 사용할 수 있다.
  • 클래스는 클래스 선언문 이전에 참조할 수 없다.
  • 하지만 호이스팅이 발생하지 않는 것은 아니다. 클래스는 let, const 키워드로 선언한 변수처럼 호이스팅 된다. 따라서 클래스 선언문 이전에 일시적 사각지대에 빠지기 때문에 호이스팅이 발생하지 않는 것 처럼 동작한다.

class 선언

constructor는 인스턴스를 생성하고 클래스 필드를 초기화하기 위한 특수한 메서드이다.
constructor는 클래스 안에 한 개만 존재할 수 있다. 2개 이상 있을 경우 Syntax Error가 발생하니까 주의하자.

class Person {
	height = 180; // 인스턴스 변수

	constructor(name, age) {
      // this는 클래스가 생성할 인스턴스를 가리킨다.
      // key쪽의 name은 클래스 필드이다.
      this.name = name;
      this.age = age;
    }
}

let person1 = new Person('john', 23);
console.log(person1.name); // john
console.log(person1.age); // 23
console.log(person1.height); // 180

인스턴스를 생성할 때 new 연산자와 함께 호출한 것이 바로 constructor이며 constructor의 파라미터에 전달한 값은 클래스 필드에 할당한다.

위 코드에서 new 연산자와 함께 호출한 Person은 클래스의 이름이 아니라 constructor이다. 표현식이 아닌 선언식으로 정의한 클래스의 이름은 constructor와 동일하다.

new 연산자를 사용하지 않고 constructor를 호출하면 타입 에러(TypeError)가 발생한다. constructor는 new 연산자 없이 호출할 수 없다.

class Foo {}

const foo = Foo(); // TypeError: Class constructor Foo cannot be invoked without 'new'

인스턴스를 생성할 때 new 연산자와 함께 호출한 거시 바로 constructor이며 constructor의 파라미터에 전달한 값은 클래스 필드에 할당한다.

constructor는 생략할 수 있다. constructor를 생략하면 클래스에 constructor() {}를 포함한 것과 동일하게 동작한다. 즉, 빈 객체를 생성한다. 따라서 인스턴스에 프로퍼티를 추가하려면 인스턴스를 생성한 이후, 프로퍼티를 동적으로 추가해야 한다.

class Foo { }

const foo = new Foo();
console.log(foo); // Foo {}

// 프로퍼티 동적 할당 및 초기화
foo.num = 1;
console.log(foo); // Foo { num: 1 }

super

super 키워드는 부모 클래스를 참조(Reference)할 때 또는 부모 클래스의 constructor를 호출할 때 사용한다.
super 메소드는 자식 class의 constructor 내부에서 부모 클래스의 constructor(super-constructor)를 호출한다. 즉, 부모 클래스의 인스턴스를 생성한다. 자식 클래스의 constructor에서 super()를 호출하지 않으면 this에 대한 참조 에러(ReferenceError)가 발생한다.

2개의 댓글

comment-user-thumbnail
2023년 8월 7일

큰 도움이 되었습니다, 감사합니다.

1개의 답글