본문 바로가기

Programming

[JavaScript] 객체지향 프로그래밍 - ES6 class 키워드없이 구현하기

Reference - 코드 스테이츠 이머시브 코스 - OOP 강의 

 

 

맨 오른쪽이 왜 함수형 프로그래밍인지는 아직 모르겠다

 

객체지향 프로그래밍(Object Oriented Programming)이란?

  • OOP는 특정한 언어나 라이브러리가 아닌 프로그래밍 패러다임이다.
  • OOP에선 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위인 '객체'들의 모임으로 파악한다.
  • OOP는 예전에 만들어진 절차적 프로그래밍 언어(C, Pascal, etc)들과 다른 종류의 언어들에서 사용한다.
  • OOP의 모든 것은 지속 가능한 '객체'로 그룹화되며 4가지 주요개념을 통해 재사용성을 가질 수 있다.

 

OOP의 4가지 주요개념

1. Encapsulation

  • 데이터와 함수를 하나의 단위로 캡슐화한다. 
  • 캡슐 안의 특정 속성과 메소드를 숨긴 채로 동작하게 할 수 있다 
  • 느슨한 결합으로 내부 의존성이 낮기에 언제든 구현을 수정할 수 있다. 

2. Inheritance

  • 부모의 클래스를 자식이 물려받아 재사용할 수 있다. 
  • 상속을 통해 코드의 중복을 줄일 수 있다. 

3. Abstraction

  • Encapsulation에서 좀 더 확장된 개념이다.
  • 추상화를 통해 외부 코드에서 특정 속성과 메소드를 숨겨 인터페이스를 더 단순하게 만들 수 있다. 
  • 코드를 변경했을 때의 영향을 분리시켜  충돌 사항이 외부 코드가 아닌 표시된 변수에만 영향을 미치도록 도와준다.

4. Polymorphism

  • 같은 타입이지만 실행 결과가 다양한 객체를 대입할 수 있는 성질인 다형성을 뜻한다.
  • 같은 부모 클래스를 가졌지만 각기 다른 하위 클래스를 가질 수 있다.
  • 객체의 유형에 따라 여러 HTML 요소를 렌더링 할 수 있다. 
  • 객체의 부품화가 가능하다. 

 

ES6의 Class 키워드가 나오기 전 사용된 4가지 Class 선언 방식

 

울집 갱얼쥐

강아지를 class로 birthday를 실행하면 age가 추가되고

say를 실행하면  sound를 출력하는 함수를 쓴다면...

 

1. Functional Instantiation - 함수를 이용한 방식

 

var Dog = function(age, sound) {          // class가 되는 함수.
var someInstance = {};          // 함수가 실행될 때 리턴될 객체를 선언함. 
	someInstance.sound = sound;
    someInstance.age = age;  // 인스턴스의 초기값을 인자로 받음.
    someInstance.birthDay = function() {
    	this.age += 1;     // this는 someInstance 뜻함. 
    }
    someInstance.say = function() {
    	console.log(this.sound);
    }
    return someInstance;
};

var maltese = Dog(1, 'woof!');
var welshCorgi = Dog(4, 'bark!');
maltese.birthDay() // age는 2가 됨.
welshCorgi.say() // -> bark!가 출력됨.

 

2. Functional Shared 

var extend = function(to, from) {
	for (var key in from){
    	to[key] = from[key];  
        // someInstance의 age값은 someMethod.birthDay로 인해 누적됨.
    }
};

var someMethods = {};    // 모든 메소드들을 담아줄 객체
someMethods.birthDay = function() {
	this.age += 1;
};
someMethods.say = function() {
	console.log(this.sound)
};

var Dog = function(age, sound) {
	var someInstance = {
    	age: age,
        sound: sound
    }
    // someInstance와 someMethods를 extend로 Dog 내부에서 합침.
    extend(someInstance, someMethods); 
    return someInstance;
};

var maltese = Dog(1, 'woof!');
maltese.say() // -> woof!가 출력됨.
maltese.birthday() // age가 1 증가됨.
console.log(maltese.age) // 2가 출력됨.

 

Functional Shared를 사용하는 이유?

 

1번의 방식은 인스턴스를 생성할 때마다 모든 메소드를 someInstance에게 할당하기 때문에

각각의 인스턴스들이 메소드의 수만큼의 메모리를 더 차지한다.

 

하지만 Functional Shared 방식을 사용하면,

someMethod 객체의 메소드들의 메모리 주소만을 참조 메모리 효율이 좋아진다. 

 

3. Prototypal Instantiation 

var someMethods = {};    // 모든 메소드들을 담아줄 객체
someMethods.birthDay = function() {
	this.age += 1;
};
someMethods.say = function() {
	console.log(this.sound)
};

var Dog = function(age, sound) {
    // Object.create는 특정 객체를 프로토타입으로 하는 객체를 생성하는 함수
    var someInstance = Object.create(someMethods);
    someInstance.age = age;
    someInstance.sound = sound
    return someInstance;
};

var welshCorgi = Dog(5, 'bark!')
welshCorgi.say() // -> 'bark!'
welshCorgi.birthDay() 
console.log(welshCorgi.age) // -> 6
Object.create의 사용법
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/create
 

Object.create()

Object.create() 메서드는 지정된 프로토타입 객체 및 속성(property)을 갖는 새 객체를 만듭니다.

developer.mozilla.org

 

4. Pseudoclassical - ES6 class 키워드를 이용한 방법과 동일한 원리로 작동

var Dog = function(age, sound) {
    this.age = age;
    this.sound = sound;
};

Dog.prototype.birthDay = function() {
	this.age += 1;
};
Dog.prototype.say = function() {
	console.log(this.sound);
};

var maltese = new Dog(2, 'woof!')
var welshCorgi = new Dog(4, 'bark!')

 

앞에 new operator만 붙여주면 되기 때문에 앞서 말한 방법들보다 훨씬 간단하다. 

자주 쓰이는 방법이라고 하니 꼭 짚고 넘어가야 할 듯하다. 

 

왜 ES6 class 키워드와 동일한 원리일까?

 

자바스크립트는 클래스라는 개념이 존재하지 않는 대신 프로토타입이 존재하는 프로토타입 기반 언어라고 한다. 

그래서 ES6부터 class 키워드로 인해 언어가 클래스기반으로 바뀐 것이 아니라 class 역시 프로토타입을 이용해 문법적으로 객체 지향처럼 사용할 수 있도록 한 것이다. 

 

그러므로 class는 프로토타입이 사용된 위의 예제의 원리와 근본적으로 같다. 

아래 포스트를 참고하였다. 읽어보길 왕왕 추천!
https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67
 

[Javascript ] 프로토타입 이해하기

자바스크립트는 프로토타입 기반 언어라고 불립니다. 자바스크립트 개발을 하면 빠질 수 없는 것이 프로토타입인데요. 프로토타입이 거의 자바스크립트 그 자체이기때문에 이해하는 것이 어렵

medium.com