05.클래스 (class)

Updated:

JS 에서 Class 란?

  • 자바스크립트는 프로토타입 기반(prototype-based) 객체지향 언어 입니다.

  • 비록 다른 객체지향 언어들과의 차이점에 대한 논쟁이 있긴 하지만, 자바스크립트는 강력한 객체지향 프로그래밍 능력을 지니고 있습니다.

1. Prototype (생성자 함수)

// fistName, lastName 은 Property(속성) 이라고하고, getFullName은 함수가 할당된 속성인 메소드(Method)라고 불림
// 속성과 메소드를 통틀어서 Member(맴버)라고 불림
// this가 소속되어 있는 함수가 그 위에 객체 데이터를 지칭하는것임. 즉, this를 Jacob 이라고 명시해도 됨
// 하지만 Jacob은 변수이기 때문에 매번 바뀌어서 this 를 사용하는것임.
// 아래와 같이 작성하면 메모리 효율이 떨어짐 -> class 가 사용됨

const Jacob = {
  firstName: "Jacob",
  lastName: "ko",
  getFullName: function () {
    return `${this.firstName} ${this.lastName}`;
  },
};
console.log(Jacob);
console.log(Jacob.getFullName()); // Jacob

const amy = {
  firstName: "Amy",
  lastName: "Clarke",
  getFullName: function () {
    return `${this.firstName} ${this.lastName}`;
  },
};
console.log(amy);
console.log(amy.getFullName());

const neo = {
  firstName: "Neo",
  lastName: "Smith",
  getFullName: function () {
    return `${this.firstName} ${this.lastName}`;
  },
};
console.log(neo);
console.log(neo.getFullName());

🔸 그래서 메모리 사용 효율을 위해서 class 를 사용합니다 (일반적인 programming 언어와는 약간 다른 class 개념)

  • prototype을 사용하면 객체 데이터가 한번만 만들어져서 메모리 사용에 도움이됩니다

  • JS를 prototype 기반의 언어라고도 불림. 그만큼 많이 쓰입니다.

  • prototype 안에 많은 method 를 사용하여 실행 합니다.

// pascal case (앞에 대문자)로 function 뒤에 사용되는 key는 앞에 대문자 형태로 해야됨.
function User(first, last) {
  this.firstName = first;
  this.lastName = last;
}
user.prototype.getFullName = function () {
  return `${this.firstName} ${this.lastName}`;
};

// new 라고 새로 생긴 함수를 생성자 함수라고 함
// 그때 하나의 객체 대이터가 생성되는것임.
// 각 object를 나타내는 Jacob, amy, neo 를 instance 라고 함

const Jacob = new user("Jacob", "Ko");
const amy = new user("Amy", "Clarke");
const neo = new user("Neo", "Smith");

console.log(Jacob.getFullName());
console.log(amy.getFullName());
console.log(neo.getFullName());

// {}, [] 를 통해서 Object를 나타 내는것을 리터럴 방식이라고 함 -> 데이터를 생성하는 개념이라고 봐도됨

2. this

  • 자기 자신을 참조하는 변수 입니다.

  • JS에서는 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정되는 것이 아니고, 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정된다.

// 일반(Normal) 함수는 호출 위치에서 따라 this 정의!
// 화살표(Arrow) 함수는 자신이 선언된 함수 범위에서 this 정의!

const jacob = {
  name: "Jacob",
  normal: function () {
    console.log(this.name);
  },
  arrow: () => {
    console.log(this.name);
  },
};

// normal 함수에서는 호출위치 아래에 위치에서 변수 jacob을 불러와서
jacob.normal();
jacob.arrow();

const amy = {
  name: "Amy",
  normal: jacob.normal,
  arrow: jacob.arrow,
};
amy.normal();
amy.arrow();

// prototype 적용
function User(name) {
  this.name = name;
}
User.prototype.normal = function () {
  console.log(this.name);
};
User.prototype.arrow = () => {
  console.log(this.name);
};

const jacob = new User("Jacob");

jacob.normal();
jacob.arrow();

//  normal 함수를 사용하면 안되고 arrow 함수를 사용해야 되는경우 예시
// setTime, setTimeout 의 함수에는 콜백으로 arrow 함수를 써야됨. this의 지정 때문에
const timer = {
  name: "Jacob!!",
  timeout: function () {
    // setTimeout(함수, 시간)
    setTimeout(() => {
      console.log(this.name);
    }, 2000);
  },
};
timer.timeout();

🔑 3. ES6 Classes

  • 위의 class 는 원시적으로 나타낸것이고, ES6 class 를 사용하면 더 직관적으로 코드를 작성 할 수 있습니다.

  • SPA (특히, react) 에서 주로 사용되는 코드 형식입니다.

// normal 부분에서 :function  축약 생략해서 사용할 수 있음
const jacob = {
  name: "Jacob",
  normal() {
    console.log(this.name);
  },
  arrow: () => {
    console.log(this.name);
  },
};

jacob.normal();
jacob.arrow();

// 기존에 작성한 코드
function User(first, last) {
  this.firstName = first;
  this.lastName = last;
}
User.prototype.getFullName = function () {
  return `${this.firstName} ${this.lastName}`;
};

const jacob = new User("Jacob", "Ko");
const amy = new User("Amy", "Clarke");
const neo = new User("Neo", "Smith");

console.log(jacob);
console.log(amy.getFullName());
console.log(neo.getFullName());

// 위의 ES6 Class 로 표현한 방법임
// 나중에 React 배울때 주로 쓰는 문법임
class User {
  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
  }
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const jacob = new User("Jacob", "Ko");
const amy = new User("Amy", "Clarke");
const neo = new User("Neo", "Smith");

console.log(jacob);
console.log(amy.getFullName());
console.log(neo.getFullName());

4. class 상속 (Inheritance)

  • 클래스 상속을 사용하면 클래스를 다른 클래스로 확장할 수 있습니다.

  • 기존에 존재하던 기능을 토대로 새로운 기능을 만들 수 도 있습니다.

  • extend 키워드를 사용해서 기존 선언된 class 를 가져 올 수 있습니다.

  • super 이럴 때 사용합니다.

    • super.method(...)는 부모 클래스에 정의된 메서드, method를 호출합니다.
    • super(...)는 부모 생성자를 호출하는데, 자식 생성자 내부에서만 사용 할 수 있습니다.
class Vehicle {
  constructor(name, wheel) {
    this.name = name;
    this.wheel = wheel;
  }
}
const myVehicle = new Vehicle("운송수단", 2);
console.log(myVehicle);

// extends 확장(상속)
class Bicycle extends Vehicle {
  constructor(name, wheel) {
    super(name, wheel);
  }
}
const myBicycle = new Bicycle("자이언트", 2);
const daughtersBicycle = new Bicycle("세발", 3);
console.log(myBicycle);
console.log(daughtersBicycle);

class Car extends Vehicle {
  constructor(name, wheel, license) {
    super(name, wheel);
    this.license = license;
  }
}
const myCar = new Car("벤츠", 4, true);
const daughterscar = new Car("포르쉐", 4, false);
console.log(myCar);
console.log(daughterscar);

Reference

Leave a comment