Front-End

vsoghlv@naver.com

자바스크립트 객체지향 프로그래밍 1

예전에 공부했던 객체지향 프로그래밍의 여러 특성 - 클래스, 생성자, 메서드, 상속, 캡슐화 등을 자바스크립트로 구현하는 방법을 공부해 보자.

클래스 기반의 언어는 객체의 기본적 형태와 기능을 클래스로 정의하고, 인스턴스를 만들어 사용한다. 보통 이런 유형의 언어는 모든 인스턴스가 클래스에 정의된 대로 같은 구조이고 런타임에 바꿀 수 없다. 하지만 프로토타입 기반 언어는 객체의 자료구조와 메서드등을 동적으로 바꿀 수 있다. 물론 클래스 기반 언어에 비해 정확성, 안정성, 예측성 등이 조금 부족할 수는 있지만 위에 말했듯이 동적으로 자유롭게 객체의 구조와 동작 방식을 바꿀 수 있다는 장점이 있다.

클래스, 생성자, 메서드

물론 es6 에서 자바스크립트에 클래스 개념이 추가되긴 했지만, 프로토타입 기반 언어라는 점은 변하지 않는다. 이번에는 클래스, 생성자, 메서드를 함수로 구현해보자.

function Person(arg) {
  //클래스 이자 생성자
  this.name = arg;

  this.getName = function () {
    return this.name;
  };
  this.setName = function (value) {
    this.name = value;
  };
}

let me = new Person("Sun"); //인스턴스 생성
console.log(me.getName()); //Sun

me.setName("Kim");
console.log(me.getName()); //Kim

위의 코드를 보면 기존의 클래스 기반언어에서 클래스의 인스턴스를 생성하는 코드와 매우 유사하다. 클래스 이자 생성자의 역할을 하는 함수 Person 이 있고 new 키워드를 사용해 인스턴스를 생성해 사용한다.

하지만 위의 예제는 문제가 있는데 예를 들어

let me = new Person("Sun");
let kim = new Person("Kim");
let lee = new Person("Lee");

위와 같이 여러 개의 객체를 생성했을 때 setName() 과 getName() 함수를 각각 생성하며 자원 낭비를 가져온다. 이 문제를 해결하기 위해 함수객체의 프로토타입을 사용할 수 있다.

function Person(arg) {
  this.name = arg;
}
Person.prototype.getName = function () {
  return this.name;
};
Person.prototype.setName = function (value) {
  this.name = value;
};

위와 같이 prototype 프로퍼티에 각 함수를 정의하였다. 이제 Person 으로 객체를 생성했을 때 각각 생성할 필요 없이 프로토타입 체인으로 함수에 접근할 수 있다.

자바스크립트에서 클래스 안의 메서드를 정의할 때는 프로토타입 객체에 정의하고 new 로 생성된 객체에서 접근할 수 있게 하는 것이 좋다. 더글라스 크락포트는 메서드를 정의하는 방법을 아래와 같이 소개했다.

Function.prototype.method = function (name, func) {
  if (!this.prototype[name]) {
    this.prototype[name] = func;
  }
};

위의 함수를 사용하면 아래와 같이 정의할 수 있다.

Function.prototype.method = function (name, func) {
  if (!this.prototype[name]) {
    this.prototype[name] = func;
  }
};

function Person(arg) {
  this.name = arg;
}
Person.method("setName", function (value) {
  this.name = value;
});
Person.method("getName", function () {
  return this.name;
});