[Javascript] Prototype

JungChihoon·2020년 2월 3일
0

Javascript

목록 보기
3/6

1. 프로토 타입 객체

자바스크립트의 객체 생성방법

자바스크립트의 모든 객체는 자신의 부모역할을 담당하는 객체와 연결되어 있다.
그리고 이것은 부모객체의 프로퍼티 또는 메소드를 상속받아 사용할 수 있게 한다.
이러한 부모객체를 Prototype객체 또는 prototype이라고 한다.

prototype객체는 생성자 함수에 의해 생성된 공유프로퍼티를 제공하기 위해 사용한다.
자바스크립트의 모든 객체는 [prototype]이라는 인터널 슬롯을 가진다.
[[prototype]]의 값은 null 또는 객체이며 상속을 구현하는 데 사용된다. [[prototype]]객체의 데이터 프로퍼티는 get 액세스를ㄹ 위해 상속되어 자식객체의 프로퍼티처럼 사용할 수 있다. 하지만 set액세스는 허용되지 않는다.

student 객체는 proto_프로퍼티로 자신의 부모객체 (프로토타입 객체)인 Object.prototype을 가리키고 있다.

var student = {
    name : 'Lee',
    score : 90
}
console.log(student.__proto__ === Object.prototype)      // true```

### 2. [[prototype]] 과 prototype 프로퍼티의 비교
모든 객체는 자신의 프로토타입 객체를 가리키는 [[Prototype]] 인터널 슬롯(internal slot) 을 갖으며 상속을 위해 사용된다.
함수도 객체이므로 [[Prototype]] 인터널 슬롯을 갖는다. 그런데 함수 객체는 일반 객체와는 달리 prototype 프로퍼티도 소유하게 된다.
```javascript 
function Person(name) {
    this.name = name;
}

var foo = new Person('Lee');

console.dir(Person);      // prototype 프로퍼티가 있다.
console.dif(Person);      // prototype 프로퍼티가 없다.```

- [[prototype]]
- 함수를 포함함 모든객체가 가지고 있는 인터넷 슬롯
- 객체의 입장에서 자신의 부모 역할을 하는 프로토타입 객체을 가리킴, 함수객체의 경우 Function.prototype을 가리킴
- prototype 프로퍼티
- **함수 객체만 가지고 있는 프로퍼티**이다.
- 함수 객체가 생성자로 사용될 때 이 함수를 통해 생성될 객체의 부모역할을 하는 객체(프로토타입 객체)를 가리킨다.

### 3. constructor 프로퍼티
- 프로토타입 객체는 constructor 프로퍼티를 갖는다.
- constructor 프로퍼티는 객체의 입장에서 자신을 생성한 객체를 가리킨다.
```javascript
//객체
var student = {
 name : 'Lee'
} 

// 생성자 함수를 이용해 만든 객체
function Person(name){
 this.name = name;
}

var aPerson = new Person('Kim');

// 확인
console.dir(student.constructor) // Object 생성자 함수 
console.dir(aPerson.constructor) // Person 생성자 함수```

### 4. Prototype Chain
자바스크립트는 특정객체의 프로퍼티나 메소드에 접근하려 할 때 해당 객체에 접근하려는 프로퍼티 또는 메소드가 없다면 [[prorotype]]이 가리키는 링크를 따라 자신의 부모역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례대로 검색한다. 이 것을 **프로토 체인**이라 한다.
```javascript
function Car(model){
    this.model = model;
}
Car.prototype.color = 'red';

var car1 = new Car('sonata');
car1.style = 'sports';

console.log(car1)              // Car {model: "sonata", style: "sports"}

console.log(car1.style);       // 'style'  (car1 객체의 프로퍼티)
console.log(car1.color);       //  'red'   (car1의 상위객체 car1.__proto__.color 프로퍼티)```

### 객체 생성 방법
- 객체 리터럴
- 생성자 함수
- Obect() 생성자 함수

```javascript
// 객체 리터럴, Object생성자 함수(객체리터럴로 생성하면 엔진 내부적으로 Object생성자 함수로 객체만듬)
var literal = {name : Chanho};

//생성자 함수
function Literal(name) {
    this.name = name;
}

var makeName = new Literal('Jisung');```

### 생성자함수로 생성된 객체의 프로토타입체인
생성자 함수로 객체를 생성하기 위해서는 우선 생성자 함수를 정의하여야 한다.

**함수를 정의하는 방식**
- 함수표현식(Function declaration)
- 함수선언식(Function expression)
- Function() 생성자 함수

3가지 함수 정의 방식은 결국 Function() 생성자 함수를 통해 함수 객체를 생성한다, 따라서 어떠한 방식으로 함수 객체를 생성하여도 **모든 함수 객체의 prototype 객체는 Function.prototype**이다. 
생성자 함수도 함수 객체이므로 생성자 함수의 prototype 객체는 Function.prototype이다.

### 프로토타입 객체의 확장
프로토타입 객체도 객체이므로 일반 객체와 같이 프로퍼티를 추가/삭제할 수 있다. 그리고 이렇게 추가/삭제된 프로퍼티는 즉시프로토타입 체인에 반영된다.

```javascript
function Person(name) {
  this.name = name;
}

var foo = new Person('Lee');

Person.prototype.sayHello = function(){
  console.log('Hi! my name is ' + this.name);
};

foo.sayHello();                          // Hi! my name is Lee```

### 프로토타입 객체의 변경
객체를 생성할 때 프로토타입은 결정된다. **결정된 프로토타입 객체는 다른 임의의 객체로 변경할 수 있다.** 이것은 부모 객체인 프로토타입을 동적으로 변경할 수 있다는 것을 의미한다. 이러한 특징을 활용하여 객체의 상속을 구현할 수 있다.

!!!!!!!!!!!!이때 주의할 것은 프로토타입 객체를 변경하면!!!!!!!!!!!!
- **프로토타입 객체 변경 시점 이전에 생성된 객체**
- 기존 프로토타입 객체를 [[Prototype]]에 바인딩한다.
- **프로토타입 객체 변경 시점 이후에 생성된 객체**
- 변경된 프로토타입 객체를 [[Prototype]]에 바인딩한다.

```javascript
function Person(name) {
  this.name = name;
}

var foo = new Person('Lee');

// 프로토타입 객체의 변경
Person.prototype = { gender: 'male' };

var bar = new Person('Kim');

console.log(foo.gender); // undefined
console.log(bar.gender); // 'male'

console.log(foo.constructor); //  ① Person(name)
console.log(bar.constructor); //  ② Object()```
profile
주니어 개발자

0개의 댓글