Maintainable JavaScript


발생일: 2013.02.12

문제:
연휴에 시골에 다녀오던 길에 Maintainable JavaScript(읽기 좋은 자바스크립트 코딩 기법)을 읽었다.

원래는 책읽기 스터디를 하려고 샀던 책이었는데, 가볍게 읽을 수 있을 것 같아 챙겨갔더랬다.


제목만 봐서는 컨벤션 이야기나 코딩 기법에 대한 것만 있을 것 같았는데,

의외로 배포 자동화까지 폭넓은 주제를 다루고 있다.

무엇보다, 저자의 경험을 기반으로 꼼꼼하게 설명하고 있어 더 유익했던 것 같다.


기억할 만한 내용을 메모해 옮겨둔다.



해결책:


p.41:

null은 객체(object)를 대신한다고 생각하는 것이 좋으며, 다음과 같이 사용한다.
- 나중에 "객체"의 값을 할당할 변수를 초기화할 때
- 인자 값으로 객체를 넘기는 함수를 호출할 때
- 함수를 호출한 곳에서 반환값으로 "객체"를 기대할 때
- 객체를 담은 변수의 값을 비교할 때

변수를 null로 초기화하면 나중에 객체를 저장할 것이라는 의도를 명확하게 할 수 있다.


p.78:

동등 연산자 == 를 사용하면, 두 피연산자 사이에 형변환이 일어난다.

Boolean을 Number와 비교하면, Boolean이 숫자로 캐스팅된 후 비교를 수행한다.
true는 1, false는 0으로 변환된다.

1 == true // true
2 == true // false
0 == false // true

String을 Number와 비교할 경우에도 마찬가지로 Number로 캐스팅 된 후 비교를 수행한다.

"1" == 1 // true
"1.0" == 1 // true
25 == "0x19" // true

String과 Boolean을 비교할 경우, 먼저 Number로 캐스팅 된 후 비교를 수행한다.

"1" == true // true
"1.0" == true // true
"2" == true // false
"0" == false // true

객체를 비교할 경우, 먼저 valueOf()를, valueOf()가 없다면 toString()으로 비교한다.

var foo = {
  toString: function() { return "25"; }
};
25 == foo // true


p.131:

객체 참조 타입 알아내기

value instanceof Date
value instanceof RegExp

instanceof 연산자는 "사용자 정의 타입"을 구분할 때 가장 좋으면서도 유일한 방법이다.

value instanceof Person

단, 프레임이 다른 경우, 각 프레임 간 인스턴스 정보를 공유하지 않으므로 주의해야 한다.

frameAPersonInstance instanceof frameAPerson // true
frameAPersonInstance instanceof frameBPerson // false


p.133:

IE8 이하에서는 document.getElementById()와 같은 DOM 함수를 함수가 아닌 객체로 인식한다.
IE 초기 버전에서는 DOM을 네이티브 자바스크립트 함수로 구현하지 않았기 때문이다.

따라서, DOM 기능은 in 연산자를 이용해 확인해보는 것이 좋다.
if ("querySelectorAll" in document) 


p.134:

프레임 간 배열을 전달할 일이 많은데, instanceof Array를 하면 결과값이 잘못 나온다.
ECMAScript5에서는 isArray()를 제공하고, 하위 버전에서는 네이티브 객체의 toString()을 비교하는 방식을 사용한다.

function isArray(value) {
  if (typeof Array.isArray === "function") {
    return Array.isArray(value);
  } else {
    return Object.prototype.toString.call(value) === "[object Array]";
  }
}


p.147:

throw "message";

문자열을 이용해 에러를 던질 수는 있지만,
사파리와 IE에서는 "uncaught exception"이라는 메시지만 보여줄 뿐,
예외를 던질 때 입력한 문자열을 보여주지 않는다.

따라서, 새 에러 객체를 생성해 예외를 던지는 것이 좋다.

throw new Error("message");


p.150:

모든 라이브러리는 외부에서 접근 가능한 공개 인터페이스를 작성할 때,
예측할 수 있는 모든 예외 상황에 대해 에러를 던지도록 해야 한다.
단, 에러의 호출 스택이 라이브러리의 인터페이스에서 끝나야지 더 깊게 들어가서는 안된다.
예를 들어 호출 스택이 라이브러리 함수엥서만 12단계에 걸쳐있는 것만큼 나쁜 것도 없다.


p.153:

ECMA-262에는 총 7가지의 에러타입이 정의되어 있다.

Error : 기본 타입
EvalError : eval()에서 발생한 에러
RangeError : 숫자가 범위를 벗어난 경우
ReferenceError : 사용하려는 객체를 찾을 수 없을 때
SyntaxError : eval()에 전달한 코드가 문법 상 문제가 있을 때
TypeError : 변수가 알 수 없는 타입일 때
URIError : 잘못된 형식의 URI 문자열이 URI 처리 함수(예: encodeURI)에 전달되었을 때

커스텀 에러 타입을 생성해서 예외를 던지면, instanceof 로 확인할 수 있어 유용하다.

function MyError(message) {
  this.message = message;
}
MyError.prototype = new Error();

throw new MyError("message");

ex instanceof MyError // 커스텀 에러를 골라내 처리할 수 있다.


하지만, 커스텀 에러 타입을 던진 경우, IE8 이하 버전에서는 에러 메시지가 보이지 않는다.
대신 "Exception thrown but not caught" 메시지만 보인다.


p.164:

객체 기반 상속은 프로토타입 상속으로도 불리며,
객체가 다른 객체의 "생성자 함수를 호출하지 않고" 그 객체를 상속받는 방법이다.
ECMAScript의 Object.create()를 이용하면 된다.

var person = {};
var myPerson = Object.create(person);


p.168:

퍼사드는 인터페이스를 통해 기반 객체를 완벽히 제어할 수 있어서 유지보수가 수월한 자바스크립트 코드를 작성하는 데 좋은 패턴이다.
퍼사드는 한 객체에 다른 인터페이스를 구현한다는 면에서 어댑터와 유사하다.
하지만, 퍼사드는 새로운 인터페이스를 생성하지만 어댑터는 기존 인터페이스를 재활용한다는 점이 다르다.


p.169:

ECMAScript5에서는 객체 변경을 방지하는 몇 가지 메서드를 추가했다.
변경 방지를 위한 잠금 타입으로는 총 3단계가 있다.

- 확장 방지(Prevent Extension) : 객체에 새로운 프로퍼티나 메서드 추가할 수 없음. 삭제와 수정 가능.
- 봉인(Seal) : 확장 방지 + 삭제 불가. 수정은 가능.
- 불변(Freeze) : 봉인 + 수정 불가. 즉, 모든 필드가 읽기 전용.

Object.preventExtension(obj);
Object.isExtensible(obj); // false;

Object.seal(obj);
Object.isSealed(obj); // true

Object.freeze(obj);
Object.isFrozen(obj); // true


p.177:

기능 탐지에서는 아래 세 단계로 검사하는 것이 효율적이다.

1. 표준 솔루션을 확인한다.
2. 브라우저 기반 솔루션을 확인한다.
3. 기능 탐지에 실패하면 적절하게 처리한다.


p.178:

기능 탐지를 부적절하게 사용하면 기능 탐지가 아닌 기능 추론이 된다.
한 가지 기능이 있으므로 다른 기능이 있으라리 생각하는 것인데, 문제가 생길 수 있다.

...
if  (window.ActiveXObject) { // IE
  element = document.all[id]; // 기능 추론은 좋지 않다.
}


p.191:

기본 디렉토리 구조
프로젝트마다 그 구조가 다양하지만 반드시 자바스크립트만을 위한 하위 디렉터리를 마련한다.
디렉토터리명은 script나 javascript를 많이 사용한다.

script
 |
 |-- src : 소스 디렉터리
 |-- test : 테스트 디렉터리
 |-- build : 최신 빌드 파일을 유지 (소스 형상 관리에 포함하지 않음)
  `-- release : 안정된 최신 빌드 파일 (형상 관리에 포함)


p.195~: 

Ant로 빌드하기. 설정 관련된 내용이나 최소화/압축과 관련된 내용도 자세히 정리해뒀다.


p.277:

주석 어노테이션의 종류

- TODO: 다음에 작업할 내용
- HACK: 임시변통의 방법을 사용한 코드. 핵을 왜 사용했는지에 대한 정보가 반드시 필요하다.
- XXX: 코드에 문제가 있어서 가능한 빨리 수정해야 함.
- FIXME: 코드에 문제가 있어 곧 수정해야 함. XXX 보다 덜 중요함.
- REVIEW: 변경 가능성이 있어 리뷰가 필요한 코드를 의미.








카테고리

분류 전체보기 (682)
About me. (6)
Daylogs (647)
비공개 (0)
영어공부 (0)
My works - 추억 (29)