JS-prototype

topics 200-프론트개발
types 이론 학습
tags #javascript #prototype #oop

prototype

프로토타입 상속

자바스크립트의 모든 객체는 <a href="/pages/Prototype.html" class="wiki-link">Prototype</a>이라는 숨김 프로퍼티를 가지고 있다.

그리고 이 참조 대상을 prototype 이라고 부른다.

이것은 상속 받아 사용할 수 있고 해당 객체에서 해당 프로퍼티가 없을 시 프로토타입에서 해당 프로퍼티를 찾게된다.

prototype vs **Prototype vs **proto

let A = { name: "A" };
let B = { name: "B" };
B.__proto__ = A;

console.log(B.__proto__);//{name: "}
console.log(A.__proto__);//{}

Untitled

<a href="/pages/Prototype.html" class="wiki-link">Prototype</a> : 숨김 프로퍼티, 객체를 참조하거나 null값을 갖는다.

prototype: <a href="/pages/Prototype.html" class="wiki-link">Prototype</a> 숨김 프로퍼티가 참조하는 대상이다.

__proto__ : Prototype의 getter setter , null이나 객체만 가능, 다른자료형 무시

함수 객체에는 prototype이라는 일반프로퍼티도 있지만 이후에 다룰 예정.

prototype 체인

let A = { name: "A", age: 30, id: "25532" };
let B = { name: "B", age: 26 };
let C = { name: "C" };

B.__proto__ = A;
C.__proto__ = B;

console.log(C.name);//C
console.log(C.age);//26
console.log(C.id);//25532

자신에게 해당 프로퍼티가 있다면 그 값을 리턴하고,

참조된 prototype을 순서대로 확인하여 가까운 프로퍼티값을 리턴한다.

prototype은 읽기만 가능하다.

prototype의 값은 변경이 불가능하다.

값을 변경할려면 해당 객체에서 변경을 해야한다.

let user = {
  name: "John",
  surname: "Smith",
  fullName: "John Smith"
};

let admin = {
  __proto__: user,
  isAdmin: true
};

console.log(admin.fullName); // John Smith (*)

admin.fullName = "Alice Cooper";

console.log(admin.fullName);//Alice Cooper"
console.log(user.fullName);//John Smith

이렇게 프로퍼티를 할당할려고하면 prototype에 있는 프로퍼티임에도 불구하고 admin객체에 해당 프로퍼티가 추가된다.

let user = {
  name: "John",
  surname: "Smith",

  set fullName(value) {
    [this.name, this.surname] = value.split(" ");
  },

  get fullName() {
    return `${this.name} ${this.surname}`;
  }
};

let admin = {
  __proto__: user,
  isAdmin: true
};

console.log(admin.fullName); // John Smith (*)

// setter 함수가 실행됩니다!
admin.fullName = "Alice Cooper"; // (**)

console.log(admin.fullName); // Alice Cooper, setter에 의해 추가된 admin의 프로퍼티(name, surname)에서 값을 가져옴
console.log(user.fullName); // John Smith, 본래 user에 있었던 프로퍼티 값

프로퍼티의 메서드는 실행되나 user의 프로퍼티 값은 그대로고 admin에 값이 추가된다.

내장 메서드와 반복문

키-값을 순회하는 대부분이 메서드는 상속프로퍼티를 제외하고 작동한다

  • Object.keys
  • Object.values

for … in 반복문: 상속프로퍼티도 순회한다.

함수의 prototype프로퍼티

함수를 이용하여 객체를 만들 수 있다. 이러한 생성자 함수에는 prototype이라는 일반 프로퍼티가있다. prototype프로퍼티에 할당된 객체는 새로운 객체가 생성될 시의 프로퍼티가 된다.

let animal = {
  eats: true
};

function Rabbit(name) {
  this.name = name;
}

Rabbit.prototype = animal;

let rabbit = new Rabbit("흰 토끼");
//rabbit의 <a href="/pages/prototype.html" class="wiki-link">prototype</a> : aniaml

console.log( rabbit.eats ); // true
console.log(rabbit.__proto__);// {eats: true}

default prototype(프로퍼티) & constructor

모든 함수는 prototype 프로퍼티를 갖는다.

아무 것도 지정하지 않았을시 갖는 default prototype은 constructor하나만 있는 객체를 가리키고

이 constructor의 값은 이 값의 생성자 함수를 가리킨다.

생성자 함수를 모를 때 이를 이용하여 생성자 함수를 찾을 수 있다.

function Rabbit() {}
let rabbit = new Rabbit()
alert( Rabbit.prototype.constructor === Rabbit ); // true
alert(rabbit.constructor == Rabbit);//rabbit은 prototype프로퍼티는 없음

하지만 prototype에 다른 객체를 할당하면 이 default프로퍼티는 없어지게 된다

let animal = {
  eats: true
};

function Rabbit(name) {
  this.name = name;
}

Rabbit.prototype=animal;
let rabbit = new Rabbit()
console.log(Rabbit.prototype.constructor === Rabbit) //false
console.log(rabbit.constructor == Rabbit) //Object(){}

그대로 constructor 를 유지할려면 prototype 객체에 프로퍼티를 추가하면된다..

내장 객체의 prototype