본문 바로가기
프로그래밍 언어/Javascript

자바스크립트의 객체지향 : public, private

by whale in milktea 2023. 8. 18.

 

자바스크립트 참고 자료들을 찾다보면, `객체의 상속`을 중심으로 설명하는 글들을 흔히 찾아볼 수 있다. 

__prototype__ 접근자를 통해 찾아볼 수 있는 이 객체들은 객체지향(Object Oriented) 프로그래밍 원칙에 의해 정의되어있다.

당장에 해당 객체들을 사용할 일은 없지만, 참고자료들을 빠르게 이해하기 위해서 OOP 개념들에 해당하는 속성들을 chat gpt + Mdn을 활용하여 연습해보기로 했다.

* OOP 원칙 중 캡슐화

OOP는 상속, 추상화, 다형성의 개념을 활용하여 하나의 객체로부터 수만가지에 이르는 인스턴스를 생성함으로 필요한 곳에 필요한 객체를 확장하여 새롭게 정의할 수 있는 강점을 가진다.

다만 이렇게 확장된 코드들은 외부로부터의 접근에 취약하기에, 외부에 노출시킬 데이터와 그렇지 않은 데이터를 구분하여 관리할 수 있는 방법들이 등장한다.

 

Java 언어의 경우 public, default, private, protected 총 4가지 종류의 접근제어자가 있다.

Javascript의 경우 원래는 접근제어자가 따로 없었지만, ES2019 이후 해쉬 # prefix 를 추가해 private class 필드를 선언할 수 있게 되었다.

1. Public

// 접근제한자 public
// cpu가 속한 원래의 객체
class Computer {
  cpu = "i5"

  constructor (model) {
    this.model = model
  }

  getCpu() {
    return this.cpu // 당연히 자신의 객체 내부에서도 동작!
  }
}


// 원 객체로부터 상속받은 새로운 객체
class Macbook extends Computer {
  // 상속받은 객체 내부에서도 접근 가능!
  checkCpu() {
    console.log(`직접 접근 : ${this.cpu}`) 
    console.log(`메서드를 활용한 간접 접근 : ${this.getCpu()}`)
  }
}

const myComputer = new Computer("lg gram 14 inch")
const myMacbook = new Macbook("macbook pro 13 inch")

// 상속받은 객체에서도 그대로 출력 가능
console.log(myMacbook.cpu) // i5
// 외부에서도 접근 가능
console.log(myComputer.cpu) // i5

 

상속받은 객체 내부와  console.log()에 찍히는 내용을 보면 알 수 있듯, 

public한 객체는, 내부에서의 접근 / 외부에서의 접근 모두 다 자유롭다.

2. Private

// 접근제한자 private 실습
class Car {
  #fuel = 100;

  constructor (model) {
    this.model = model;
  }

  getFuel() {
    return this.#fuel
  }
}

class Suv extends Car {
  drive() {
    // ! console.log(`상속된 모델에서 Private 객체에 접근하려고 한다면? ${this.#fuel}`)
    // ! Property '#fuel' is not accessible outside class 'Car' because it has a private identifier.ts(18013)
  }

  checkFuel() {
    this.getFuel()
  }
} // 상속받은 객체

const myCar = new Car("부가티")
const mySuv = new Suv("랭글러")

console.log(myCar) // Car { model: '부가티' }
// ! console.log(myCar.#fuel) / Property '#fuel' is not accessible outside class 'Car' because it has a private identifier.ts(18013)

console.log(mySuv) // Suv { model: '랭글러' }
console.log(mySuv.getFuel()) // 100
// ! console.log(mySuv.#fuel) / Property '#fuel' is not accessible outside class 'Car' because it has a private identifier.ts(18013)

 

반대로 객체 내부에 private로 보호되는 객체는 해당 클래스 내부에서만 접근이 가능하고, 외부에서는 접근이 불가능하다.

상속받은 객체에서도 접근이 안된다.