tteokbokki-master 2024. 4. 29. 16:25

시작

let user = {
	name : 'Lee',
	age: 25
}

console.log(user.name); // Lee
console.log(user.hasOwnProperty('email')); // false

user라는 객체 변수에는 name과 age라는 속성만 있는데, hasOwnProperty라는 메서드를 사용해도 에러가 나오지 않는다. 이 메서드는 어디서 온 것일까?

 

 

 

 

모든 객체는 위와 같이 global Object prototype을 가진다. 이 prototype안에 hasOwnPropert 메서드가 존재하기에 에러가 나오지 않고 결괏값이 반환되었던 것이다.

 

 

 

 

 

Prototype이란?

 

프로토타입은 자바스크립트 객체가 다른 객체로부터 메서드와 속성을 상속받는 메커니즘을 말한다. 이를 프로토타입 체인이라고도 한다. 위의 코드에서 prototype object 안에 있는 hasOwnProperty를 상속받아서 사용하고 있다. 이렇게 하므로 인해 더 적은 메모리를 사용할 수 있고, 코드도 재활용할 수 있다.

 

 

 

 

 

예제

function Person(name, email, birthday){
  this.name = name;
  this.email = email;
  this.birthday = new Date(birthday);
  this.calculateAge = function(){
    const diff = Date.now() - this.birthday.getTime();
    const ageDate = new Date(diff);
    return Math.abs(ageDate.getUTCFullYear() - 1970);
  }
}

const lee = new Person('lee', 'lee@example.com', '01-01-00');
const jin = new Person('jin', 'jin@example.com', '01-01-01');

다음과 같이 생성자 함수와 이를 통해 생성된 객체 인스턴스 lee, jin이 있다. 

 

 

 

 

lee, jin의 name, email, birthday 속성은 다르지만 calculateAge 메서드는 같은 것을 알 수 있다. 

 

prototype을 사용하는 이유는 더 적은 메모리 사용과 재사용 때문이다. 즉 각각의 인스턴스에 같은 메서드가 따로 존재하기보다는, 공통된 prototype에 메서드가 들어있는 것이 더 효율적이다.

 

공통된 calculateAge 메서드를 prototype으로 옮겨주자.

 

 

 

 

function Person(name, email, birthday){
  this.name = name;
  this.email = email;
  this.birthday = new Date(birthday);
}

Person.prototype.calculateAge = function(){
  const diff = Date.now() - this.birthday.getTime();
  const ageDate = new Date(diff);
  return Math.abs(ageDate.getUTCFullYear() - 1970);
}

const lee = new Person('lee', 'lee@example.com', '01-01-00');
const jin = new Person('jin', 'jin@example.com', '01-01-01');

이제는 각 객체 인스턴스에 calculateAge 메서드가 사라지고, prototype에 존재하는 것을 확인할 수 있다. 이렇게 재사용되는 부분은 prototype에 넣어서 더 효율적으로 사용할 수 있다.

 

 

 

 

 

또 다른 방법 Object.create()

지정된 프로토타입 객체 및 속성을 갖는 새 객체를 만든다.

function Person(name, email, birthday) {
  let person = Object.create(personPrototype);
  person.name = name;
  person.email = email;
  person.birthday = new Date(birthday);
  return person;
}

const personPrototype = {
  calculateAge() {
    const diff = Date.now() - this.birthday.getTime();
    const ageDate = new Date(diff);
    return Math.abs(ageDate.getUTCFullYear() - 1970);
  }
}
const lee = new Person('lee', 'lee@example.com', '01-01-00');
const jin = new Person('jin', 'jin@example.com', '01-01-01');

personPrototype이라는 프로토타입 객체를 가지는 새 객체를 만들고 그것을 반환하는 것이다. 마찬가지로 prototype안에 personPrototype가 속하게 된다.

 

 

 

 

 

prototype chain 

어떤 메서드나 프로퍼티를 사용할 때, 계속 올라가면서 해당 메서드나 프로퍼티를 찾아 올라간다.