[JS] class -2

이정우·2023년 11월 12일
0

JS

목록 보기
2/2
post-thumbnail

밸~하 밸로그 여러분 안녕하세요!

오늘은 class 학습의 두번째 시간으로
인스턴스의 속성과 class의 field와 extends(상속)에 대해서 알아보겠습니다.

인스턴스 속성

이전시간에 인스턴스에 대해서 학습을 하였습니다.

잠깐 다시 생각해보면 ,
인스턴스란 class의 constructor에 의해 생산된 객체라고 할 수 있겠는데요.

쉽게 말해
class가 template라고 한다면
이 template를 통해 생성된 값이 인스턴스라고 할 수 있습니다.

그러면 이러한 함수 생산자를 통해서 생성된 인스턴스의 속성은 어떤 특징을 가지고 있을까요??

인스턴스의 속성은
먼저는

  • 반드시 클래스 메서드 내에 정의 되어야한다.

인스턴스에서 속성을 정의하는 것이 아니라
인스턴스 만들어주는 class의 메서드 내부에 속성을 정의해 주어야 한다는 것입니다.

글로만 봐서는 이해가 힘들 수 있으니 예제 코드와 함께 살펴보도록 하겠습니다.

class MyClass {
  myMethod() {
    // 메서드 내에서만 유효한 인스턴스 지역 변수
    let localVar = "I am a local variable";
    console.log(localVar);
  }
}

여기서 인스턴스의 지역변수(여기서는 localVar)는

  • 클래스 메서드 내에서 정의된 변수는 해당 메서드 내에서만 유효하다.
  • 이 변수는 메서드가 호출될 때마다 생성되고, 메서드의 실행이 종료되면 소멸한다.

이러한 특징들을 가지고 있습니다

이러한 특징들 덕분에 인스턴스 각각이 독립적인 상태를 유지하는데 도움을 주기도 합니다.

그 다음으로는

  • 정적(클래스사이드)속성과 프로토타입 데이터 속성은 반드시 클래스 선언부 바깥쪽에서 정의되어야 한다.

이렇게 두가지 속성이 있는데
학습을 하며 이런 의문이 들었습니다.
"왜 정적 속성과 프로토타입 데이터 속성은 반드시 클래스 선언부 바깥쪽에서 정의되어야할까?"

이러한 규칙을 가지게된 이유를 찾아보니
이러한 규칙은 javascript 라는 언어의 작동 방식과 클래스의 인스턴스화와 관련이 있다는 것을 알게되었습니다.

class에 대해서 더 학습하기 전에 잠깐 이 의문점을 해결하고 가겠습니다.

의문점 해결

이러한 정적속성과 프로토타입 데이터 속성이 클래스 선언부 바깥에 정의되어야 하는 이유를 알아보겠습니다.

그 이유로는 javascript의 객체 모델 및 클래스 인스턴스화 방식과 관련이 있다는 것을 알게되었습니다.

그럼 어떻게 관련이 있는지 조금 더 상세히 알아보겠습니다

  1. 클래스 인스턴스화와 메모리 사용
  • 정적 속성은 클래스 자체에 속하므로 모든 인스턴스에서 공유됩니다. 이것은 클래스가 인스턴스화될 때마다 정적 속성이 반복 생성되는것을 방지합니다.

정적 속성에 대해서는 저희가 1번째 글에서 학습을 했었습니다

  • 프로토타입 데이터 속성은 모든 인스턴스에서 공유되므로, 클래스의 모든 인스턴스가 메모리를 효율적으로 사용할 수 있습니다.

프로토타입 데이터 속성의 경우 모든 인스턴스에서 공유가 되기때문에 메모리를 효율적으로 사용할 수 있게됩니다.

  1. 프로토타입 체인

이번엔 javascript의 언어 특징에 있습니다

  • Javascript는 프로토타입 기반 언어이며, 클래스의 인스턴스는 프로토타입 체인을 통해 상위 클래스(부모 클래스)의 속성 및 메서드에 접근합니다.

기본적으로 javascript는 프로토 타입 기반의 언어라는것 또한도 지난시간에 학습을 했었는데요.
그런데 프로토 타입 체인이라는 것은 다소 생소 할 수도 있습니다.
프로토 타입 체인에 대해서 잠깐 알아보고 가면

프로토 타입 체인이란?

프로토 타입 체인은 객체 간의 상속 관계를 나타내는 매커니즘 입니다. 이러한 매커니즘은 javascript의 객체지향 프로그래밍 모델의 핵심 중 하나입니다.

javascript객체는 다른 객체로부터 상속을 받습니다.
이러한 객체는 다른 객체를 참조하는 링크인 프로토타입을 가집니다. 객체에서 어떤 속성이나 메서드를 찾을 때, 해당 객체에 속성이나 메서드가 없다면 자동으로 프로토타입 체인을 따라 상위 객체로 이동하여 찾습니다.

프로토 타입 체인의 작동방식은 추후에 다룰 수 있도록 하겠습니다

다시 돌아와서

  • 프로토타입 데이터 속성은 인스턴스의 프로토타입에 저장되어 해당 체인을 따라 공유되므로, 모든 인스턴스가 프로토타입 체인을 통해 속성에 접근할 수 있습니다.
  1. 명확한 의도 및 유지보수
  • 클래스 선언부 외부에서 속성을 정의함으로써 코드의 가독성과 유지보수성이 향상됩니다. 다른 개발자들이 코드를 이해하고 수정할 때 클래스의 속성이 어디에서 왔는지 명확히 알 수 있습니다.
  1. 명세와 호환성
  • 클래서의 정적 속성과 프로토타입 데잍 속성을 클래스 선언부 외부에서 정의하는 것은 javascript 언어의 명세와 호환성을 유지하기 위한 일반적인 관행입니다. 이러한 방식은 코드가 브라우저 및 javascript엔진에서 일관되게 작동하도록 도와줍니다.

너무 긴것같으니 요약을 해보겠습니다 .

클래스 선언부 외부에서 정의된 정적 속성과 프로토타입 데이터 속성은 인스턴스화 및 메모리 사용의 효율성을 향상시키며, javascript의 객체 모델과 프로토타입 체인과 관련된 개념을 지원하여 코드의 가독성과 유지보수성을 향상시킨다 라고 요약할 수 있겠습니다.

이렇게 인스턴스의 속성에 대해서 알아보았는데요,
그다음에 볼것은 class의 Field선언에 대해서 알아보겠습니다

Field선언

먼저 field선언에 대해서 알아보기전에 현재
javascript의 필드는 지원하는 브라우저가 제한적입니다

Warning: public과 private 필드 선언은 JavaScript 표준화 위원회에 실험적 기능 (stage 3) TC39 로 제안되어있습니다. 현재 이를 지원하는 브라우져는 제한적인 상태입니다만, Babel 과 같은 build 시스템을 사용한다면 이 기능을 사용해볼 수 있습니다.

-출처 MDN공식 문서

하지만 위의 설명과 같이 Babel과 같은 build시스템을 사용한다면 이러한 기능을 사용할 수 있기때문에 학습을 이어서 진행해 보겠습니다.

Pubilc 필드 선언

public 인스턴스 필드는 클래스에 의해 생성된 모든 인스턴스에 존재합니다.
public필드를 선언하면 해당 필드가 항상 존재하고 클래스 정의가 더욱 자체적으로 문서화되도록 할 수있습니다.

public인스턴스 필드는 기본 클래스에서 생성 시 또는 서브 클래스에서 super()가 반환된 직후에 인스턴스에 추가됩니다. 초기화 프로그램이 없는 필드는 undefined로 초기화 됩니다.

한번 예제 코드를 봐보겠습니다

class Rectangle {
  height = 0;
  width;
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

이런 식으로 필드를 먼저 선언함으로 클래스 정의는
self-documenting(자체 문서화)에 가까워졌고 필드는 언제나 존재하는 상태가 됩니다.

위의 예제와 같이 필드 선언은 기본 값과 같이 선언될 수도 있습니다.

그럼 이번엔 private 필드 선언에 대해서 알아보겠습니다.

Private field 선언

private 필드를 사용하면 어떻게 될까요??

앞서 public에서 사용한 예제를 Private field로 작성해 보겠습니다

class Rectangle {
  #height = 0;
  #width;
  constructor(height, width) {
    this.#height = height;
    this.#width = width;
  }
}

이렇게 앞에 #이 붙어있는데요
클래스의 바깥에서 #이 처리된 Private필드를 접근하려고 하면 에러가 발생합니다.

private필드는 클래스 내부에서만 읽고 쓰기가 가능합니다.
클래스 외부에서 보이지 않도록 정의하였기 때문에 클래스가 업데이트가 되어 내부 구현이 바뀌더라도 클래스를 사용하는 사용자 입장에서는 이에 아무런 영향을 받지 않도록 할 수 있습니다.

private field를 사용하실때 주의할 점은
private field는 사용전에 선언이 되어야합니다.
일반적인 프로퍼티와는 다르게 private필드는 값을 할당하면서 만들어 질 수 없습니다.

그렇기에 생성된 인스턴스에서는 호출을 할 수 없고 클래스 내부에서만 호출하여 사용할 수 있습니다 .

이렇게 class의 field에 대해서 알아봤는데요
마지막으로 extends를 통한 클래스 상속에 대해서 알아보겠습니다.

extends를 통한 클래스 상속

extends는 대표적인 상속에 대한 표현입니다.
c++이나 java와 같은 경우에도 클래스를 extends받는 경우를 자주 볼 수 있는데요 javascript에서도 그와 비슷하게 class를 extends하여 부모 클래스의 속성을 사용할 수 있습니다.

한번 예제를 보겠습니다

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name); // super class 생성자를 호출하여 name 매개변수 전달
  }

  speak() {
    console.log(`${this.name} barks.`);
  }
}

let d = new Dog("Mitzie");
d.speak(); // Mitzie barks.

-출처 MDN

상속을 받은 class를 subclass라고 하는데,
이 subclass에 constructor가 있다면, this를 사용하기 전에 먼저 super()를 호출해야합니다 .

위의 예저와 같이 super를 통해서 매개변수를 전달 할 수 있게 됩니다.

만약 이렇게 부모 자식간에 같은 메서드가 있다면 자식의 메서드를 우선시하여 호출하기도 합니다.

마무리

이렇게 오늘은 인스턴스의 속성에 대해서 알아보며 중간에 프로토타입 체인에 대해서도 알아보았고 class의 field와 extends상속에 대해서도 알아보았습니다.

다음주는 class-3으로
species와 오늘 예제에서 사용하 super그리고 mix-ins에 대해서 알아보겠습니다

profile
주니어 프론트엔드 개발자

0개의 댓글