prototype:원형
이걸 통해 js는 상속 개념 제공
함수는 객체다.
생성자로 사용될 함수도 객체다.
객체는 프로퍼티를 가질 수 있는데,
prototype이라는 프로퍼티는 그 용도가 약속되어 있는 특수한 프로퍼티다.
prototype에 저장된 속성들은 생성자를 통해 객체가 만들어질 때 그 객체에 연결된다.
function Ultra() {}
Ultra.prototype.ultraProp = true;
function
역시 생활코딩이 진리다.
설명해 주신 코드가 이해가 잘되어 사용하자면,
function Person(name, first, second){
this.name = name;
this.first = first;
this.second = second;
}
var kim = new Person('kim',10,20);
var lee = new Person('lee',10,10);
console.log(kim.sum());
위의 코드가 선언된 순간 분홍색과(Person) 초록색(Person's prototype) 2개가 만들어진다.
그리고 각자가 가지고 있는 prototype이라는 프로퍼티와 constructor라는 프로퍼티로 상호 연관 되어 있다고 한다.
주황색을 보면 각 kim과 lee의 객체가 만들어진 것이다.
만들어지며 자동으로 __proto__가 만들어진다.
__proto__가 가리키고 있는것은 그림과 같이 Person의 prototype객체이다.
Person.prototype과 kim.__proto__는 똑같이 초록색을 가리킨다.
너무 깊게 들어가는거지만 초록색도 __proto__를 가지고 있다.
function Person(name, first, second, third) {
this.name = name;
this.first = first;
this.second = second;
// this.sum = function() { // 생성자 안에서 메소드를 갖는 단점. 객체가 만들어질때마다 실행되야함.
// return this.first + this.second;
// }
}
// 생성자함수에다가 메소드를 정의하지 않고 따로 구분하나면 한번만 실행됨
// -> 성능 향상, 메모리 절약
Person.prototype.sum = function() {
return 'protytpye :'+(this.first+this.second);
}
var kim = new Person('kim', 10, 20);
// 만약 kim객체의 sum만 다르게 정의하고 싶다면 밑의 코드처럼 따로 써주면 됨
kim.sum = function() {
return 'this : '+ (this.first+this.second);
}
var lee = new Person('lee', 10, 10);
console.log("kim.sum()", kim.sum()); // 제일 먼저 kim객체 자신이 sum이라는 메소드를 가지고 있는 지 확인한다.
console.log("lee.sum()", lee.sum());
// 동작순서
// lee객체 자신이 sum이라는 함수를 가지고있지 않으면, lee객체의 생성자인 Person의 prototype에 sum이 정의 되어 있는지 찾아본다.
// 프로토타입이란?
// : 만들어진 객체들이 공통으로 갖는 프로퍼티
// 사용시 장점
// : 객체를 만들 때마다 같은 동작을 하는 중복적인 메소드가 메모리에 안쌓인다.
// 성능 저하를 막고 메모리 효율성을 높인다.
// *보충 프로토타입은 생성된 모든 객체가 공통으로 사용할 수 있고 재정의가
// 메소드를 prototype을 이용해 바깥으로 빼둠으로써, 객체가 생성될때마다 공통부분이 메모리에 중복되는것을 막는다.
//프로토타입(원형)은 생성자 함수 밖에 정의하며 한 생성자 함수에서 생성한 객체들은 모두 프로토타입으로 정의한 메소드를 사용할 수 있다.
// 객체가 해당 메소드를 갖고 있으면 그걸 바로 실행
// 갖고 있지 않다면 prototype이 그 메소드를 갖는지 확인
// 데이터는 보통 컨스트럭터에 저장 / 메소드는 prototype안에 저장.