Front-End

vsoghlv@naver.com

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

자바스크립트의 프로토타입 체인을 이용해 상속을 구현할 수 있는데, 클래스 기반의 상속 방식을 흉내내는 방법과 클래스 개념 없이 프로토타입으로 상속을 구현하는 방법이 있다. 이를 프로토타입을 이용한 상속이라 하는데 객체 리터럴을 중심으로 상속을 구현해 낸다.

먼저 프로토타입을 이용한 상속을 살펴보자.

function create_obj(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

위의 코드는 더글라스 크락포드가 자바스크립트 객체를 상속하는 방법으로 소개한 코드이다. create_obj() 에 인자로 들어온 객체를 부모로 하는 자식 객체를 생성해서 반환하는데, 반환된 객체는 부모객체의 프로퍼티에 접근할 수 있고 자신만의 프로퍼티를 만들 수도 있다.

위의 create_obj()Object.create() 함수로 제공된다.

이제 위의 함수를 이용해 상속을 구현해보자.

let person = {
  name: "Sun",
  getName: function () {
    return this.name;
  },
  setName: function (arg) {
    this.name = arg;
  },
};
function create_obj(o) {
  function F() {}
  F.prototype = o;
  return new F();
}
let student = create_obj(person);
student.setName("a");
console.log(student.getName()); //a

위의 코드를 보면 person 객체를 상속해 student 객체를 만들었다. 자식 객체는 자신의 메서드를 재정의 하거나 추가할 수 있어야 되는데

student.setAge = function(age) ...

와 같은 방식은 코드가 지저분해질 수 있다. 자바스크립트에서는 보통 extend() 라는 이름의 함수로 객체에 객체, 혹은 함수를 추가시킨다.

let person = {
  name: "Sun",
  getName: function () {
    return this.name;
  },
  setName: function (arg) {
    this.name = arg;
  },
};

function create_obj(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

function extend(obj, prop) {
  if (!prop) {
    prop = obj; //prop 가 없는 경우 , 즉 부모가 없는 경우 자식이 부모
    obj = this; //this 를 obj 에
  }
  for (var i in prop) obj[i] = prop[i];

  return obj;
}
let student = create_obj(person);
let added = {
  setAge: function (age) {
    this.age = age;
  },
  getAge: function () {
    return this.age;
  },
};

extend(student, added);
student.setAge(25);

위의 extend 함수를 보면 반복문을 통해 값을 복사해주는데 얕은 복사를 하고 있다. 즉, 해당 객체를 복사하는 것이 아닌 참조하기 때문에 두번째 객체의 프로퍼티가 변경되면 첫번째 객체의 프로퍼티 또한 같이 변경된다.

따라서 보통 extend 함수를 구현하는 경우 대상이 객체일 때는 깊은 복사를 하는 것이 일반적이다.