JavaScript

[JavaScript] 함수 프로퍼티 prototype과 객체 [[Prototype]]

FRDYtheme 2022. 12. 15. 23:03

생성자 함수를 사용해 생성한 객체는 생성자 함수의 prototype을 사용해 [[Prototype]]을 설정한다.

<script>
  function Food(name) {
    this.name = name;
  }
  console.log(Object.getPrototypeOf(new Food)) // {constructor: ƒ}
</script>

생성자 함수의 prototype = constructor(default)

모든 함수는 prototype이라는 일반 프로퍼티를 기본적으로 갖고 있으며 이 값의 디폴트는 'constructor'로 함수 자신이다.

 

여기서, 생성자 함수로 객체를 생성하면 그 객체가 참조하는 대상을 나타내는 [[Prototype]]은

함수의 prototype = constructor가 된다.

 

근데 생성자 함수의 일반 프로퍼티인 prototype에 다른 객체를 복사한 뒤에 객체를 생성하면 그 객체는 어떤 대상을 [[Prototype]]으로 참조할까?

 

<script>
  let somebody = {
    intro: function () {
      console.log("저는 생성자 함수의 prototype이 될 거에요.");
    }, // 이 함수의 prototype 프로퍼티는 constructor (디폴트)
  };

  function Boy(name, age) {
    this.name = name;
    this.age = age;
  }

  console.log(Object.getPrototypeOf(new Boy())); // {constructor: ƒ}

  let newArr = new Boy("기찬", "30살");

  console.log(Object.getPrototypeOf(newArr)); // {constructor: ƒ}
  // 생성자 함수 Boy의 prototype인 constructor가 객체 newArr의 [[Prototype]]

  alert(newArr.name); // 기찬

  // 생성자 함수 Boy의 prototype을 위에 만들어 둔 객체 somebody로 바꾸고
  // 새로운 객체를 만들어서 확인.

  Boy.prototype = somebody;
  console.log(Object.getPrototypeOf(new Boy())); // {intro: ƒ}

  let newArr2 = new Boy("귀찮", "20살");
  alert(newArr2.name); // 귀찮
  newArr2.intro(); // 저는 생성자 함수의 prototype이 될 거에요.

  //  newArr2는 생성자 함수 Boy의 prototype이 된 somebody가 [[Protootype]]이며
  //	객체 내 함수를 상속받아 사용할 수 있다
</script>

 

생성자 함수의 prototype 프로퍼티는 함수를 호출할 때만 (new F) 사용되기 때문에 호출 후 prototype을 변경하면 전과 후에 만들어지는 객체는 각자 다른 [[Prototype]]을 참조한다.

 

constructor는 객체가 어떤 생성자로부터 생성됐는지 알고싶을 때 유용하지만 constructor가 항상 있는 것은 아니다.단지 모든 함수는 prototype이라는 프로퍼티를 갖고 있으며 이 값은 기본적으로 constructor지만 constructor가 아닐 수도 있다.

 

혹 생성자 함수를 사용해서 객체를 만들다가 constructor를 살리고 싶으면 새로 만들어주면 된다.

 

생성자함수{

  prototype: constructor

}

 

좀 더 안전하게 constructor도 활용하고 생성자 함수의 prototype을 제어해서 객체의 [[Prototype]]을 조정하고 싶다면

prototype의 값을 바꾸는 대신 추가해서 참조하는 방법도 있다.

<script>
  Boy.prototype.boy2 = somebody;

  let newArr2 = new Boy;
  
  newArr2.boy2.intro(); // 저는 생성자 함수의 prototype이 될 거에요.

  // 생성자 함수 Boy의 prototype인 constructor 대신 boy2를 추가해서 somebody를 대입하고
  // newArr2는 boy2를 [[Prototype]]으로 참조해서 접근할 수 있다.
</script>