Classes & Constructors 클래스 사용 > 프로토타입 직접조작
Always use class. Avoid manipulating prototype directly.
- prototype을 직접 조작하는 것보다 class를 활용한다.
- class 문법은 prototype의 조작보다 더 간결하며, 의미를 알기 쉽기 때문이다.
// bad
function Queue(contents = []) {
this._queue = [...contents];
}
Queue.prototype.pop = function() {
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
// good
class Queue {
constructor(contents = []) {
this._queue = [...contents];
}
pop() {
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
}
/* 참고: 언더바(_) 변수
코딩 컨벤션의 일종이며, 해당 함수 내부에서 사용될 변수 또는 함수임을 암시하기 위함. (java의 private과 유사)
class Injuk {
constructor(contents = []) {
console.log(this);
console.log(this._injuk);
this._injuk = [...contents];
console.log(this._injuk);
}
}
let injuk = new Injuk([1, 2, 3]);
실행 결과:
Injuk {} // 실행 context는 Injuk{} 클래스
undefined // this._injuk 초기화 전
[ 1, 2, 3 ] // this._injuk 초기화 후
*/
상속: extends 사용
Use extends for inheritance.
- 상속은 extends를 사용합니다.
- It is a built-in way to inherit prototype functionality without breaking .instanceof
- instanceof를 사용할 수 있으면서 함께 프로토타입 상속을 받을 수 있게 구현된 Built-in 방식이다.
// bad
const inherits = require('inherits');
function PeekableQueue(contents) {
Queue.apply(this, contents);
}
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function() {
return this._queue[0];
}
// good
class PeekableQueue extends Queue {
peek() {
return this._queue[0];
}
}
/* inherits 검증 필요
*/
클래스 메서드 체이닝: 메서드가 this 를 return
Methods can return this to help with method chaining.
- 메소드의 반환값으로 this 를 반환하는 것으로 메소드채이닝을 할 수 있다.
// bad
// prototype을 사용하며, return이 적절하지 않게 구현되었습니다.
Jedi.prototype.jump = function() {
this.jumping = true;
return true;
};
Jedi.prototype.setHeight = function(height) {
this.height = height;
};
const luke = new Jedi();
luke.jump(); // => true
luke.setHeight(20); // => undefined
// good
// class 방식을 사용하며, 메소드가 context(이 경우, Jedi{})를 반환하여 연속된 메소드 사용(메소드 체이닝)이 가능합니다.
class Jedi {
jump() {
this.jumping = true;
return this;
}
setHeight(height) {
this.height = height;
return this;
}
}
const luke = new Jedi();
luke.jump()
.setHeight(20);
클래스의 커스텀 toString() 메서드
It's okay to write a custom toString() method, just make sure it works successfully and causes no side effects.
- 확인해야 할점 : class 별로 독자적인 toString()을 사용하는 것은 허용되나, 정상 동작 여부와 side effect 여부를 확인해주시기 바랍니다.
class Jedi {
constructor(options = {}) {
this.name = options.name || 'no name';
}
getName() {
return this.name;
}
// It's Okay... just make sure it
toString() {
return `Jedi - ${this.getName()}`;
}
}
default 생성자 eslint: no-useless-constructor
- 빈 constructor 생성자는 생략해도 된다.
- 빈 생성자를 가지는 클래스를 상속하는 클래스에서, 또한 빈 생성자를 가지고 있을 땐 constructor 가 불필요하다.
// bad
class Jedi {
constructor() {}
getName() {
return this.name;
}
}
// bad
class Rey extends Jedi {
constructor(...args) {
super(...args);
}
}
class Jedi {
getName() {
return this.name;
}
}
class Rey extends Jedi { }
// good
class Rey extends Jedi {
constructor(...args) {
super(...args);
this.name = 'Rey';
}
}
중복된 클래스 멤버를 가지는 클래스 X . eslint: no-dupe-class-members
- 중복된 클래스 멤버를 선언하면 암묵적으로 마지막 멤버가 적용되며, 이에 중복된 클래스 멤버를 가질 수 있는 버그이다.
// bad
class Foo {
bar() { return 1; }
bar() { return 2; }
}
// good
class Foo {
bar() { return 1; }
}
// good
class Foo {
bar() { return 2; }
}
클래스 메서드에서 this 를 사용하지 않을 경우 : static 메서드 사용 eslint: class-methods-use-this
// bad
class Foo {
bar() {
console.log('bar');
}
}
// good - this 를 사용할 경우 -> 일반 메서드
class Foo {
bar() {
console.log(this.bar);
}
}
// good - constructor 를 생략할 수 있다.
class Foo {
constructor() {
// ...
}
}
// good - this 를 사용하지 않은 경우 -> static methods, 정적 메소드는 this를 사용하지 않는다고 예상할 수 있습니다
class Foo {
static bar() {
console.log('bar');
}
}
'JS > 자바스크립트 Style Guide' 카테고리의 다른 글
10. terators and Generators (JS style guide) (0) | 2023.01.09 |
---|---|
9. Modules(JS style guide) (0) | 2023.01.03 |
7. Arrow Functions (JS style guide) (0) | 2022.12.21 |
6. Functions (JS style guide) (2) | 2022.12.14 |
5. Strings (JS style guide) (0) | 2022.12.07 |