minzzl

[Javascript] Class vs Object 본문

프로젝트/자바스크립트

[Javascript] Class vs Object

minzzl 2022. 10. 8. 20:33
728x90
반응형

 

Class와 Objec는 연관있는 데이터들을 한군데 모아 놓은 컨테이너 같은 역할을 합니다.

 

// 클래스 선언
class person {
    name; // 프로퍼티(혹은 속성(filed))
    age; // 프로퍼티(혹은 속성(filed))
    speak(); // 메소드
}

// 객체 생성
// 객체를 생성할 때는 클래스앞에 new라는 키워드를 사용한다.
const mike = new Person('mike', 20);
console.log(mike.name);
console.log(mike.age);

 

우선 class와 object 에 대해서 알아봅시다.

 

Class

  • template, 즉 틀 같은 역할을 한다.
  • 한번만 선언한다.
  • 클래스 안에는 데이터가 없다.
  • 메모리에 올라가지 않는다.

 

Object

  • instanc of a class, 클래스의 인스턴스이다.
  • 1개의 클래스로 여러개의 객체를 만들수 있다.
  • 객체 안에는 데이터가 있다.
  • 메모리에 올라간다.
클래스는 달고나 틀
객체는 클래스(달고나 틀)로 찍어낸 달고나
즉 클래스를 정의해서 다양한 객체들을 만든다.

 

 

Constructor

constructor는 객체를 생성할 때 인자를 프로퍼티에 전달하여 생성합니다. 즉 객체를 만들 때 필요한 데이터를 전달하여 객체를 생성해줍니다.

 

class Person {
  // constructor(생성자)
  constructor(name, age) { // 인자를 받아 할당한다.
    // fields
    this.name = name; // this는 객체(변수명)를 지칭한다.
    this.age = age; // this.name, this.age는 클래스의 필드(프로퍼티)이다.
  }

  // methods
  speak() {
    console.log(`${this.name}: hello!`);
  }
}

물론 인자를 전달할 필요가 없이 프로퍼티를 선언하고 할당 할 수 있습니다.

class Person {
    name = 'mike';
	age = 21;
}

 

Property

  • Data property : 값을 저장하기 위한 프로퍼티. 일반적으로 사용하는 프로퍼티는 데이터 프로퍼티입니다. 
  • Accessor property : 프로퍼티를 읽거나 쓸 때 호출하는 함수를 값 대신에 지정할 수 있는 프로퍼티. Accessor property의 본질은 함수인데, 이 함수는 값을 획득(get)하고 설정(set)하는 역할을 담당합니다. 그런데 외부 코드에서는 함수가 아닌 일반적인 프로퍼티처럼 보입니다.

접근자란 객체 지향 프로그래밍에서 객체가 가진 프로퍼티 값을 객체 바깥에서 읽거나 쓸 수 있도록 제공하는 메서드를 의미합니다. 객체의 프로퍼티를 객체 바깥에서 직접 조작하는 행휘는 데이터의 유지 보수성을 해치는 주요한 원인이므로 접근자를 통해 이루어져야합니다.

 

Getter 와 Setter

getter는 객체의 특정 프러퍼티 값을 가져오도록 하기 위한 , setter는 객체의  특정 프러퍼티 값을 설정하기 위한 메서드 입니다.

 

getter

let user = {
  name: "John",
  surname: "Smith",

  get fullName() {
    return `${this.name} ${this.surname}`;
  }
};

alert(user.fullName); // John Smith

 

 

바깥 코드에서는 접근자 프로퍼티를 일반 프로퍼티처럼 사용할 수 있습니다. 접근자 프로퍼티를 사용하면 함수처럼 호출하지 않고 일반 프로퍼티에서 값에 접근하는 것처럼 평범하게 . 을 사용해 프로퍼티 값을 얻을 수 있습니다. 

setter

let user = {
  name: "John",
  surname: "Smith",

  get fullName() {
    return `${this.name} ${this.surname}`;
  }
  
  set fullName(value) {
    [this.name, this.surname] = value.split(" ");
  }
};

// 주어진 값을 사용해 set fullName이 실행됩니다.
user.fullName = "Alice Special"

alert(user.fullName); // Alice Special
alert(user.name); // Alice
alert(user.surname); // Special

이렇게 getter와 setter 메서드를 구현하면 fullName이라는 가상의 프로퍼티가 생깁니다. 가상의 프로퍼티는 읽고 쓸 수 는 있지만 실제로 존재하지는 않습니다.

 

 

Public & Private

 

Public Property

클래스에 일반적인 방식으로 프러퍼티를 선언하고 할당하면 Public Property입니다. Public property는 외부에서 프로퍼티에 접근하여 값을 사용하거나 수정이 가능합니다.

 

Private Property

클래스에서 프로퍼티 앞에 # 키워드를 작성하여 선언하면 Private Property가 됩니다. 프라이빗 프로퍼티는 오직 클래스 안에서만 사용, 변경이 가능합니다. 외부에서는 접근이 불가능합니다.

 

class Experiment {
  publicField = 2; // 퍼블릭 프로퍼티, 위부에서 프로퍼티에 접근하여 값을 사용하거나 수정이가능하다.
  #privateField = 0; // 프라이빗 프로퍼티, 오직 클래스안에서만 사용, 변경이 가능하다. 
}
const experiment = new Experiment();
console.log(experiment.publicField);
console.log(experiment.privateField); // undefined

 

 

Static property and Static method

 

Static

클래스의 정적 메서드를 정의

 

정적 메서드는 클래스의 종속적인 메서드를 의미합니다. 즉 클래스와 해당 메서드는 연결되어있지만, 해당 클래스의 특정 인스턴스와는 연결이되어있지 않기 때문에 정적 메서드는 특정객체에 저장된 데이터에 접근할 수 없습니다.

 

정적 메소드는 생성자 함수로 인스턴스를 생성하지 않아도 호출할 수 있는 메서드를 말합니다. 그렇기 때문에 정적 메소드는 클래스로 호출이 가능합니다. 또한 정적 메서드는 클래스로 호출되기 때문에, 인스턴스로 호출되는 클래스와는 내부의 this가 다를 수 밖에 없습니다. 따라서 this를 사용해야하는 경우엔 프로토타입 메소드로 정의해야합니다. 반면에 this로 인스턴스의 프로퍼티를 참조해야할 필요가 없고 클래스 호출만으로도 충분하다면 정적 메서드로 만들면 됩니다.

 

클래스를 선언할 때 프로퍼티와 메소드 앞에 static 키워드를 작성하여 선언하면 클래스로만 접근하여 사용할 수 있습니다. 이는 어떤 객체든 상관없이 공통된 모든 객체에 같은 프로퍼티, 메서드가 필요할 때 사용하면 메모리를 줄일 수 있습니다.

 

class Article {
  static publisher = 'alice'; // Static property
  constructor(articleNumber) {
    this.articleNumber = articleNumber; // 일반적인 property
  }

  static printPublisher() { // Static methods
    console.log(Article.publisher);
  }
}

const article1 = new Article(1);
// bad
console.log(article1.publisher); // undefined
article1.printPublisher(); // 에러

// good
console.log(Article.publisher);
Article.printPublisher();

 

Class 상속

 

상속

클래스에서 다른 클래스로 상속하면 클래스의 기능을 확장 해 나갈 수 있다.

class 자식클래스 extends 부모클래스 {}

 

Shape 라는 부모 class를 선언해봅시다.

class Shape {
  constructor(width, height, color) {
    this.width = width;
    this.height = height;
    this.color = color;
  }

  draw() {
    console.log(`drawing ${this.color} color of`);
  }

  getArea() {
    return this.width * this.height;
  }
}

 

Rectangle, Triangle class 는 Shape class 를 상속받습니다.

상속 받을 때 프로퍼티와 메소드는 오버라이딩이 가능하며 부모클래스 접근시에는 super 키워드를 통해 접근가능합니다.

class Rectangle extends Shape {} // Shape의 모든 정의들이 Rectangle클래스에 포함이 된다.
class Triangle extends Shape {
  getArea() {
    // 메서드 오버라이딩 - Shape에 정의되었던 메서드를 덮어씌워서 재정의한다.. 프로퍼티도 오버라이딩이 가능하다.
    return (this.width * this.height) / 2;
  }

  draw() {
    super.draw(); // super는 부모클래스, 즉 Shape클래스를 지칭한다.
    console.log(`🔺`);
  }
}

const rectangle = new Rectangle(20, 20, 'red');
rectangle.draw();
console.log(rectangle.getArea());

const triangle = new Triangle(20, 20, 'blue');
triangle.draw();
console.log(triangle.getArea());

 

728x90
반응형

'프로젝트 > 자바스크립트' 카테고리의 다른 글

[Javascript] JSON  (0) 2022.10.09
[Javascript] Array  (0) 2022.10.09
[Javascript] operator와 loop,if  (0) 2022.10.08
[Javascript] 호이스팅  (0) 2022.10.08