상속과 프로토타입?

Posted by : on

Category : javaScript


상속과 관련하여, JavaScript에는 객체라는 하나의 구조만 있다. 각 객체에는 프로토타입이라는 다른 객체에 대한 링크를 보유하는 비공개 속성이 있다

클래스는 현재 널리 채택되어 JavaScript의 새로운 패러다임이 되었지만, 클래스는 새로운 상속 패턴을 가져오지 않는다

그 프로토타입 객체도 자신만의 프로토타입을 가지고 있으며, 프로토타입으로 null을 가진 객체에 도달할 때까지 이 연결은 계속된다.

프로토타입 체인을 이용한 상속

객체의 [[Prototype]]을 지정하는 방법에는 여러 가지가 있으며, {proto: … } 구문이 표준

const o = {
  a: 1,
  b: 2,
  // __proto__는 [[Prototype]]을 설정합니다.
  // 여기에 다른 객체 리터럴로 지정되어 있습니다.
  __proto__: {
    b: 3,
    c: 4,
  },
};
const o = {
  a: 1,
  b: 2,
  // __proto__는 [[Prototype]]을 설정합니다.
  // 여기에 다른 객체 리터럴로 지정되어 있습니다.
  __proto__: {
    b: 3,
    c: 4,
    __proto__: {
      d: 5,
    },
  },
};

// { a: 1, b: 2 } ---> { b: 3, c: 4 } ---> { d: 5 } ---> Object.prototype ---> null

console.log(o.d); // 5

메서드 상속

상속된 함수가 실행 될 때, this 값은 함수가 자체 속성인 프로토타입 객체가 아니라 상속 객체를 가리킵니다.

const parent = {
  value: 2,
  method() {
    return this.value + 1;
  },
};

console.log(parent.method()); // 3
// 이 경우 parent.method를 호출할 때, 'this'는 부모를 가리킵니다.

// 자식은 부모로부터 상속받는 객체입니다.
const child = {
  __proto__: parent,
};
console.log(child.method()); // 3
// child.method가 호출되면, 'this'는 자식을 가리킵니다.
// 자식이 부모의 메서드를 상속받을 때,
// 자식에서 'value' 속성을 찾습니다. 그러나 자식은 'value'라는 자체 속성이 없기 때문에,
// 해당 속성은 [[Prototype]]에서 찾을 수 있으며, 이는 parent.value입니다.

child.value = 4; // 자식의 속성 'value'에 값 4를 할당합니다.
// 이 코드는 부모의 'value' 속성을 숨깁니다.
// 자식 객체는 이제 다음과 같습니다.
// { value: 4, __proto__: { value: 2, method: [Function] } }
console.log(child.method()); // 5
// Since child now has the 'value' property, 'this.value' means
// 자식은 이제 'value' 속성을 가지므로 'this.value'는 child.value를 의미합니다.

생성자

모든 인스턴스가 동일한 몇가지 동일한 속성을 공유하는 경우

const boxPrototype = {
  getValue() {
    return this.value;
  },
};

const boxes = [
  { value: 1, __proto__: boxPrototype },
  { value: 2, __proto__: boxPrototype },
  { value: 3, __proto__: boxPrototype },
];
// 생성자 함수
function Box(value) {
  this.value = value;
}

// Box() 생성자에서 생성된 모든 속성
Box.prototype.getValue = function () {
  return this.value;
};

const boxes = [new Box(1), new Box(2), new Box(3)];

생성자는 new로 호출되는 함수입니다.

위 생성자 함수는 classes에서 다음과 같이 다시 작성할 수 있습니다.

class Box {
  constructor(value) {
    this.value = value;
  }

  // 메서드는 Box.prototype에 생성됩니다.
  getValue() {
    return this.value;
  }
}

아래처럼 재할당이 가능하지만 하지 않는 것이 좋다.

function Box(value) {
  this.value = value;
}
Box.prototype.getValue = function () {
  return this.value;
};
const box = new Box(1);

// 인스턴스가 이미 생성된 후, `Box.prototype`을 변경합니다.
Box.prototype.getValue = function () {
  return this.value + 1;
};
box.getValue(); // 2

About 유재석
유재석

개발자 유재석 입니다. Web Developer.

Email : jaeseok9405@gmail.com

Website : https://github.com/yoo94