TIL#8

Yea Myeong Kim·2021년 12월 13일
0

2021/12/13(월)

객체지향 프로그래밍

하나의 모델이 되는 청사진(blueprint)을 만들고 -> class
그것을 바탕으로 한 객체(object)를 만드는 -> instance
프로그래밍 패턴.

OOP

프로그램 설계 철학 중 하나.
OOP의 모든 것은 "객체"로 그룹화된다.
4가지 주요개념을 통해 재사용성을 얻을 수 있음.

1. 캡슐화(Encapsulation)

  • 데이터와 기능을 하나의 단위로 묶는 것.
  • 은닉(hiding): 구현은 숨기고, 동작은 노출시킴
    - 내부 데이터나 내부 구현이 외부로 노출되지 않도록 만드는 것
  • 느슨한 결합(Loose Coupling)에 유리: 언제든 구현을 수정 가능
    - 느슨한 결합 : 코드 실행 순서에 따라 절차적으로 코드를 작성하는 것이 아니라, 코드가 상징하는 실제 모습과 닮게 코드를 모아 결합하는 것을 의미
  • 장점 : 코드가 복잡하지 않게 만들며, 재사용성을 높임.

2. 추상화(Abstraction)

  • 내부 구현은 아주 복잡한데, 실제로 노출되는 부분은 단순하게 만든다는 개념
  • 이러한 추상화를 통해 인터페이스가 단순해짐 -> 많은 기능들이 노출되지 않은 덕분에 예기치 못한 사용상의 변화가 일어나지 않도록 만들 수 있음.
  • 캡슐화의 포커스가 코드나 데이터의 은닉에 있다면, 추상화는 클래스를 사용하는 사람이 필요하지 않은 메소드 등을 노출시키지 않고, 단순한 이름으로 정의하는 것에 포커스가 맞춰져 있음.
  • 클래스를 정의할 때 메소드와 속성만 정의한 것 -> 인터페이스
  • 장점 : 단순화된 사용으로 인해 변화에 대한 영향을 최소화할 수 있다.

3. 상속(Inheritance)

  • 부모 클래스(기본 클래스(base class))의 특징을 자식 클래스(파생 클래스(derive class))가 물려받는 것.
  • JavaScript에서 extendssuper를 이용해서 상속을 구현할 수 있음.
  • 장점 : 불필요한 코드를 줄여 재사용성을 높임

4. 다형성(Polymorphism)

  • 똑같은 메소드라 하더라도, 다른 방식으로 구현될 수 있음.
  • 만일 언어 자체에서 다형성을 제공하지 않는다면, 부모 클래스에 종류별로 분기를 시켜서 하나하나 다르게 만들어야 함.
  • 장점 : 동일한 메소드에 대해서 객체의 특성에 맞게 달리 작성하는 것이 가능해진다.

클래스와 인스턴스

클래스를 만들 때 일반적인 함수를 정의하듯 만드는데, 그냥 실행하는 것이 아닌 new 키워드를 써서 만듬. + 암묵적인 규칙으로 대문자, 일반명사로 이름을 만듬

ES6 문법

class Car{
  constructor(brand, name, color){
    // 인스턴스가 만들어질 때 실행되는 코드
  }
  refuel(){
  }
  drive(){
  }
}
  • 클래스에서 속성(데이터)과 메소드(기능)를 정의 / 인스턴스에서 사용
  • this -> 함수가 실행될 때, 해당 스코프마다 생성되는 고유한 실행 컨텍스트(excution context), new키워드로 인스턴스를 생성했을 때, 해당 인스턴스가 바로 this의 값이 됨.
  • prototype -> 모델의 청사진을 만들 때 쓰는 원형 객체(original form)
  • constructor -> 인스턴스가 초기화될 때 실행하는 생성자 함수
  • 생성자 함수는 return값을 만들지 않음.

프로토타입과 프로토타입-체인

  • 자바스크립트는 프로토타입(prototype)기반 언어이다.
  • 클래스 기반 언어에서는 상속을 사용하지만, 프로토타입 기반 언어에서는 어떤 객체를 원형(prototype)으로 삼고, 이를 복제(참조)함으로써 상속과 비슷한 효과를 얻는다.

프로토타입의 개념 이해

  1. 어떤 생성자 함수(Constructor)를 new 연산자와 함께 호출
  2. Constructor에서 정의된 내용을 바탕으로 새로운 인스턴스 생성.
  3. 이때 인스턴스에는 __proto__라는 프로퍼티가 자동으로 부여됨. (__proto__는 생략이 가능)
  4. 이 프로퍼티는 Constructor의 prototype이라는 프로퍼티를 참조.

__proto__는 생략이 가능하기 때문에, 생성자 함수의 prototype에 어떤 메서드나 프로퍼티가 있다면, 인스턴스에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근이 가능하다.

example) Array(배열)

  1. Array를 new연산자와 함께 호출해서 인스턴스를 생성하든, 그냥 배열 리터럴을 생성하든, 인스턴스가 만들어 짐.
  2. 이 인스턴스의 __proto__Array.prototype을 참조 -> __proto__는 생략이 가능하기 때문에, pushpop같은 메서드를 마치 자신의 것처럼 호출할 수 있음.
  3. 다만, Arrayprototype 프로퍼티 내부에 있지 않은 from이나 isArray 등의 메서드들은 인스턴스가 직접 호출할 수 없다. -> Array 생성자 함수에서 직접 접근해야 사용이 가능하다.

constructor 프로퍼티

  • 생성자 함수의 프로퍼티인 prototype 객체 내부에는 constructor라는 프로퍼티가 있는데, 이 프로퍼티는 단어 그대로 원래의 생성자 함수(자기 자신)을 참조한다.
  • 인스턴스로부터 그 원형이 무엇인지를 알 수 있는 수단이 되기 때문에 꼭 필요한 정보이다.
  • 읽기 전용 속성이 부여된 예외 케이스(기본형 리터럴 변수(number, string, boolean))을 제외하고는 값을 바꿀 수 있다.

프로토타입-체인

__proto__ 방향을 계속 찾아가는 과정.
이 프로토타입 체이닝을 통해 각 프로토타입 메서드들을 자신의 것처럼 호출할 수 있음.
접근 방식은 자신으로부터 가장 가까운 대상으로부터 점차 먼 대상으로 나아가며, 원하는 값을 찾으면 검색을 중단함.

만약 인스턴스가 prototype과 동일한 이름의 프로퍼티 또는 메서드를 가지고 있다면?

  • 자바스크립트 엔진이 메서드를 찾는 방식은, 가장 가까운 대상인 자신의 프로퍼티, 메서드를 검색하고 없으면 그다음으로 가까운 대상인 __proto__를 검색하는 순서로 진행됨.
  • 그렇기 때문에, 인스턴스의 프로퍼티 또는 메서드가 호출됨.(메서드 오버라이딩)
  • 검색 순서의 최상단은 Object.prototype이 될 것임.
let arr = [1,2];
arr.__proto__ // Array
arr.__proto__.__proto__ // Object, 최상단
  • 그렇기 때문에 Object.prototype 에는 모든 데이터 타입에서 사용할 수 있는 범용적인 메서드만이 존재.
  • 그래서 객체 전용 메서드는 Object.prototype가 아닌 Object 생성자 함수에 static하게 담겨있다.

0개의 댓글

관련 채용 정보