개발의변화
Javascript - 프로토타입 본문
Javascript는 클래스라는 개념이 없다. 기존의 객체를 복사하여 새로운 객체를 생성하는 프로토타입 기반 언어이다.
객체 원형인 프로토아입을 통해 새로운 객체를 만들고 이 새로운 객체는 또 다른 객체의 원형이다.
프로토타입은 이러한 방식을 통해 객체를 확장하고 객체 지향적인 프로그래밍을 가능하게 한다.
function Person() {}
속성이 하나도 없는 Person이라는 함수가 정의되고 파싱단계에 들어가면, Person 함수 Prototype 속성은 프로토타입 객체 참조
프로토타입 객체 멤버인 constructor 속성은 Person 함수를 참조하는 구조
객체안에는 proto 속성이 존재 ->객체가 만들어지기 위해 사용된 프로토타입 객체를 숨은 링크로 참조
프로토타입 객체: 자신이 다른 객체의 원형이 되는 객체, 모든 개체는 프로토타입 객체에 접근가능, 프로토타입 객체도 동적으로 런타임에 멤버를 추가가능
프로토타입을 활용하여 코드의 재사용 즉 상속을 표현할려고 한다. 처음 막혔던 부분부터 이야기 해보자
function Person(name) {
this.name = name || "준"
}
Person.prototype.getName = function() {
return this.name;
}
function Korean(name) {
}
Korean.prototype = new Person()
const kor = new Korean("수")
console.log(kor.name) //준
console.log(kor.getName()) // 준
자식에 해당하느 함수의 Prototy속성을 부모함수를 이용하여 객체를 생성할 때 참조하는 방법을 생각하여 막연히 Korean의 prototype 속성을 부모 함수로 생성된 객체로 바꾸었을 때
부모 객체의 속성과 부모 객체의 프로토타입 속성을 모두 물려받아 객체 자신의 속성은 특정 인스턴스에 한정되어 재사용 불가
즉 자신의 속성을 활용하여 부모 객체를 사용하는 것이 아닌 부모 객체에 한정되어버려 인자를 넣어도 default값만 나타남
function Person(name) {
this.name = name || "준"
}
Person.prototype.getName = function() {
return this.name;
}
function Korean(name) {
Person.apply(this, arguments)
}
let kor = new Korean("수")
console.log(kor.name) //수
console.log(kor.getName()) //준
그러면 apply를 통해 인자를 바인딩 하면?
this로 선언한 멤버만 물려받고 프로토타입 객체의 멤버들을 물려받지 못받는다.
링크가 안되어 있는 것을 확인할 수 있다.
function Person(name) {
this.name = name || "준"
}
Person.prototype.getName = function() {
return this.name;
}
function Korean(name) {
Person.apply(this, arguments)
}
Korean.prototype = new Person()
const kor = new Korean("수")
console.log(kor.name) //수
console.log(kor.getName()) //수
부모함수 this를 자식 함수 this로 바인딩, 11라인에서 자식 함수 prototype속성을 부모 함수를 사용하여 생성된 객체 지정했지만
문제가 하나 있다.
바로 부모 생성자를 두 번 호출하여 생성하는 방식이다.
이제 classical과 prototypal한 방식으로 해결해보자.
- classical
function Person(name) { this.name = name || "준" } Person.prototype.getName = function() { return this.name; } function Korean(name) { this.name = name } Korean.prototype = Person.prototype const kor = new Korean("수") console.log(kor.name) //수 console.log(kor.getName()) //수
자식함수를 부모함수의 속성을 참조하는 객체로 설정
- prototypal
const person = { type:"인간", getType : function() { return this.type; }, getNAme : function(){ return this.name } } const kor = Object.create(person) console.log(kor.name) //수 console.log(kor.getName()) //수
Object.create()를 사용하여 객체를 생성과 동시에 프로토타입으로 저장