Javascript 헷갈렸던 내용, 새로 알게된 내용 정리
→ Class, fields


Class

클래스 : 데이터를 정의하지 않고 틀만 정의해놓는 명세서
오브젝트 : 클래스를 이용해서 실제로 데이터를 넣어서 만들어지는 것

class Person {
  // constructor
  constructor(name, regieon){
    //fields
    this.name = name;
    this.regieon = regieon;
  }
  speak(){
    console.log(`${this.name} : hello!`);
  }
}

const person = new Person('jin', 'seoul');
console.log(person.name);
console.log(person.regieon);
person.speak();

// ↓결과값
// jin
// seoul
// jin : hello!


getter, setter, private fields, static

getter, setter

‘클래스’를 일상에서 볼 수 있는 자판기로 비유하자면, ‘커피의 개수(number of coffee)’는 integer일 것이고, put coins, make coffee 메서드 두개가 있다고 할 때 number of coffee는 마이너스가 될 수 없을 것이다. 이렇듯 ‘사용자’가 마이너스라는 말도안되는 값을 넣으려고 하는 것을 방지하기 위해 getter와 setter를 사용한다고 할 수 있다.

또한 자판기 커피 개수를 다른사람이 수정할 수 있다는 것은 좋지 않듯, 다른사람이 getter와 setter를 사용하는 것은 좋지 않을 것이다. 따라서, number of coffee라는 프로퍼티는 프라이빗으로 만들어야 하고 이것을 ‘인캡슐레이션’이라고 한다.

class User {
  constructor(firstName, lastName, age){
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age; // ← (1)
  }
  
  get age(){
    return this.age;
  }
  
  set age(value){
    this.age = value;
  }
}

const user1 = new User('Steve', 'Job', -1); // ← (2)
console.log(user1.age);

이 경우에 문제가 있다. (2)단계에서 age를 정의하게 되는순간 (1)단계의 this.age라는 부분이 getter age를 호출하고 = age;라는 부분이 바로 setter를 호출하는데,

문제는, setter 내부의 this.age = value; 라는 부분에서 또 다시 getter와 setter를 호출하는 현상이 발생되고 이것이 무한 반복되어 스택 풀 현상 발생.

이것을 방지하기 위해서는 getter와 setter안에 사용되는 변수명을 constructor에 선언된 변수와 다르게 설정해야한다.

class User {
  constructor(firstName, lastName, age){
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }
  
  get age(){
    return this._age; ◀︎◀︎◀︎◀︎◀︎◀︎◀︎◀︎◀︎
  }
  
  set age(value){
    this._age = value; ◀︎◀︎◀︎◀︎◀︎◀︎◀︎◀︎◀︎
  }
}

const user1 = new User('Steve', 'Job', -1);
console.log(user1.age);

그리고 앞서 설명했던 마이너스 값을 방지하기 위해 setter를 좀더 보완하면 아래처럼 구현 가능

set age(value){
  // 아래의 throw Error(메세지); 코드로 개발자모드 콘솔창에 메세지 출력 가능
  // if (value < 0) {
  //   throw Error('age can not be negative');
  // }
  this._age = value < 0 ? 0 : value;
}


private fileds

private fields 선언은 아래와 같이 선언 가능

class Experiment {
  publicField = 2;
  #privateField = 0;
}

const experiment = new Experiment();
console.log(experiment.publicField);
console.log(experiment.privateField);

// ↓결과값
// 2
// undefined

필드명 앞에 해시(#)기호를 붙이게 되면 외부에서 접근할 수 없는 private field가 된다.

주의사항으로는 매우 최신 문법이기 때문에 아직 지원되지 않는 브라우저가 상당수 존재한다는 점


static

마찬가지로 아직까지 많이 지원되는 문법은 아니지만 참고해놓으면 좋은 문법으로 static이 있다.

class Aricle {
  static publisher = 'A team';
  constructor(articleNumber){
		this.articleNumber = articleNumber;
  }
	static printPubilsher(){
    console.log(Article.publisher);
  }
}

const article1 = new Articlel(1);
const article2 = new Articlel(2);
console.log(article1.publisher); // ← (1)

여기서 (1)부분의 결과값은 undefined.

이유는 artice1이라는 인스턴스에서는 publisher라는 필드가 정의되지 않은 것으로 간주되고있기 때문. static으로 선언된 변수의 경우 오브젝트 명이 아니라 클래스 자체에 붙어있기 때문.

따라서,

console.log(article1.publisher); 가 아니라

console.log(Article.publisher); 로 호출해야 호출 가능

마찬가지로 printPublisher 함수를 호출할때도

Article.printPubilsher()로 호출 필요.

이렇듯 static은 인스턴스에 들어오는 값에 상관없이 ‘공통적으로’ 선언 및 사용이 필요한 경우에 유용하게 사용가능. (메모리 효율 ↑)

Leave a comment