[JS] prototype

Im-possible·2025년 4월 23일

프로토타입

- 모든 함수가 기본으로 가지고 있는 속성으로 빈 객체로 생성된다
- prototype에 추가한 속성은 해당 함수가 생성자로 사용될 때 생성된 인스턴스 내부 링크로 참조되어 사용된다
- 생성자 함수를 통해 생성되는 인스턴스의 메서드를 정의하는 역할
const Score = function(kor, eng){
  this.kor = kor;
  this.eng = eng;
  // 생성자 내부에 메서드 정의
  this.sum = function(){
    return this.kor + this.eng;
  }
};
// 프로토타입에 메서드 정의 (함수 외부에 정의)
Score.prototype.avg = function(){ 
  return this.sum() / 2;
}

// 생성자 함수로 객체 생성
const s1 = new Score(90, 80);

생성자 함수 내부에 메서드를 정의할 경우

  • 새로운 객체를 생성할 때 마다 sum 함수가 새로 생성되고 -> 각 객체마다 메서드 복사
  • 메모리 관리에 비효율적

프로토타입에 메서드를 정의하는 경우

  • 모든 인스턴스를 공유하기 때문에 같은 함수를 사용한다. -> 동일한 메서드 사용
  • 메모리 관리에 효율적

프로토타입 체인

- 모든 함수는 프로토타입 객체를 갖고있다.
- 모든 객체는 해당 객체를 만드는데 사용된 생성자를 참조하는 constructor 속성의 객체가 정의되어 있다.
- constructor 속성은 객체 생성 시 자동으로 연결되며, 객체와 생성자 함수 사이의 참조 링크를 제공한다.
- 프로퍼티는 해당 객체에서 먼저 찾고 실패했을 때 프로토타입을 확인한다

1. 객체에 해당 프로퍼티가 있으면 사용
2. 객체에 연결된 프로토타입에 해당 프로퍼티가 있으면 사용
3. 프로토타입에도 해당 프로퍼티가 없으면 연결된 프로토타입에서 찾는다
... 찾을 때 까지 반복
4. 최상위 프로토타입인 Object까지 찾아서 해당 프로퍼티가 없으면 그 값은 undefined

위 코드의 프로토타입 체인

1. s1 객체(Score 함수)에서 avg 메서드 탐색
2. s1의 프로토타입(Score.prototype)에서 avg 메서드 탐색
3. 찾으면 해당 메서드 실행

프로토타입 체인의 마지막 객체

- 모든 객체의 프로토타입 체인 마지막 객체는 Object이다.
- Array, String, Number, Data, Function 등 내장 객체와 Score, Ping 등 사용자가 정의한 객체는 모두 프로토타입 체인에 의해 자동으로 Object의 메서드를 사용할 수 있다.

내장된 생성자 함수의 프로토타입

- Object, Array, Function, Data 등
- 내장된 생성자 함수도 프로토타입 속성이 있으므로 해당 함수에 속성, 메서드를 추가해서 네이티브 객체의 기능을 확장할 수 있다.

typeof

- 객체의 타입을 반환
- 기본 데이터 타입과 함수를 제외한 모든 인스턴스에 대해 object로 반환

instanceof

- 객체가 지정한 생성자를 통해 생성되었는지 판단
- 직접 생성된 생성자가 아니더라도 프로토타입 체인에 있는 생성자라면 true 반환

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

- 하위 생성자(자식)의 프로토타입을 상위 생성자(부모)의 객체로 지정
- 상위 생성자의 모든 속성을 물려받아 사용할 수 있음
- Object.create(): 지정한 prototype 객체를 참조하는 인스턴스 생성
// HighSchool
function HighSchool(kor, eng){
  this.kor = kor;
  this.eng = eng;
}

HighSchool.prototype.sum = function(){
  return this.kor + this.eng;
}

HighSchool.prototype.avg = function(){
  return Math.round(this.sum() / 2);
}


const s1 = new HighSchool(100, 91);
console.log(s1.sum());
console.log(s1.avg());

// College
function College(kor, eng){
  HighSchool.call(this, kor, eng)
}

// 상속 함수 불러오기
inherite(HighSchool, College)

// Child가 Parent를 상속받는다
function inherite(Parent, Child){
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child; 
}


College.prototype.grade = function(){
  let level = 'F';
  const avg = this.avg();
  if(avg >= 90){
    level = 'A';
  }else if(avg >= 80){
    level = 'B';
  }else if(avg >= 70){
    level = 'C';
  }else if(avg >= 60){
    level = 'D';
  }
  return level;
}

const c1 = new College(80, 99);
console.log(c1.sum());
console.log(c1.avg());
console.log(c1.grade());

console.log(College.prototype)

생성자 함수와 객체를 생성하고 prototype의 복잡함을 해결하기 위해 ES6에서 추가된 class 키워드를 사용하면 상속을 더 쉽게 사용할 수 있습니다.

0개의 댓글