생성자 함수 와 Class (01)
목차 📕
1. 생성자 함수란와 Class에 대하여 다음과 같은 목차로 다뤄보려 합니다.
하지만 막상 다뤄보니 다 다루진 못했어요 못 다룬 내용에 대해서는 다음 편에 다뤄보도록 할게요 (상속패턴, ES6 Class)
- 1.1 생성자 함수 동작 및 설명
- 1.2 예제로 살펴보기
- 1.3 상속
- 상속의 종류도 (다음편에...)
2. 생성자 함수 쓸 때 Tips
- 2.1 대문자로 시작하는 Convnetion
- 2.2 메소드는 Constructor.Prototype에
3. ES6 Class and Objcet.create(다음편에 ...)
1.생성자 함수 동작 및 설명
생성자 함수는 무엇일까? new로 무엇을 생성한다는 것일까요? 답은 바로 Plain 객체를 생성합니다 아래 영상에서 나온 설명을 참고해서 정리해보면
- 새로운 객체를 생성한다.
{}
- 이 객체에 prototype을 constructor.prototype과 연결한다.
Object.setPrototype(obj, constructor.prototype)
constructor.apply(obj, ..arguments)
this context객체를obj
로 정의해줍니다. 그러면 생성자 함수에서 this로 정의해놓은 부분이 자연스레 새로 생성된obj
객체가 되서 이 객체에 속성들이 붙겠죠- 마지막 이
obj
를 return 해줍니다 😄 단 fn에서 return값을 정의해주면 그 return값을 내어줍니다.
고로 일반 function과 생성자 함수로 쓸 때 구분을 지어주어야 겠죠 일반적인 convention으로 대문자로 시작해줍시다.
1.2 예제로 살펴보는 생성자 함수
function Person(name){
console.log(this) // context객체
this.name = name;
this.say = function(saying){
console.log(`I am ${saying}`)
}
this.think = function(what){
console.log(`I am thinking ${what}`)
}
}
var dali = new Person('dali')
브라우저에서
dali->
dali를 찍어서 열어보면 생성자 함수 표시가 나오고
정의해놓은 속성들을 가지고 있는 객체라고 나온다
또 호기심이 많은 사람들은 눌러보면
__proto__ 프로토타입 링크를 통해서 -> constructor 프로퍼티
가
생성자 함수랑 연결되어 있다는 것을 알 수 있다.
__proto__: constructor: ƒ Person(name)
또 생성자 함수도 Person.prototype 프로퍼티 역시 constructor: ƒ Person(name)
가지고 있는데
Person.prototype === dali.__proto__
//true 가 나오면서 같은 곳을 가르키고 있음을 알 수 있다
1.3 상속
여담이지만 잘 쓰기 어려운 패턴이, 상속이라고 한다. 많은 분들이 상속을 잘 못 써서, 설계가 잘 못되는 경우가 빈번하다고 ...상속을 잘 쓰려면 많은 훈련이 필요하다는 사실 인지하고 들어가보자
상속이라기보다 Class에 extends라는 말에 맞게 의미상으로 확장에 더 걸맞는다고 한다. 하지만 관습적으로 상속이라는 용어로 이미 통용이 많이 되고 있으니 상속이라고 얘기를 하겠다.
객체에 내부속성 prototype이 연결 되어 상위 확장을 지어준 객체를 가르키고
또 이 객체는 [[prototype]] 으로 상속되기 전 객체를 가르키고 이런식으로 프로토타입 체이닝을 통해서
쭈욱 올라갈 수 있을 때 결국 최정목적지는 Object를 가르키게 된다.
Object__proto는 null
1.3 상속
function Person(name) {
this.name = name;
}
Person.prototype.think = function() {
return `${this.name} is thinking`;
};
function Developer(name, skill) {
// super() 처럼 Person.call을 이용해서 확장 기반으로 할 constructor를 실행시켜준다.
Person.call(this, name);
this.skill = skill;
}
// 핵심 prototype을 prototype 링크 연결된 객체를 통해서 연결시킨다 (feat. Object.create)
Developer.prototype = Object.create(Person.prototype);
//
// instance of 로 검출할 때 Constructor.prototype으로 연결 관계를 체크하기 때문에
// 프로토타입 링크로 연결되어 있기 때문에 상속(확장)관계를 체크할 수 있다.
// 다만 이제 developer랑 연결된 consturcotr 속성이 없어서 인스턴스에서 직접 접근은 할 수 없어진다.
//
ES6;
Object.setPrototypeOf(Devleoper.prototype, Person.prototype);
// Devleoper.prototype -> Person.prototype 객체를 가르키는지 확인
Devleoper.prototype.coding = function() {
return `${this.name} is ${this.skill} coding `;
};
var dali = new Devleoper("dali", "js");
dali.think(); //
dali.coding(); //
예제로 상속 구현에 대해서 알아보았다. Prototype 링크들끼리 연결시켜주기만 하면 된다. 분명 몇 번 봤는 것 같은데도 ... 매번 잘 까먹는 것을 보면 직접 구현해보면서 연습해보지 않는 이상 'ㅁ';;; 다음에는 상속을 좀 이용해서 뭐라도 만들어봐야 겠네요
1.3.2 메소드 상속
var o = {
a: 2,
m: function(b) {
return this.a + 1;
}
};
var p = Object.create(o);
// 새객체를 만들면서 [[prototype]]을 o와 연결시킨다.
p > {};
__proto__: a: 2;
m: ƒ(b);
1.3.3 프로토타입 상속의 종류
MDN에서 소개해주는 3가지 종류의 상속
- 위임형 상속 위임형 상속은 앞서 살펴본 new나 es6 class 기반 인스턴스를 만드는 상속인데
장점 메모리 절약 메소드로 한 Constructor 함수들을 공유해서 쓴다.
단점
- Constructor(Functioin).prototype과 쓸데없는 binding되기 된다.
- 반대로 프로토타입에 변경이 모든 곳에 공유된다. 상태변경 전파를 막기 위해서 각 객체마다 상태 값의 복사값을 만들어야 한다.
- 연결형 상속
연결형 상속은 한 객체의 속성을 다른 객체에 모두 복사함으로써 상속을 구현하는 방법이다.
필요한 부분만 유연하게 합성해서 넣어주기 좋을 것 같다 😄 ... 이 부분도 좀 써보고 더
함수형 상속
-- Factory 함수로 만들어 사용하는 방식이다.
다뤄보려 하기에 양도 많고, 공부도 덜 된 것 같아서 2부에 상속과 class도 같이 다뤄보도록 하겠다 😄
생성자 함수 쓸 때 Tips
2.1 생성자 함수는 대문자로
일반 fn과 구분되도록 return값 정의하지 않고 😄
2.2 메소든느 프로토타입에다가 Prototype
일반적으로 생성자함수 객체에 prototype이 가르키는 곳에 함수를 다 공유해서 쓰면
객체마다 methods를 따로 가지지 않아도 이 공간으로 (dali.__proto__ === Person.prototype
)
공유해서 쓸 수가 있겠지요 😄
function Person(name) {
console.log(this); // context객체
this.name = name;
}
Person.prototype.say = function(saying) {
console.log(`I am ${saying}`);
};
Person.prototype.think = function(what) {
console.log(`I am thinking ${what}`);
};
2.3 생성자 함수 prototype을 뒤에서 수정하는 일
정의 한 곳 말고 또 다시 prototype을 직접 수정하게 되면 이로 상속 관계를 체크해서 연결되어 있는 부분 역시 영향을 끼치게 됨으로서 사이드 이펙트를 초래한다.
ETC
저는 JS만 해서 잘 모르겠지만... 어서 다른 언어들도 다뤄봐야 겠네요 (많이 다르다고 하지만,) 기본적으로 인스턴스냐 객체냐 미리 정의한 속성을 가진 것을 찍어내기 위해 만드는 것은 비슷할 것 같아요 비유로 설명할 때 많이 들어보셨을 것 같은 붕어빵, 게임 캐릭터, 자동차 공장 ...
전통적인 OOP 기반 언어들과 다르게 JS에서는 Prototype 기반 언어로 상속을 구현하고 있습니다.
Reference
Class
- 다음편에 따로 다뤄보겠습니다.
← 생성자 함수 와 클래스 뷰 컴포넌트 →