[이펙티브 자바스크립트] 6장. 라이브러리와 API 설계

Bewell·2023년 8월 6일
1
post-thumbnail

[아이템 53] 일관된 컨벤션을 유지하라

  • 라이브러리의 사용자는 관례를 사용해서 읽고 쓰는 방법을 익혀야 하며, 이런 학습 프로세스를 가능한 쉽게 만드는 것이 여러분의 몫이다.
  • 핵심 컨벤션 중 하나는 인자의 순서다
  • width, height같은 여러 개의 측정 값을 동일한 순서로 만드는 편이 좋다
  • 예를 들면, CSS 사각형의 네 부분을 기술하기 위해서는 시계방향 top right bottom left 순으로 선언되기를 요구한다
  • 최고의 라이브러리는 사용자가 한번 익숙해지면, 문서를 다시 확인하지 않고 일반적인 작업을 처리할 수 있어야 한다

기억할 점

  • 변수 이름과 함수 시그니처에 일관된 컨벤션을 사용하라
  • 여느 개발 플랫폼에서 마주치기 쉬운 컨벤션과 다르게 설계하지 마라





[아이템 54] undefined를 '값이 없는' 것처럼 처리하라

undefined값은 수행 결과가 구체적인 값을 가지지 않음을 나타낸다

var x
x  // undefined

var obj = {}
obj.a //  undefined

function f() {
  return
}
f() // undefined

예를 들어 색상을 지정하는 함수에서 임의의 색상을 사용하기 위해 undefined를 사용하는 것은, 일반적인 의미와는 다르다. 다른 변수 'random'으로 사용할 수 있다

element.highlight()// 디폴트 색상사용
element.highlight('red')// 사용자 지정 색상사용

element.highlight(undefined)// 임의의 색상을 사용한다
element.highlight('random')// 임의의 색상을 사용한다

예제에서 트루시니스를 테스트하는 구현은 버그를 포함할 것이다.

var c1 = new Element(0, 0)  //  width: 0, height: 0
var c2 = new Element()  //  width: 320, height: 240


function Element(width, height) {
  this.width = width || 320 //  잘못된 테스트
  this.height = height || 240 // 잘못된 테스트
}

var c1 = new Element(0, 0)
c1.width // 320
c1.height // 240

대신에 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, '&lt')
  			...
}
  • 이런 반복된 메서드 호출 스타일을 메서드 체이닝이라고 한다
  • map, filter, reduce 등 메서드 체이닝에 사용된다

기억할 점

  • 무상태 연산을 결합하기 위해 메서드 체이닝을 사용하라
  • 무상태 메서드에서는 새로운 객체를 만들어 내도록 설계하여 메서드 체이닝을 지원하라
  • 상태 유지 메서드에서는 this 를 리턴하여 메서드 체이닝을 지원하라

0개의 댓글