1. 프로토타입의 두 가지 의미
- 자바스크립트는 프로토타입 기반의 객체지향 프로그래밍
- 자바스크립트의 모든 객체는 자신의 부모인 프로토타입 객체를 가리키는 참조 링크 형태의 숨겨진 프로퍼티가 있다.
ECSAScript에서는 이러한 링크를 암묵적 프로토타입 링크(implicit prototype link)라고 부른다. = [[Prototype]]링크
- prototype 프로퍼티와 [[Prototype]] 링크를 구분해야 한다.
- 자바스크립트에서 모든 객체는 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 프로토타입 객체를 자신의 부모 객체로 설정하는 [[Prototype]]링크로 연결한다.
- 생성된 객체의 실제 부모 역할을 하는 건 생성자 자신이 아닌 생성자의 prototype 프로퍼티가 가리키는 프로토타입 객체이다.
∴ prototype : prototype perperty 객체 - 함수의 입장에서 자신과 링크된 프로토타입 객체
__proto__ : pretotype 객체 - 객체의 입장에서 자신의 부모 객체인 프로토타입 객체
2. 객체 리터럴 방식으로 생성된 객체의 프로토타입 체이닝
- 프로토타입 체이닝 : 자신의 부모역할을 하는 프로토타입 객체의 프로퍼티에 접근 가능하다.
var myObject = {
name : 'foo',
sayName : function(){
console.log('My Name is ' + this.name);
}
};
myObject.sayName();
console.log(myObject.hasOwnProperty('name'));
console.log(myObject.hasOwnProperty('nickName'));
myObject.sayNickName();
//출력 결과
//My Name is foo
//true
//false
//Uncaught TypeError: Object #<Object> has no method 'sayNickName'
3. 생성자 함수로 생성된 객체의 프로토타입 체이닝
- 자바스크립트에서 모든 객체는 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 객체를 자신의 프로토타입 객체(부모 객체)로 취급한다.
//Person() 생성자 함수
function Person(name, age, hobby){
this.name = name;
this.age = age;
this.hobby = hobby;
}
//foo 객체 생성
var foo = new Person('foo', 30, 'tennis');
//프로토타입 체이닝
console.log(foo.hasOwnProperty('name')); // true
//Person.prototype 객체 출력
console.dir(Person.prototype);
4. 프로토타입 체이닝의 종점
- 자바스크립트에서 Object.prototype 객체는 프로토타입 체이닝의 종점이다.
5. primitive 데이터 타입 확장
- primitive 타입 역시 프로토타입을 가지고 있다.
ex)Number.prototype, String.prototype, Array.prototype -> Obejct.prototype
- 자바스크립트는 표준 빌트인 프로토타입 객체에도 사용자가 직접 정의한 메서드들을 추가하는 것을 허용한다.
String.prototype.testMethod = function(){
console.log('This is the String.prototype.testMethod()');
};
var str = "this is test";
str.testMethod();
console.dir(String.prototype);
6. 프로토타입도 자바스크립트 객체다.
- 프로토타입 객체 역시 자바스크립트 객체이므로 일반 객체처럼 동적으로 프로퍼티를 추가/삭제 가능하다.
7. 프로토타입 메서드와 this 바인딩
- 메서드 호출 패턴에서 this는 그 메서드를 호출한 객체에 바인딩된다.
//Person() 생성자 함수
function Person(name){
this.name = name;
}
//getName() 프로토타입 메서드
Person.prototype.getName = function(){
return this.name;
}
//foo 객체 생성
var foo = new Person('foo');
console.log(foo.getName()); //this : foo, 출력값 : foo
//Person.prototype 객체에 name 프로퍼티 동적 추가
Person.prototype.name = 'person';
console.log(Person.prototype.getName()); //this : Person, 출력값 : person
8. 디폴트 프로토타입은 다른 객체로 변경이 가능하다.
- 생성자 함수의 프로토타입 객체가 변경되면, 변경된 시점 이후에 생성된 객체들은 병경된 프로토타입 객체로 [[Prototype]] 링크를 연결한다는 점을 기억해야 한다.
//Person() 생성자 함수
function Person(name){
this.name = name;
}
console.log(Person.prototype.constructor); //출력 결과 : Person(name)
//foo 객체 생성
var foo = new Person('foo');
console.log(foo.coutry); //출력 결과 : undefined
//디폴트 프로토타입 객체 변경
Person.prototype = {
country: 'korea',
};
console.log(Person.prototype.constructor); //출력 결과 : Object()
//bar 객체 생성
var bar = new Person('bar');
console.log(foo.country); //출력 결과 : undefined
console.log(bar.country); //출력 결과 : korea
console.log(foo.constructor); //출력 결과 : Person(name)
console.log(bar.constructor); //출력 결과 : Object()
9. 객체의 프로퍼티 읽기나 메서드를 실행할 때만 프로토타입 체이닝이 동작한다.
- 객체에 있는 특정 프로퍼티 값을 쓰려고 한다면 이때는 프로토타입 체이닝이 일어나지 않는다. -> 단순 추가된다.
'Language > Java Script' 카테고리의 다른 글
자바스크립트 스코프 체인 (0) | 2020.02.24 |
---|---|
자바스크립트 실행 컨텍스트 (0) | 2020.02.24 |
자바스크립트 함수 호출과 this (0) | 2020.02.23 |
자바스크립트 함수 형태 (0) | 2020.02.23 |
자바스크립트 함수 객체 (0) | 2020.02.23 |