2023.02.18
자바스크립트 스터디 6회차
공부 사이트: https://poiemaweb.com/
19. 자바스크립트의 객제치향 프로그래밍
1) 클래스 기반 vs 프로토타입 기반
종류 | 설명 |
클래스 기반 언어 | - 클래스로 객체의 자료구조와 기능을 정의, 생성자 통해 인스턴스 생성 - 클래스: 같은 종류의 집단에 속하는 속성과 행위를 정의 - 모든 인스턴스는 클래스에서 정의된 범위 내에서만 작동, 런타임에 구조 변경 불가능. |
프로토타입 기반 언어 | - 클래스 개념 대신 별도의 객체 생성 방법 존재. (객체 리터럴, Object() 생성자 함수, 생성자 함수) - 이미 생성된 인스턴스의 자료구조와 기능을 동적으로 변경할 수 있음. |
2) 생성자 함수와 인스턴스의 생성
생성자 함수와 new 연산자 통해 인스턴스를 생성할 수 있다.
function Person(name) {
this.name = name;
this.setName = function(name) {
this.name = name;
};
this.getName = function(){
return this.name;
};
}
var p1 = new Person('홍길동');
var p2 = new Person('고길동');
var p3 = new Person('박길동');
console.log(p1);
console.log(p2);
console.log(p3);
각각의 인스턴스에 메소드 setName과 getName이 중복되어 생성된다. 각 인스턴스가 내용이 동일한 메소드를 각자 소유하는 건데.. 이는 메모리 낭비이다. → 프로토 타입으로 해결
3) 프로토타입 체인과 메소드 정의
모든 객체는 프로토타입 객체를 가리키는 내부 링크를 가지고 있다. "프로토타입 체인"
메소드를 생성자 함수의 prototype 프로퍼티가 가리키는 프로토타입 객체로 이동시키면, 생성자 함수에 의해 생성된 인스턴스들은 프로토타입 체인에 의해 해당 메소드를 참조할 수 있다.
function Person(name) {
this.name = name;
}
Person.prototype.setName = function(){
this.name = name;
};
Person.prototype.getName = function(){
return this.name;
}
var p1 = new Person('홍길동');
var p2 = new Person('고길동');
var p3 = new Person('박길동');
console.log(p1);
console.log(p2);
console.log(p3);
console.log(Person.prototype);
getName(), setName() 메소드를 Person 생성자 함수의 prototype 프로퍼티가 가리키는 프로토타입 객체로 이동시켰다. 프로토타입은 상속할 것들이 저장되는 장소가 된다.
4) 상속
클래스 기반 언어에서 객체는 인스턴스이며, 클래스는 다른 클래스로 상속될 수 있다.
자바스크립트는 프로토타입을 통해 상속을 구현하는데, 이는 프로토타입을 통해 객체가 다른 객체로 직접 상속된다는 의미이다.
자바스크립트의 상속 구현 방식은 두 가지이다.
- 의사 클래스 패턴 상속(Pseudo-classical Inheritance): 클래스의 상속을 흉내내는 것
- 프로토타입 패턴 상속(Prototypal Inheritance): 프로토타입으로 상속을 구현하는 것
① 의사 클래스 패턴 상속
자식 생성자 함수의 prototype 프로퍼티를 부모 생성자 함수의 인스턴스로 교체하여 상속을 구현하는 방법.
부모와 자식 모두 생성자 함수를 정의 해줘야 함.
var Parent = (function() {
// 생성자
function Parent(name){
this.name = name;
}
// 메소드
Parent.prototype.sayHello = function(){
console.log('Hello, ' + this.name);
};
return Parent;
}());
var Child = (function() {
// 생성자
function Child(name){
this.name = name;
}
// 자식 생성자 함수의 프로토타입 객체를 부모 생성자 함수의 인스턴스로 교체
Child.prototype = new Parent();
// 메소드 오버라이딩
Child.prototype.sayHello = function(){
console.log('안녕하세요 ' + this.name);
};
Child.prototype.sayBye = function(){
console.log('바이바이 ' + this.name);
};
return Child;
}());
var child = new Child('자식');
console.log(child);
console.log(Child.prototype);
child.sayHello();
child.sayBye();
console.log(child instanceof Parent);
console.log(child instanceof Child);
[ 코드 설명 ]
- Child 생성자 함수가 생성한 인스턴스 child
- child의 프로토타입 객체는 new Parent()통해 생성된 Parent의 인스턴스
- Parent의 인스턴스의 프로토타입 객체는 Parent.prototype
▷ child는 프로토타입 체인에 의해 Parent 인스턴스와 Parent.prototype의 모든 프로퍼티에 접근할 수 있게 됨.
▷ 내부에서 프로토타입을 사용하는 것.
[의사 클래스 패턴의 문제점]
new 연산자 통해 인스턴스를 생성함.
- 프로토타입 통해 상속할 수 있는 대신, 생성자 함수와 new 연산자 통해 객체를 생성해야 하는 불필요한 단계 존재
- new 연산자 사용을 잊으면 this가 새로운 객체와 바인딩되지 않고 전역 객체에 바인딩될 수 있음
생성자 링크 파괴
- child 인스턴스의 프로토타입 객체는 new Parent() 객체.
- 프로토타입 객체는 내부 프로퍼티로 constructor를 가지며, 이는 생성자 함수를 가리킴.
- 의사 클래스 패턴 상속은.. constructor의 연결이 깨지게 된다
- child 인스턴스를 생성한 것은 Child 생성자 함수이나, child.constructor의 결과는 Parent이다.
객체 리터럴
- 생성자 함수를 사용하기 때문에 객체 리터럴 방식으로 생성한 객체의 상속에는 적합하지 않음
- 객체리터럴 패턴으로 생성한 객체의 생성자 함수는 Object이고, 이를 변경할 방법이 없기 때문.
② 프로토타입 패턴 상속 ✔
Object.crate를 사용해서 다른 객체로의 직접 상속을 구현하는 방석이다 .개념적으로 간단하며, new 연산자가 필요하지 않고 생성자 링크도 파괴되지 않는다. 객체 리터럴도 사용할 수 있다.
Object.crate: 매개변수에 프로토타입으로 설정할 객체/인스턴스를 전달하고 이를 상속하는 새로운 객체를 생성한다.
var Parent = (function() {
// 생성자
function Parent(name){
this.name = name;
}
// 메소드
Parent.prototype.sayHello = function(){
console.log('Hello, ' + this.name);
};
return Parent;
}());
var child = Object.create(Parent.prototype);
child.name = 'child';
child.sayHello();
console.log(child instanceof Parent);
[ Object.create 원리 ]
// Object.create 함수의 폴리필
if (!Object.create) {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
ⓐ 비어있는 생성자 함수 F를 생성
ⓑ F.prototype에 매개변수로 전달받은 객체 할당
ⓒ F를 생성자로 하여금 새로운 객체를 생성하고 반환
'프로그래밍 > js' 카테고리의 다른 글
lessons 21. 전역 객체 (0) | 2023.02.15 |
---|---|
lessons 20. 빌트인 객체 (0) | 2023.02.15 |
lessons 18. 클로저 (0) | 2023.02.13 |
lessons 17. this 키워드 (0) | 2023.02.13 |
lessons 16. Strict mode (0) | 2023.02.12 |