Open KimHyeSeon opened 4 years ago
1. 프로토타입의 개념과 이해
var instance = new Constructor();
- 어떤 생성자 함수(Constructor)를 new 연산자와 함께 호출하면
- Constructor에서 정의된 내용을 바탕으로 새로운 인스턴스(instance)가 생성됨
- 이때 instance에는 __proto__라는 프로퍼티가 자동으로 부여되는데,
- 이 프로퍼티는 Constructor의 porototype이라는 프로퍼티를 참조함
var Person = function (name) {
this._name = name;
};
Person.prototype.getName = function () {
return this._name;
};
var suzi = new Person('Suzi');
suzi.__proto__tetName();
// undefined
// 에러가 발생하지 않았으므로 getName이 실행됨을 알 수 있음 (getName은 함수라는 것이 입증됨)
Person.prototype === suzi.proto // true. 둘은 서로 같은 객체를 바라 봄
- __proto__는 생략 가능한 프로퍼티
- __proto__를 생략하지 않으면 this는 suzi.__proto__를 가리키지만, 생략하면 suzi를 가리킴
suzi.proto.getName -> suzi(.proto).getName -> suzi.getName
- __proto__는 생략가능하기 때문에 **생성자 함수의 prototype에 어떤 메서드나 프로퍼티가 있다면 인스턴스에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근할 수 있게 됨**
**2. constructor 프로퍼티**
- prototype 객체와 __proto__ 객체 내부에는 constructor라는 프로퍼티가 있고, 생성자 함수(자기 자신)을 참조함
- 인스턴스로부터 그 원형이 무엇인지를 알 수 있는 수단
var arr = [1, 2]; Array.prototype.constructor === Array //true arr.proto.constructor === Array //true arr.constructor === Array //true
var arr2 = new arr.constructor(3, 4);
//인스턴스의 proto가 생성자 함수의 prototype 프로퍼티를 참조
//proto가 생력가능하기 때문에 constuctor에 접근할 수 있어 오류가 발생하지 않음
console.log(arr2); //[3, 4]
- constructor는 읽기 전용 속성이 부여된 예외적인 경우(기본형 리터럴 변수 - number, string, boolean)을 제외하고는 값을 바꿀 수 있음)
- constructor를 변경하더라도 참조대상이 변경될 뿐, 이미 만들어진 인스턴스의 원형이나 데이터 타입이 변하는 것은 아님
**다양한 constructor 접근 방법**
var Person = function(name) { this.name = name; }; var p1 = new Person('사람1'); // Person { name: "사람1" } true var p1Proto = Object.getPrototypeOf(p1); var p2 = new Person.prototype.constructor('사람2'); // Person { name: "사람2" } true var p3 = new p1Proto.constructor('사람3'); // Person { name: "사람3" } true var p4 = new p1.proto.constructor('사람4'); // Person { name: "사람4" } true var p5 = new p1.constructor('사람5'); // Person { name: "사람5" } true
[p1, p2, p3, p4, p5].forEach(function(p) { console.log(p, p instanceof Person); });
- 모두 동일한 대상을 가리킴
[Constructor] [instance].proto.constructor [instance].constructor object.getPrototypeOf([instance]).constructor [Constructor].prototype.constructor
- 모두 동일한 객체에 접근할 수 있음
[Constructor].prototype [instance].proto [instance] object.getProtytypeOf([instance])
06 프로토타입 자바스크립트는 프로토타입(prototype) 기반 언어 어떤 객체를 원형으로 삼고 이를 복제(참조)하여 상속과 비슷한 효과를 가짐
6-1 프로토타입의 개념 이해 6-1-1 constructor, prototype, instance
var instance = new Constructor();
1) Constructor라는 생성자 함수를 new 연산자와 함께 호출하면 2) Constructor에서 정의된 내용을 바탕으로 새로운 인스턴트 생성 3) instance에 proto라는 프로퍼티 자동 부여, Constructor의 prototype이라는 프로퍼티 참조
var Person = function (name) { //Person의 instance는 __proto__ 프로퍼티 통해 getName 호출 가능
this._name = name;
}
Person.prototype.getName = function() { //constructor prototype
return this._name;
};
var suzi = new Person('Suzi');
suzi.__proto__.getName();
//getName의 this는 suzi.__proto__인데, 객체 내부에 name 프로퍼티가 없어 undefined 반환
//그렇다면 name 프로퍼티를 추가해보자
var suzi = new Person('Suzi');
suzi.__proto__._name = 'Suzi__proto__';
suzi.__proto__.getName(); // Suzi__proto__
// __proto__를 빼면 this가 instance가 됨(생략 가능한 프로퍼티)
var suzi = new Person('Suzi');
suzi.getName(); //Suzi
var instance = new Constructor();를 정리하자면
// 출력 결과로 확인하기
var Constructor = function (name) {
this.name = name;
};
Constructor.prototype.method1 - function() {};
Constructor.prototype.property1 = 'constructor prototype property';
var instance = new Constructor('Instance'); console.dir(Constructor); //Constructor의 디렉터리 구조 출력 console.dir(instance); //instance의 디렉터리 구조 출력, constructor의 prototype과 동일한 내용 구성
**6-1-2 constructor 프로퍼티**
- 생성자 함수 프로퍼티인 prototype 객체 내부에는 constructor라는 프로퍼티가 있음
- 원래의 생성자 함수(자기 자신)을 참조하는 프로퍼티
- 인스턴스로부터 원형이 무엇인지 알 수 있는 수단이기 때문에 필요
- 기본형 리터럴 변수(number, string, boolean)를 제외하고 값을 바꿀 수 있지만 참조 대상이 변경될 뿐 인스턴트의 원형이나 데이터 타입이 변하는 것은 아님
// 다양한 constructor 접근 방법 // p1~p5까지 모두 Person의 인스턴스 var Person = function(name) { this.name = name; }; var p1 = new Person('사람1'); var p1Proto = Object.getPrototypeOf(p1); var p2 = new Person.prototype.constructor('사람2'); var p3 = new p1Proto.constructor('사람3'); var p4 = new p1.proto.constructor('사람4'); var p5 = new p1.constructor('사람5');
[p1, p2, p3, p4, p5].forEach(function(p) { console.log(p, p instanceof Person); });
var instance = new Constructor();
var Person = function (name) {
this._name = name;
};
Person,prototype.getName = function() {
return this._name;
}
var suzi = new Person('Suzi');
suzi._proto__.getName(); //undefind;
undefind 출력으로 getName이 함수라는 것을 알 수 있다.
ver suzi = new Person('Suzi', 28);
suzi.getName(); // Suzi
proto는 생략이 가능하다
생선자 함수의 prototype에 어떤 메서드나 프로퍼티가 있다면 인스턴스에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근할 수 있게 된다.
constructor 원래 생성자 함수(자기 자신)를 참조한다.
var arr = [1.2];
Array.prototype.constructor === Array //true
arr.__proto__.constructor === Array //true
arr.constructor === Array //true
var arr2 = new arr.constructor(3,4);
console.log(arr2); // [3,4]
인스턴스의 proto가 생성자 함수의 prototype 프로퍼티를 참조하며 proto 가 생략 가능하기 때문에 인스턴스에서 직접 constructor에 접근할 수 있는 수단이 생긴다.
new 연산자로 constructor를 호출하면 instance가 만들어 지는데, 이 instance의 생략 가능한 프로퍼티인 proto는 contsructor의 prototype을 참조한다
생성자 함수의 proto type에 어떤 메서드나 프로퍼티가 있다면 인스턴스 에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근할 수 있게 됩니다.
var Person = function (name) {
this._name = name;
};
person.prototype.getName = function() {
return this._name;
};
// person의 인스턴스는 __proto__ 프로퍼티를 통해 getName을 호출할수 있다.
var suzi = new Person('suzi');
suzi.__proto__.getName(); //undefined
Person.prototype === suzi.__proto__ //true
//contsructor 프로퍼티
var arr = [1,2];
array.prototype.constructor === Array //true
arr.__proto__.constructor === Array //true
arr.constructor === Array //true
var arr2 = new arr.constructor(3, 4);
console.log(arr2); //[3 ,4]
var instance = new Constructor();
1)어떤 생성자 함수(Constructor)를 new 연산자와 함께 호출하면 2)Constructor에서 정의된 내용을 바탕으로 새로운 인스턴트 생성 3)instance에 proto라는 프로퍼티 자동 부여되는데 이는 Constructor의 prototype이라는 프로퍼티를 참조
var Person = function (name) { //Person의 instance는 __proto__ 프로퍼티 통해 getName 호출 가능
this._name = name;
}
Person.prototype.getName = function() { //constructor prototype
return this._name;
};
var suzi = new Person('Suzi');
suzi.__proto__.getName(); // undefined
ㄴ getName 함수 내부에서의 this는 suzi가 아니라 suzi.proto라는 객체가 되는 것. 이 객체 내부에 name 프로퍼티가 없어 undefined 반환되는 것
var suzi = new Person('Suzi');
suzi.__proto__._name = 'Suzi__proto__';
suzi.__proto__.getName(); // Suzi__proto__
ㄴ name 프로퍼티가 있어 Suziproto가 잘 출력됨
var suzi = new Person('Suzi');
suzi.getName(); //Suzi
ㄴproto를 빼면 this는 instance가 되는게 맞지만 이는 생략 가능함
생성자 함수의 prototype에 어떤 메서드나 프로퍼티가 있다면 인스턴스에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근할 수 있음!!
다양한 constructor 접근 방법
var Person = function(name) {
this.name = name;
};
var p1 = new Person('사람1'); // p1부터 p5까지 모두 Person의 인스턴스
var p1Proto = Object.getPrototypeOf(p1);
var p2 = new Person.prototype.constructor('사람2');
var p3 = new p1Proto.constructor('사람3');
var p4 = new p1.__proto__.constructor('사람4');
var p5 = new p1.constructor('사람5');
[p1, p2, p3, p4, p5].forEach(function(p) {
console.log(p, p instanceof Person);
});
study 완료 후 체크 부탁드립니다.