클래스 | 코어자바스트립트 7

deli-ght·2022년 3월 29일
14

Javascript / algorithm

목록 보기
14/14
post-thumbnail

클래스와 인스턴스 개념 이해

클래스 : 어떤 사물의 공통 속성을 모아 정의한 것일 뿐 직접 만질 수도 볼 수도 없는 존재

  • 여기서 상하관계가 존재하는데, 하위 개념은 상위 개념을 포함하면서 더 구체적인 개념이 추가됨.

인스턴스 : 어떤 클래스의 속성을 지니는 실존하는 개체

  • 클래스를 바탕으로 인스턴스를 만들 때 비로소 어떤 개체가 클래스의 속성을 지님.
  • 다중상속을 지원하는 언어든 아니든 인스턴스 생성시 호출 가능한 클래스는 하나뿐

자바스크립트 클래스

인스턴스에 상속되는지 여부에 따라 스태틱 멤버(static member)프로토타입 메서드(prototype method)로 나뉨.

  • 스태틱 멤버 : 인스턴스에서 직접 접근할 수 없는 메서드
    • 생성자 함수를 this로 해야만 호출 가능
  • 프로토타입 메서드 : 인스턴스에서 직접 호출할 수 있는 메서드

클래스 상속

기본 구현

클래스에 있는 값이 인스턴스의 동작에 영향을 주면 안됨.
-> 클래스의 추상성을 해치는 것

하위 클래스로 삼을 생성자 함수의 prototype에 상위 클래스의 인스턴스를 부여 - 기본적인 메서드 상속 가능
하지만 다양한 문제 발생 가능 및 구조적으로 안정성이 떨어짐

클래스가 구체적인 데이터를 지니지 않게 하는 방법

일단 만들고 프로퍼티들을 일일이 지우고 새로운 프로퍼티를 추가할 수 없게 하는 것.

인스턴스 생성 후 프로퍼티 제거

let extendClass = function(SuperClass, SubClass, subMethods){
  Subclass.prototype = new SuperClass();
  for (let prop in SubClass.prototype){
    if (SubClass.prototype.hasOwnProperty(prop)){
      delete Subclass.prototype[prop]
    }
  }
  
  if (subMethod){
    for(let method in subMethods){
      SubClass.prototype[method] = subMethods[method]
    }
  }
  
  Object.freeze(SubClass.prototype);
  return SubClass;
}

let Square = extendClass(Rectangle, function(width){
  Rectangle.call(this, width, width)
})

빈 함수를 활용

let extendClass = (function() {
  let Bridge = function(){};
  return function (SuperClass, SubClass, subMethods){
    Bridge.prototype = SuperClass.prototype;
    SubClass.prototype = new Bridge();
    if(subMethods){
      for(let method in subMethods){
        SubClass.prototype[method] = subMethods[method];
      }
    }
    Object.freeze(SubClass.prototype);
    return SubClass
  }
})();

Object.create활용

// ...
Square.prototype = Object.create(Rectangle.prototype);
Object.freeze(Square.prototype);
// ...

세 코드의 공통점은 SubClass.prototype의 __proto__가 SuperClass.prototype을 참조하고,
SubClass.prototype에 불필요한 인스턴스 프로퍼티가 남아있지 않다는 것
또, SubClass 인스턴스의 constructor는 여전히 superClass를 가리키고 있음.

constructor 복구하기

SubClass.prototype.constructor가 원래의 SubClass를 바라보도록 해주어야 함.

인스턴스 생성 후 프로퍼티 제거

let extendClass = function(SuperClass, SubClass, subMethods){
  Subclass.prototype = new SuperClass();
  for (let prop in SubClass.prototype){
    if (SubClass.prototype.hasOwnProperty(prop)){
      delete Subclass.prototype[prop]
    }
  }
  🔥 SubClass.prototype.constructor = SubClass;
  if (subMethod){
    for(let method in subMethods){
      SubClass.prototype[method] = subMethods[method]
    }
  }
  
  Object.freeze(SubClass.prototype);
  return SubClass;
}

let Square = extendClass(Rectangle, function(width){
  Rectangle.call(this, width, width)
})

빈 함수를 활용

let extendClass = (function() {
  let Bridge = function(){};
  return function (SuperClass, SubClass, subMethods){
    Bridge.prototype = SuperClass.prototype;
    SubClass.prototype = new Bridge();
    
    🔥 SubClass.prototype.constructor = SubClass;
    
    if(subMethods){
      for(let method in subMethods){
        SubClass.prototype[method] = subMethods[method];
      }
    }
    Object.freeze(SubClass.prototype);
    return SubClass
  }
})();

Object.create활용

// ...
Square.prototype = Object.create(Rectangle.prototype);
🔥 SubClass.prototype.constructor = SubClass;
Object.freeze(Square.prototype);
// ...
profile
PRE-FE에서 PRO-FE로🚀🪐!

4개의 댓글

comment-user-thumbnail
2022년 3월 29일

오래 헤매고 있었는데 저에게 해결방향을 잡아주었어요, 정말 감사합니다

1개의 답글
comment-user-thumbnail
2022년 3월 31일

이 글을 읽고 자바스크립트에 대한 눈이 뜨였습니다.

1개의 답글