[JavaScript] Object-Oriented Programming

Steve·2021년 5월 10일
0

웹개발 코스

목록 보기
18/59

객체지향 프로그래밍

절차 지향 (Precedural Programming) <--> 객체 지향 (Object Oriented Programming)

  • 객체 지향 프로그래밍은 데이터기능을 한데 묶을 수 있다.
  • 속성과 메소드가 하나의 class 에 포함된다.
  • 자바스크립트 내장 타입인 object (object literal이라고 부른다) 와는 다르다. (template literal 과 혼동하지 말것)

** literal - 문자 그대로의 (literally, ...)

OOP Basic Concetps

1) 캡슐화 (Encapsulate)

  • 데이터와 기능을 class 로 묶어 정의한다.
  • 은닉성 (Hiding) : 필요에 따라 데이터와 메소드를 외부로부터 숨길 수 있다.
  • 느슨한 결합(Loose Coupling) - 절차적 코드와는 달리 쉽게 수정이 가능하다 (loose).

2) 추상화 (Abstraction)

  • 복잡한 것을 단순화한다 - interface

3) 상속 (Inheritance)

  • 부모 클래스의 특징을 자식 클래스가 물려받는 것.

4) 다형성 (Polymorphism)

  • 하나의 객체가 여러가지 타입을 가질 수 있다.

자바스크립트는 엄밀히 말하면 객체지향 언어는 아니다. prototype 지향 언어다. 하지만 객체 지향 방식으로 사용할 수 있다.

JavaScript 메소드 호출

  • 싱글턴 패턴 (object literal 형식으로 만들기)
  • 클로저 모듈 패턴

Class (blueprint) -> Class Instances (objects)

JavaScript 객체 정의법

// ES5
function Person (age){
  this.age = age;
} // 생성자 함수는 return 값이 없음.
Person.prototype.speak = function() {}
let steve = new Person(32);

// ES6 <- 주로 사용
class Person {
  constructor (age) { // 생성자 함수 (인스턴스 생성 시 실행됨)
    this.age = age; // attribute(속성)
  }
  speak() {} // method
}
let annie = new Person(13);
  • this - 함수가 실행될 때, 해당 scope 마다 생성되는 고유한 실행 context (excution context). new 키워드로 인스턴스를 생성했을 때에는, 해당 인스턴스가 바로 this 의 값이 됨.
// 배열은 Array 객체의 instance 이다.
let arr = [1, 2, 3];
let arr = new Array(1, 2, 3);
Array.prototype.push();

Prototype

Person --- .prototype ---> Person.prototype --- new ---> steve
Person <--- .constructor --- Person.prototype <--- .__proto__ --- steve

class Person {
  constructor (sex) {
    this.sex = sex;
  }
  speak() {}
}

let steve = new Person('male');
Person === Person.prototype.constructor; // true
steve.__proto__ === Person.prototype; // true
steve.speak === Person.prototype.speak; // true

알 수 있는 사실

  1. 클래스가 정의되면 JS 는 그에 맞는 prototype 객체를 만든다.
  2. 클래스 메소드는 prototype 객체에 정의되어 있다.
  3. 사실 JavaSciprt 에서의 class 는 함수의 형태를 억지로 class 로 바꾼 것이다.class 정의가 사실상 함수 정의라는 것이다. class 정의는 constructor 함수 그자체다.

상속

class Person {
  constructor (age) {
    this.age = age;
  }
  speak() {return "I'm a person."}
}

class Student extends Person { // extends 로 상속한다.
  constructor (age, school) {
    super(age); // super() 함수는 바로 위 부모의 constructor 함수 호출이다.
    this.school = school;
  }
  speak() {
    super.speak(); // 부모의 speak() 함수를 호출한다.
    return "I'm a student.";
  }
}

JavaScript 의 한계

1. 은닉화

private 키워드가 없으므로 클로저 모듈 패턴을 사용하거나, typescript를 사용하거나, 개발시 시각적으로만 사용하거나, ES2019의 public, private field 개념을 사용한다 (babel를 이용하여 호환성 문제 해결).

2. 추상화

typescript 에는 interface 라는 개념이 있다. 인터페이스는 일종의 규약이 되어 클래스 작성 시 이에 맞게 작성할 수 있도록 돕는다.

기타

  • JS 는 함수 오버로딩을 허용하지 않는다. 이름이 같으면 인자의 갯수와 상관없이 재정의된다.
  • JS 는 멤버 함수 오버라이딩을 허용한다. 즉 자식 클래스에서 부모 클래스 내의 함수와 동일한 이름의 함수를 재정의할 시 자식 클래스의 함수가 호출된다. 엄밀히 말하면 prototype chain 을 따라 가는 것이다.
  • 부모 함수를 호출하고 싶을 때는 super 키워드를 사용한다.

느낀점

  • JS 로 객체지향 프로그래밍을 설명하기에는 부족함이 많다. 직관적이지도 않고, 객체지향의 필수 요소들이 많이 빠져 있어서 억지로 도입한 느낌이 강하다.
  • JS 는 멤버함수, 멤버변수라는 말을 잘 쓰지 않는 것 같다. 멤버변수는 class attribute, 멤버함수는 prototype method 라고 한다.
profile
게임과 프론트엔드에 관심이 많습니다.

0개의 댓글