자바스크립트의 프로토타입

baegyeong·2024년 8월 11일

Java Script

목록 보기
7/9
post-thumbnail

코어자바스크립트 ch6. 프로토타입를 읽고 정리한 내용입니다.


프로토타입 이해하기


var Person = function (name) {
	this._name = name;
};
Person.prototype.getName = function() {
	return this._name;
};

var suzi = new Person('Suzi');
suzi.__proto__.getName(); // undefined

Person 인스턴스의 __proto__는 Person의 prototype을 상속한다고 한다.

그렇다면 suzi.__proto__.getName()은 ‘Suzi’를 출력 해야 하는거 아닌가?

그런데 왜 undefined가 뜰까?

suzi.__proto__의 객체 내부에는 name 프로퍼티가 없기 때문이라고 한다.

즉, __proto__는 Constructor의 prototype은 참조한다.

하지만 인스턴스가 생성한 name 프로퍼티는 알지 못한다. 따라서 undefined가 할당된다.

하지만, suzi.getName()은 가능하다.

suzi는 name 프로퍼티를 알고 있기 때문이다.

프로토타입 상속


생성자 함수의 상속

function Member(name) {
	this.name = name;
	this.sayHello = function() {
		console.log(`hi, ${name}`);
	}
}

const member1 = new Member('철수')
const member2 = new Member('영희')
  • 생성자 함수를 통해 객체를 생성한다면, 인스턴스는 메서드를 중복 소유한다.
  • 매번 새 인스턴스를 만들 때마다 내용이 동일한 메서드가 중복 소유되므로, 한 메서드를 모든 인스턴스가 공유하는 형태로 만들어보자.
function Member(name) {
	this.name = name;
}

Member.prototype.sayHello = function () {
	console.log(`hi, ${name}`);
}

const member1 = new Member('철수')
const member2 = new Member('영희')

console.log(member1.sayHello === member2.sayHello) // true
  • 프로토타입 상속으로 모든 인스턴스가 동일한 메서드를 바라보게 할 수 있다.
  • 프로토타입의 특성을 이용한다면, 객체가 여러 메서드를 가질 경우 이들을 프로토타입에 정의하여 모든 인스턴스가 공유하도록 할 수 있다.

프로토타입으로 싱글톤 패턴을 구현할 수 있겠다.

싱글톤 패턴은 인스턴스가 오직 하나만 존재하도록 보장하는 설계 패턴이다.

생성자 함수를 통해 새로운 인스턴스를 생성하더라도 기존에 생성했던 단 하나의 인스턴스만 바라본다.

  • 위의 상속 예시에서도, 모든 인스턴스가 동일한 메서드를 바라보게 구현했다. 그렇다면 생성되는 인스턴스가 모두 동일한 인스턴스를 바라보게도 구현이 가능하지 않을까?
let instance = null;

function Singleton(data = 'Initial data') {
  if (instance) {
    return instance;
  }

  this.data = data;
  instance = this;
}

Singleton.prototype.getData = function() {
  return this.data;
}

Singleton.prototype.setData = function(data) {
  this.data = data;
}
  • instance를 외부에서 접근하지 못하도록 한다면 …
    • 즉시 실행함수 내부에 instance 변수를 선언하여 외부에서 직접 접근을 막는다.

      const Singleton = (function(){
          let instance;
      
          function Constructor() {
              // 생성자 로직
          }
      
          Constructor.prototype.someMethod = function() {
              console.log('This is a method shared by all instances');
          };
      
          return {
              getInstance: function() {
                  if (!instance) {
                      instance = new Constructor();
                  }
                  return instance;
              }
          };
      })();
      
      let obj1 = Singleton.getInstance();
      let obj2 = Singleton.getInstance();
      
      console.log(obj1 === obj2); // true
      obj1.someMethod(); // "This is a method shared by all instances"

오버라이딩과 섀도잉

  • 오버라이딩: 상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의하여 사용하는 방식
  • 섀도잉: 상속 관계에 의해 프로퍼티가 가려지는 현상
  • 오버로딩: 함수의 이름은 동일하지만, 매개변수의 타입 또는 개수가 다른 메서드를 구현하고 매개변수에 의해 메서드를 구별하여 호출하는 방식

메서드를 오버라이딩 한 후 원본 메서드에 접근하기

var Person = function (name) {
  this.name = name;
};

Person.prototype.getName = function () {
  return this.name;
};

var iu = new Person("지금");
iu.getName = function () {
  return "바로 " + this.name;
};
console.log(iu.getName());
  • 자신의 프로퍼티를 검색한 후 없으면 그 다음 가까운 대상인 __proto__를 검색하는 순서로 진행된다.
  • 의도적으로 __proto__를 통해 부모의 프로퍼티를 검색할 수 있다.

0개의 댓글