[LearningJS] 객체와 객체지향 프로그래밍

객체와 객체지향 프로그래밍

  1. Tutorial

    • 배열과 마찬가지로 객체 역시 컨테이너지만, 배열은 값을 가지며 각 값에는 숫자형 인덱스가 있다. 반면, 객체는 프로퍼티를 가지며 각 프로퍼티에는 문자열이나 심볼 인덱스가 있다.

      • 문자열 인덱스 : 객체명[key] -> return value

      • 심볼 인덱스 : 객체명[심볼명] -> return value

    • 배열에는 순서가 있다. 즉, arr[0]은 arr[1] 보다 항상 앞에 있다. 반면, 객체는 순서가 보장되지 않는다.
    • 프로퍼티는 키(문자열 또는 심볼)과 값으로 구성된다.
    • 객체는 키를 통해 프로퍼티에 접근할 수 있다.
  2. 프로퍼티 나열

    • for..in : 키가 심볼인 프로퍼티는 포함되지 않는다.
      • hasOwnProperty() : 상속된 프로퍼티가 for..in에 나타날 위험을 제거
      • for..in 문을 배열에 사용할 수 있지만, 좋은 것은 아니다. 배열에는 일반적인 for 루프나 forEach를 사용하는 것이 좋다.
    • Object.keys : 객체에서 나열 가능한 문자열 프로퍼티를 배열로 반환
      • 객체의 프로퍼티 키를 배열로 가져와야 할 때는 Object.keys가 편리하다.
  3. 객체지향 프로그래밍

    • 객체(Object) : 데이터와 기능을 논리적으로 묶어 놓은 것(key를 통해 프로퍼티에 접근)

    • 클래스(Class) : 어떤 자동차처럼 추상적이고 범용적인 것

    • 인스턴스(Instance) : 특정 자동차처럼 구체적이고 한정적인 것

    • 메서드(Method) : 기능

    • 클래스 메서드(Class Method) : 클래스에 속하지만 특정 인스턴스에 묶이지는 않는 기능

    • 생성자(Constructor) : 인스턴스를 처음 만들 때 객체 인스턴스를 초기화하는 것

    • 클래스 생성

      class Car {
          constructor() {
                   
          }
      }
      
    • 인스턴스 생성

      const car1 = new Car();
      
    • 객체가 클래스의 인스턴스인지 확인하는 연산자

      car1 instanceof Car;	// true
      
    • this : 의도한 목적, 즉 메서드를 호출한 인스턴스를 가리키는 목적으로 사용

      • 일종의 placeholder, 클래스의 this는 클래스의 인스턴스의 placeholder도 된다.
      • this는 메서드를 호출하는 시점에서 무엇인지 알 수 있다.
        • 정의하는 시점에서는 알 수 없다.
    • 가짜 접근 제한 : 외부에서 접근하면 안되는 프로퍼티 이름 앞에 밑줄(_)을 붙인다.

    • 프로퍼티 보호 : 스코프를 이용해 보호하는 WeakMap 인스턴스를 사용

      • WeakMap은 클래스 외부에서 접근하면 안되는 프로퍼티를 안전하게 저장한다.
    • 프로토 타입 : 클래스의 인스턴스에서 사용할 수 있는 메서드

      • 선언 : 클래스명.prototype.메서드명
      • 모든 함수에는 prototype이라는 프로퍼티가 있으며, new 키워드로 만든 새 객체는 생성자의 prototype 프로퍼티에 접근할 수 있다. 객체 인스턴스는 생성자의 prototype 프로퍼티를 __proto__ 프로퍼티에 저장한다. (__ 가 붙은 프로퍼티는 자바스크립트의 내부 동작 방식에 영향을 미치기 때문에 건드리지 말자!)
      • 동적 디스패치(Dynamic Dispatch) : 클래스의 인스턴스는 모두 같은 프로토타입을 공유하므로, 프로토타입에 프로퍼티나 메서드가 있다면 해당 클래스의 인스턴스는 모두 그 프로퍼티나 메서드에 접근할 수 있다.
      • 인스턴스에서 메서드나 프로퍼티를 정의하면 프로퍼티에 있는 것을 가린다.
        • 자바스크립트는 먼저 인스턴스를 체크하고, 거기에 없으면 프로토타입을 체크한다. (chaining 된 순서대로 체크한다.)
      • 정적 메서드(== 클래스 메서드) : 인스턴스와 관련 X. 클래스에 관련된 범용적인 작업(동작)을 한다.
        • this 인스턴스가 아닌 클래스 자체에 묶인다.
        • this 대신 클래스 이름을 사용한다.
    • 상속 : 클래스의 인스턴스는 클래스의 기능을 모두 상속한다. (키워드 : extends)

      • 프로토타입 체인 : 객체의 프로토타입에서 메서드를 찾지 못하면 자바스크립트는 프로토타입의 프로토타입을 검색한다.
      • 클래스의 계층 구조를 만들 때 프로토타입 체인에서 가장 적절한 위치에 메서드를 정의하는 것이 좋다.
      • 서브클래스의 생성자에서는 super() 함수를 써서 슈퍼클래스의 생성자를 호출한다.
      • 서브클래스의 인스턴스는 슈퍼클래스의 모든 메서드에 접근할 수 있다. (반대로 슈퍼클래스는 서브클래스에 접근할 수 없다.)
    • 다형성(Polymorphism) : 여러 슈퍼클래스의 멤버인 인스턴스

      • 자바스크립트의 모든 객체는 루트 클래스인 Object의 인스턴스이다.
    • 문자열 표현 : toString() 메서드 사용

  4. 다중 상속, 믹스인, 인터페이스

    • 다중 상속 : 클래스가 슈퍼클래스 두 개를 가지는 기능

      • 인터페이스로 대체
    • 믹스인 : 자바스크립트에서 다중 상속이 필요한 문제에 대해 적용하는 기능

      • 개별 객체가 아닌 Car 클래스의 프로토타입에 믹스인 적용
      class InsurancePolicy {};
      function makeInsurable(o) {
          o.addInsurancePolicy = function(p) {
              this.insurancePolicy = p;
          };
          o.getInsurancePolicy = function() {
              return this.insurancePolicy;
          };
          o.isInsured = function() {
              return !!this.insurancePolicy;
          };
      }
           
      makeInsurable(Car.prototype);
      const car1 = new Car();
      car1.addInsurancePolicy(new InsurancePolicy());
      
      • 심볼을 이용해 클래스 간의 메서드 충돌 방지
      class InsurancePolicy {};
      const ADD_POLICY = Symbol();
      const GET_POLICY = Symbol();
      const IS_INSURED = Symbol();
      const _POLICY = Symbol();
           
      function makeInsurable(o) {
          o[ADD_POLICY] = function(p) {
              this[_POLICY] = p;
          };
          o[GET_POLICY] = function() {
              return this[_POLICY];
          };
          o[IS_INSURED] = function() {
              return !!this[_POLICY];
          };
      }
      

태그:

업데이트:

댓글남기기