[Section 2] 프로토 타입

정호·2023년 3월 16일
0

코드스테이츠

목록 보기
22/49
post-custom-banner

프로토타입이란?

자바스크립트는 프로토타입기반 언어이다. 프로토타입은 원형 객체를 의미하며 자바스크립트에서 객체를 상속하기 위해 사용하는 방식이다.
모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 프로토타입 객체를 가진다는 의미이기도 하다.

--> 상속되는 속성과 메소드들은 각 객체가 아니라 객체의 생성자의 prototype이라는 속성에 정의되어 있는것이다.

프로토타입 체인

프로토타입 객체 또한 상위 프로토타입 객체들로부터 메소드 와 속성을 상속 받고 그 상위 객체들도 마찬가지이다. 이처럼 다른 객체에 정의된 메소드와 속성을 한객체에서 사용할 수 있는것이 프로토타입 체인이다.

정확히 말하자면 상속되는 속성과 메소드들은 각 객체가 아니라 객체의 생성자의 prototype이라는 속성에 정의되어 있습니다.
-출처 MDN

JavaScript에서는 객체 인스턴스와 프로토타입 간에 연결(많은 브라우저들이 생성자의 prototype 속성에서 파생된 __proto__ 속성으로 객체 인스턴스에 구현하고 있습니다.)이 구성되며 이 연결을 따라 프로토타입 체인을 타고 올라가며 속성과 메소드를 탐색합니다.


예시

Person()생성자

function Person(first, last, age, gender, interests) {

  // 속성과 메소드 정의
  this.first = first;
  this.last = last;
  
  // 인스턴스 생성
var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
}

person1의 프로토타입 객체인 Person()에 정의된 멤버들 name, age, ...을 볼 수 있습니다. — watch, valueOf처럼 Person()의 프로토타입 객체인 Object에 정의된 다른 멤버들도 볼 수 있습니다. 이는 프로토타입 체인의 동작을 뜻합니다.

Object 탐색

위에서 person1Object에 정의된 메소드를 가져오는 방식
ex)

person1.valueOf()
  1. 브라우저는 person1 객체가 valueOf() 메소드를 가지고 있는지 체크합니다. --> 없음
  2. person1의 프로토타입 객체(Person() 생성자의 프로토타입)에 valueOf() 메소드가 있는지 체크합니다.--> 없음
  3. Person() 생성자의 프로토타입 객체의 프로토타입 객체(Object() 생성자의 프로토타입)가 valueOf() 메소드를 가지고 있는지 체크합니다. --> 존재함->호출

따라서 Object.prototype.watch(), Object.prototype.valueOf()등 생성자를 통해 새로 생성되는 인스턴스는 물론 Object.prototype을 상속 받는 객체라면 어떤 객체에서든지 접근할 수 있습니다.


생성자 속성

모든 생성자 함수는 constructor 속성을 지닌 객체를 프로토타입 객체로 가지고 있습니다.
constructor 속성은 원본 생성자 함수 자신을 가리키고 있습니다.


프로토타입 상속

function Person(first, last, age, gender, interests) {
  this.name = {
    first,
    last
  };
  this.age = age;
  this.gender = gender;
  this.interests = interests;
};

Person.prototype.greeting = function() {
  alert('Hi! I\'m ' + this.name.first + '.');
};

Person상속받는 Teacher클래스 만들기

function Teacher(first, last, age, gender, interests, subject) {
  Person.call(this, first, last, age, gender, interests);

  this.subject = subject;
}

subject 추가됨
call()함수: 첫번재 매개변수는 다른 곳에서 정의된 함수를 현재 컨텍스트에서 실행하도록 합니다. this로 전달하고 나머지는 실제 함수 실행에 필요한 인자들을 전달합니다.

Teacher()의 생성자는 Person()을 상속받았으므로 같은 매개변수들이 필요합니다. 따라서 동일한 매개변수들을 call()의 인자로 전달하여 실행합니다.

function Teacher(first, last, age, gender, interests, subject) {
  this.name = {
    first,
    last
  };
  this.age = age;
  this.gender = gender;
  this.interests = interests;
  this.subject = subject;
}

다음과 같은 의미 (Person을 상속받은것이 아닌 그냥 동일한 인자를 정의한것)


class Human {
  constructor(name, age) {
    this.name = name;	//class내의 constructor객체의 this는 인스턴스를 가리킴 
    this.age = age;
  }

  sleep() {
    console.log(`${this.name}은 잠에 들었습니다`);
  }
}

let kimcoding = new Human('김코딩', 30); // 인스턴스 객체의 이름은 김코딩 age는 30

// 실습해보세요
Human.prototype.constructor === Human; 
Human.prototype === kimcoding.__proto__; 
Human.prototype.sleep === kimcoding.sleep

Human클래스 객체생성
sleep()사용할 수 있음 --> 프로토타입체이닝

같은 주소값담겨있기 때문에 sleep()사용 가능

같은 주소값담겨있기 때문에 sleep()사용 가능

Human.prototype === kimcoding.__proto__
Human.prototype.constuctor === Human

Human 자체에 constructor가 담겨있기 때문에 Human.prototype은 저장소고
__proto__는 저장소의 주소가 담겨있는 주소값이다.

profile
열심히 기록할 예정🙃
post-custom-banner

0개의 댓글