[아이템 53] 일관된 컨벤션을 유지하라
- 라이브러리의 사용자는 관례를 사용해서 읽고 쓰는 방법을 익혀야 하며, 이런 학습 프로세스를 가능한 쉽게 만드는 것이 여러분의 몫이다.
- 핵심 컨벤션 중 하나는 인자의 순서다
- width, height같은 여러 개의 측정 값을 동일한 순서로 만드는 편이 좋다
- 예를 들면, CSS 사각형의 네 부분을 기술하기 위해서는 시계방향 top right bottom left 순으로 선언되기를 요구한다
- 최고의 라이브러리는 사용자가 한번 익숙해지면, 문서를 다시 확인하지 않고 일반적인 작업을 처리할 수 있어야 한다
기억할 점
- 변수 이름과 함수 시그니처에 일관된 컨벤션을 사용하라
- 여느 개발 플랫폼에서 마주치기 쉬운 컨벤션과 다르게 설계하지 마라
[아이템 54] undefined를 '값이 없는' 것처럼 처리하라
undefined값은 수행 결과가 구체적인 값을 가지지 않음을 나타낸다
var x
x
var obj = {}
obj.a
function f() {
return
}
f()
예를 들어 색상을 지정하는 함수에서 임의의 색상을 사용하기 위해 undefined를 사용하는 것은, 일반적인 의미와는 다르다. 다른 변수 'random'으로 사용할 수 있다
element.highlight()
element.highlight('red')
element.highlight(undefined)
element.highlight('random')
예제에서 트루시니스를 테스트하는 구현은 버그를 포함할 것이다.
var c1 = new Element(0, 0)
var c2 = new Element()
function Element(width, height) {
this.width = width || 320
this.height = height || 240
}
var c1 = new Element(0, 0)
c1.width
c1.height
대신에 undefined를 테스트하기 위해 조금 더 장황한 테스트문을 사용해야 한다.
function Element(width, height) {
this.width = width === undefined ? 320 : width
this.height = height === undefined ? 240 : height
}
기억할 점
- 특정값이 존재하지 않는다는 사실을 표현하는 경우를 제외하고는 undefined의 사용을 삼가하라
- 애플리케이션에 특화된 플래그 값을 표현하기 위해 undefined나 null보다는 서술적인 문자열 값이나 이름이 지정된 불리언 프로퍼티를 가지는 객체를 사용하라
- 유효한 인자로 0, NaN, 빈 문자열을 허용하는 함수에는, 파라미터의 디폴트 값을 위해 트루시니스를 테스트하는 방법을 사용하지 마라
[아이템 55] 키워드 인자를 위해 옵션 객체를 받아들여라
함수가 처음에는 간단하게 만들어졌지만 시간이 흘로 기능이 확장됨에 따라, 더 많은 인자들이 필요하게 된다.
자바스크립트에서는 더 많은 인자를 필요로 하는 큰 함수에서 옵션객체를 제공한다.
옵션객체를 통해 인자의 각 역할, 설명을 하기 위한 문서가 필요없고, 완벽히 스스로 설명해준다
var alert = new Alert(100, 75, 300, 200, 'Error')
var alert = new Alert({
x: 100,
y: 75,
width: 300,
height: 200,
message: 'Error'
})
extend를 이용해 목적객체와 소스객체를 받아 소스객체의 프로퍼티들을 목적객체에 복사하고, 디폴트값과 옵션객체로 사용자가 제공한 값을 병합하는 로직을 추상화 할 수 있다
기억할 점
- API를 가독성이 좋고 기억하기 좋게 만들기 위해 옵션 객체를 사용하라
- 옵션 객체로 전달되는 인자 모두는 반드시 부가적으로 처리되어야 한다
- extend 유틸리티 함수를 사용해 옵션 객체에서 값을 추출하는 로직을 추상화하라
[아이템 56] 불필요한 상태 유지를 피하라
- API는 때로 stateful, stateless로 분류된다
- Stateless API는 상태 변화에 의존하지 않고 입력 값에만 의존하는 함수나 메서드
- Stateful API는 상태 변화에 의존하기 때문에 다른 결과를 만들어 낸다
- Stateless API
- 모듈화된 코드를 만들어 낸다
- 예기치 못한 버그를 막아주고, 코드를 더 읽기 쉽게 만들어 준다
- Statefull API
- 예기치 못한 버그를 파악하기 어렵다
- 상태 의존성에 대해 항상 판단해야하는 번거로움
기억할 점
- 가능하면 무상태 API를 사용하라
- 상태 유지 API를 제공할 때는, 각 연산이 의존하는 관련된 상태에 대해 문서화하라
[아이템 57] 유연한 인터페이스를 위해 구조화된 형식을 사용하라
기억할 점
- 유연한 객체 인터페이스를 위해 구조적 타입 지정 (덕 타입 지정)을 사용하라
- 구조적 인터페이스가 더 유연하고 가볍다면 굳이 상속하지마라
- 단위 테스트를 위해 반복적인 동작을 제공하는 인터페이스의 대체 구현 방법인 mock 객체를 사용하라
[아이템 58] 배열과 유사 배열 객체를 구별하라
- 객체가 Array의 인스턴스이면 배열처럼 동작할 수 있고, 객체가 구현된 구조적인 타입을 나타내기 위한 명시적인 정보를 덧붙이지 않기 때문에, 하나의 값이 하나의 구조적인 인터페이스를 구현했는지 탐지할 수 없기때문에 정보를 신뢰할 수 있는 프로그래밍 가능한 방법은 없다
- 이런 이유로 ES5에서는 Array.isArray 함수를 제공한다. 이 함수는 프로토타입 상속과 관계없이 배열인지 확인한다.
- 객체가 유사배열객체가 아니라 진짜 배열인지 확인하기 위해서 instanceof 보다 Array.isArray가 더 신뢰할 만하다
기억할 점
- 구조적 타입을 다른 중복된 타입으로 절대 오버로딩하지마라
- 구조적 타입을 다른 타입으로 오버로딩할 때, 다른 타입을 먼저 테스트하라
- 다른 객체 타입으로 오버로딩할때, 유사 배열 객체 대신에 진짜 배열을 받아들여라
- API가 진짜 배열을 받아들이는지, 유사 배열 값을 받아들이는지 문서화하라
[아이템 59] 과도한 강제 형변환을 피하라
- 자바스크립트는 타입 검사가 느슨하기로 악명 높다
- 예상치 않은 입력값에 대해 예외를 발생하기 보다, 그 인자를 기대하는 값으로 강제 형변환한다
- 이는 에러를 감추고, 불규칙하고 분석하기 어려운 동작으로 초래한다
기억할 점
- 오버로딩과 강제 형변환을 섞어서 사용하지 마라
- 기대하지 않은 입력 값을 방어적으로 보호하라
[아이템 60] 메서드 체이닝을 지원하라
- Stateless API의 강력함 중 하나는 합셩 연산을 더 작은 것으로 만들 수 있는 유연함
function escapeBasicHtml (str) {
return str.replace(/&/g, '&')
.replace(/</g, '<')
...
}
- 이런 반복된 메서드 호출 스타일을 메서드 체이닝이라고 한다
- map, filter, reduce 등 메서드 체이닝에 사용된다
기억할 점
- 무상태 연산을 결합하기 위해 메서드 체이닝을 사용하라
- 무상태 메서드에서는 새로운 객체를 만들어 내도록 설계하여 메서드 체이닝을 지원하라
- 상태 유지 메서드에서는 this 를 리턴하여 메서드 체이닝을 지원하라