본문 바로가기

JavaScript

JavaScript에서의 OOP (Object Oriented Programming)

반응형

객체(Object) 란?

물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 고유 속성을 가지고 다른 것과 식별 가능한 것

 

따라서 소프트웨어에서 객체를 만든다는 것은 물리적 존재나, 추상적 생각의 구현물들을 속성과 메소드로 정의하는 과정이라고 볼 수 있다.

 

객체의 구성

객체 = 속성 + 메소드

 

 

자바스크립트에서의 Object

 

JS의 객체 자료형

  • 원시 자료형 (null, undefined, "string", 10, true, false ...) --> 객체처럼 다루지 않으면 객체의 특성을 가지지 않음
  • 객체

자바스크립트는 데이터 저장을 위해 원시 자료형과 객체 이 2가지 종류의 자료형을 사용한다. 숫자나 문자열 같은 단일한 데이터를 저장하는 원시 자료형은 자바스크립트 안에서 사용하는 기본적인 데이터 저장 형태지만 실제 우리가 살아가는 세상의 데이터들은 이런 원시 자료형으로는 다 담을 수가 없다. 불가능한 것은 아니지만, 수 백개의 변수를 선언해야 하는 등 매우 비효율적일 수 있다.

 

 

그리고 자바스크립트가 주 무대로 활동하는 웹에서는 다양한 데이터들이 JSON 또는 XML 등의 형태로 표현되어 전송되며, 여러 타입의 데이터가 넘어온다. 이런 데이터를 일일이 구분해 저장한다면 많은 처리 지연시간을 발생시키고, 비효율적인 연산 작용이 많이 필요하다. 이런 복잡성은 서비스 사용자에게 대기시간을 발생시키고 이탈을 야기할 수도 있으며 객체는 이러한 데이터들을 하나의 컨테이너에 담아 저장하고, 데이터에 접근할 수 있게 도와준다.

 

  • 객체는 new 키워드와 함께 생성자 함수를 호출하여 만들 수 있다. 또는 literal 이라는 약식 표현을 사용해서 만들 수도 있다.
  • 원시값은 값으로 저장되고, 원시값을 복사하면 그대로 복사가 된다. 반면 객체는 참조가 저장되므로 객체를 복사하면 참조만 복사된다.
  • 즉 객체는 서로 동일한 객체를 참조하고 있을 때만 같은 것으로 본다.
  • 객체의 속성을 참조하면 먼저 해당 객체에 속성이 참조되어 있는지 확인하고, 참조되어있지 않으면 생성자 함수의 prototype 속성에서 찾는다. 여기서도 찾을 수 없으면 prototype은 객체이고, 객체는 Object() 생성자로부터 만들어지므로 Object() 생성자의 prototype 속성(Object.prototype)에서 속성을 찾는다. 여기서도 속성을 찾을 수 없으면 이 속성은 정의되지 않았다(undefined)고 판단한다.
  • 자바스크립트에서는 프로토타입 체인 검색을 사용해 상속을 구현한다(이를 프로토타입 상속이라고 부른다,)
  • prototype 속성은 Object() 객체라는 사실과 객체 속성 검색 체인(=프로토타입 상속) 덕분에 모든 객체는 Object()를 상속받는다.
  • 함수는 속성과 값을 지닌 객체다.
  • 함수 안에서 사용하는 this 키워드는 함수를 포함한 객체를 참조한다.
  • this의 값은 함수가 호출되는 컨텍스트에 따라 결정된다.
  • 자바스크립트에서는 고유한 스코프를 만들기 위해 함수를 사용한다.
  • 함수는 스코프 체인을 통해 변수를 찾는다.
  • 스코프 체인은 코드가 작성된 위치에 따라 만들어지므로 함수가 호출된 컨텍스트에는 영향을 받지 않는다. 이 덕분에 한 번 작성된 함수는 다른 컨텍스트 에서 실행되더라도 원래의 스코프에 접근할 수 있다. 이런 특성으로 인해 클로저가 만들어진다.

 

 

자바스크립트에서의 OOP(Object Oriented Programming)

OOP의 기본 컨셉은 프로그램 내에서 표현하고자 하는 실 세계(real world)의 일들을 객체를 사용해서 모델링하고, 객체를 사용하지 않으면 불가능 혹은 아주 어려웠을 일들을 쉽게 처리하는 방법을 제공한다는 것입니다. 

-MDN-

 

자바스크립트에는 Object, Function, Array 등과 같이 다양한 기본 객체들이 있고, 모든 객체는 자바스크립트의 기본 객체인 Object를 확장하고 있다. 하지만 자바스크립트는 클래스 기반이 아니라 프로토 타입을 기반으로 하는 객체 기반의 언어입니다. 이렇게 기반이 다르기 때문에 자바스크립트를 사용하여 객체의 계층 구조를 만들고 상속하는 방법은 명확하지 않을 수 있다.

 

자바스크립트는 함수 기반 언어인 Scheme을 기반으로 만들어진 뒤 자바에서 다양한 프로그래밍 개념들을 가져왔는데, 객체지향 언어는 아니지만 객체지향과 비슷한 특징들을 지원한다. 이를 가능하게 하는 개념이 바로 프로토타입(prototype) 이다.

 

사실 OOP와 객체지향의 클래스라는 주제는 자바스크립트의 핵심을 관통하는 내용이라고 보기는 어렵다. 하지만 프로그래밍 세계를 이해하는데 있어 중요한 개념이고, 자바스크립트의 데이터타입, 스코프, 실행 컨텍스트, this, 클로저, 프로토타입 등을 이해하는 데 큰 도움이 될 것이다.

 

 

프로토타입 (Prototype)

 

const instacne = new Constructor();

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

 

 

위 그림대로 new 연산자로 constructor를 호출하면 instance가 만들어지고, 이 instance가 가지고 있는 생략 가능한 프로퍼티인 __proto__는 constructor의 prototype을 참조합니다.
자바스크립트는 함수에 자동으로 객체인 prototype 프로퍼티를 생성해 놓습니다. 그래서 해당 함수를 생성자 함수로써 사용할 경우, 즉 new 연산자와 함께 함수를 호출할 경우, 그로부터 생성된 인스턴스에는 숨겨진 프로퍼티인 __proto__가 자동으로 생성됩니다. 그리고 이 프로퍼티는 생성자 함수의 prototype을 참조합니다. __proto__ 프로퍼티는 생략 할 수 있도록 구현돼 있기 때문에 생성자 함수의 prototype에 어떤 메서드나 프로퍼티가 있다면 인스턴스에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근할 수 있게 됩니다.

 

 

Mixin

Object.assign(User.prototype, sayHiMixin);

Mixin은 다른 언어와 달리 자바스크립트에선 없는 클래스 복사 기능을 흉내 낸 것이며, 특정 행동을 실행해주는 메서드를 제공하는데 단독으로 쓰이지 않고 다른 클래스에 행동을 더해주는 용도로 사용된다.

Wikipedia에서는 믹스인(mixin) (opens new window)을 다른 객체를 상속받을 필요 없이 구현되어있는 메서드를 담고 있는 객체라고 정의합니다. 

 

자바스크립트에서 믹스인을 구현할 수 있는 가장 쉬운 방법은 유용한 메서드 여러 개가 담긴 객체를 하나 만드는 것입니다. 이렇게 하면 다수의 메서드를 원하는 클래스의 프로토타입에 쉽게 병합할 수 있습니다.

const clickableMethods = {
  hover() {
    console.log('hovering')
  },
  press() {
    console.log('button pressed')
  },
  click() {
    console.log('button clicked')
  },
}

상속이 아닌 믹스인만을 이용해서 위의 클릭과 관련한 함수 기능을 그대로 활용하고자 한다면 다음과 같이 사용할 수 있다.

function Button(size, color) {
  this.size = size
  this.color = color
}

Object.assign(Button.prototype, clickableMethods)

new Button(20, 'primary').hover() // hovering

 

 

요약

  • 어떤 생성자 함수를 new 연산자와 함께 호출하면 Constructor에 정의된 내용을 바탕으로 새로운 인스턴스가 생성된다. 이 인스턴스에는 __proto__라는, Constructor의 prototype 프로퍼티를 참조하는 프로퍼티가 자동으로 부여된다.
  • __proto__는 생략 가능한 속성이라, 인스턴스는 Constructor.prototype의 메서드를 마치 자신의 메서드인 것처럼 호출할 수 있다.
  • 프로토타입을 도식화한 삼각형의 대각선 방향인 __proto__ 방향을 계속 찾아가면 최종적으로는 Object.prototype에 도달합니다. 이런 식으로 __proto__ 안에 다시 __proto__를 찾아가는 과정을 프로토타입 체이닝이라고 합니다. 이 체이닝을 통해 각 프로토타입 메서드를 자신의 것처럼 호출할 수 있다. 이때 접근 방식은 자신으로부터 가장 가까운 대상부터 찾아 나가며, 원하는 값을 찾으면 검색을 중단한다.
  • 믹스인 은 객체 지향 언어에서 범용적으로 쓰이는 용어로, 다른 클래스들의 메서드 조합을 포함하는 클래스를 의미한다.
  • 몇몇 언어는 다중상속을 허용하지만 자바스크립트는 다중상속을 지원하지 않는다. 하지만 믹스인을 사용하면 메서드를 복사해 프로토타입에 구현할 수 있다.

 

반응형