책을 읽은 지는 꽤 지났지만, 다시 한번 복습 겸 기록을 남겨보려고 합니다. 책을 읽고 요약해 정리한 내용의 전문은 제 개인 노션에 정리해 놓았습니다.
이전 글 : [FRONT-END/JavaScript] - 06. 프로토타입 (코어 자바스크립트)
클래스
클래스는 하위로 갈수록 상위 클래스의 속성을 상속하면서 더 구체적인 요건이 추가 또는 변경됩니다.
클래스의 속성을 지니는 실존하는 개체를 인스턴스라고 합니다.
프로그래밍에서는 사용자가 직접 여러 가지 클래스를 정의해야 하고, 클래스를 바탕으로 인스턴스를 만들 때 비로소 어떤 개체가 클래스의 속성을 지니게 됩니다. 클래스가 먼저 정의되어야만 그로부터 공통적인 요소를 지니는 객체들을 생성할 수 있습니다. 또한 한 인스턴스는 하나의 클래스만을 바탕으로 만들어집니다.
다중 상속을 지원하는 언어든 그렇지 않은 언어든 결국 인스턴스를 생성할 때 호출할 수 있는 클래스는 오직 하나일 수 밖에 없습니다.
자바스크립트의 클래스
사실 이전 글에서도 알아봤듯, 자바스크립트는 프로토타입 기반의 언어이므로 클래스의 개념이 존재하지 않습니다.
그렇지만 프로토타입을 일반적이 의미에서의 클래스 관점에서 접근해보면 비슷하게 해석할 수 있는 요소가 있습니다.
생성자 함수 Array를 new 연산자와 함께 호출하면 인스턴스가 생성됩니다.
이때 Array를 일종의 클래스라고하면, Array의 prototype 객체 내부 요소들이 인스턴스에 상속된다고 볼 수 있습니다.
상속이 아닌 프로토타입 체이닝에 의한 참조지만 결과적으로는 동일하게 작동합니다.
// 생성자
var Rectangle = function (width, height) {
this.width = width
this.height = height
}
// 프로토타입 메서드
Rectangle.prototype.getArea = function () {
return this.width * this.height
}
// 스태틱 메서드
Rectangle.isRectangle = function (instance) {
return instance instanceof Rectangle && instance.width > 0 && instance.height > 0
}
var rect1 = new Rectangle(3, 4)
console.log(rect1.getArea()) // 12
console.log(rect1.isRectangle()) // Error
console.log(Rectangle.isRectangle(rect1)) // true
한편 Array의 내부 프로퍼티들 중 prototype 프로퍼티를 제외한 나머지는 인스턴스에 상속되지 않습니다.
인스턴스 상속 여부에 따라 static 멤버와 instance 멤버로 나뉩니다.
인스턴스에서 직접 접근할 수 없는 메서드를 스태틱 메서드라고 합니다.
스태틱 메서드는 생성자 함수를 this로 해야만 호출할 수 있습니다. (위 코드 Rectangle.isRectangle(rect1)에 해당)
클래스 상속
자바스크립트에서 클래스 상속을 구현했다는 것은 결국 프로토타입 체이닝을 잘 연결한 것이다라고 이해하면 됩니다.
클래스에 있는 값이 인스턴스의 동작에 영향을 줘서는 안 됩니다. 인스턴스와의 관계에서는 구체적인 데이터를 지니지 않고 오직 인스턴스가 사용할 메서드만을 지니는 추상적인 툴로서만 작동하게끔 작성해야 예기치 않은 오류 발생을 막을 수 있습니다.
클래스가 구체적인 데이터를 지니지 않게 하는 방법
1) 일단 만들고 나서 프로퍼티들을 일일이 지우고 더는 새로운 프로퍼티를 추가할 수 없게 함
var extendClass1 = function (SuperClass, SubClass, subMethods){
SubClass.prototype = new SuperClass()
for (var prop in Subclass.prototype) {
if (SubClass.prototype.hasOwnProperty(prop)){
delete SubClass.prototype[prop]
}
}
SubClass.prototype.constructor = SubClass
if (subMethods) {
for (var method in subMethods) {
SubClass.prototype[method] = subMethods[method]
}
}
Object.freeze(SubClass.prototype)
return SubClass
}
var Square = extendClass1(Rectangle, function(width) {
Rectangle.call(this, width, width)
})
2) SubClass의 prototype에 직접 SuperClass의 인스턴스를 할당하는 대신 아무런 프로퍼티를 생성하지 않는 빈 생성자 함수(Bridge)를 하나 더 만들어서 그 prototype이 SuperClass의 prototype을 바라보게끔 한 다음, SubClass의 prototype에는 Bridge의 인스턴스를 할당하게 함
var Bridge = function () {}
Bridge.prototype = Rectangle.prototype
Square.prototype = new Bridge()
Object.freese(Square.prototype)
3) Object.create 활용
Square.prototype = Object.create(Rectangle.prototype)
Object.freeze(Square.prototype)
var extendClass3 = function (SuperClass, SubClass, subMethods){
SubClass.prototype = Object.create(SuperClass.prototype)
SubClass.prototype.constructor = SubClass
if (subMethods) {
for (var method in subMethods) {
SubClass.prototype[method] = subMethods[method]
}
}
Object.freeze(SubClass.prototype)
return SubClass
}
4) ES6 문법
var ES6 = class {
constructor (name) {
this.name
}
static staticMethod() {
return this.name + ' staticMethod'
}
method() {
return this.name + ' method'
}
}
var Rectangle = class {
constructor (width, height) {
this.width = width
this.height = height
}
getArea() {
return this.width * this.height
}
}
var Square = class extends Rectangle {
constructor (width) {
super(width, width)
}
getArea() {
console.log('size is :', super.getArea())
}
}
- 끝 -
후기
이렇게 정말 오랜 시간이 걸린..! 코어 자바스크립트 재정리가 끝났습니다 😂
이미 두 번 정도 책을 꼼꼼히 읽으면서 노션에 정리해 놨었는데, 블로그에 올리기 위해 책을 한번 더 보고 노션의 내용이 부족한 것 같으면 채워 넣고, 다시 블로그에 작성하는 과정에 생각보다도 더 많은 시간이 소요되었습니다.
다른 많은 개발자 분들이 공부하고 글로 남기는 과정, 강연을 위해 자료를 만드는 과정, 영상을 찍는 과정에 엄청난 노력이 들어가는 것을 깨닫는 하나의 수행 같은 시간이었습니다..! 🥲
그래도 이 정리 과정 속에서 한번 더 개념을 학습하고 나아갈 수 있어 결코 헛되지 않은 시간✨이었습니다 🐥
앞으로도 더 기록을 생활화 할 수 있도록 글쓰기 실력도 요약 실력도 키워 나가야겠습니다!
나에게도, 더 나아가 이 글을 읽는 누군가에게도 도움이 될 수 있었기를 바랍니다 🧚🏻
'FRONT-END > JavaScript' 카테고리의 다른 글
06. 프로토타입 (코어 자바스크립트) (0) | 2024.09.23 |
---|---|
05. 클로저 (코어 자바스크립트) (6) | 2024.09.22 |
04. 콜백 함수 (코어 자바스크립트) (1) | 2024.09.22 |
03. this (코어 자바스크립트) (1) | 2024.09.22 |
02. 실행 컨텍스트 (코어 자바스크립트) (0) | 2024.09.21 |
댓글