블로그 이미지

Rurony's Training Gym

Rurony의 트레이닝 도장! by Rurony


'Javascript'에 해당되는 글 1건

  1. 2010.12.16 자바스크립트의 나쁜 점들 (더글라스 클락포드)

자바스크립트의 나쁜 점들 (더글라스 클락포드)


1. ==/!=
 
피연산자의 타입이 다를 경우 값들을 강제로 변환하여 비교합니다.

'' == '0' //false
0 == '' //true
0 == '0' //true
false == 'false' //false
false == '0' //true
false == undefined //false
false == null //false
null == undefined //true

데이터의 타입이 같고 같은 값인지를 비교하기 위해 ===/!== 를 사용해야 합니다.

2. with
자바스크립트는 객체 하나에 속한 속성들을 접근할 때 간편함을 제공할 목적으로 with 문이 있습니다.

다음과 같은 with 문은,

with (obj) { a = b; }

다음과 같은 의미입니다.

if (obj.a === undefined) { a = obj.b === undefined ? b : obj.b; } else { obj.a = obj.b === undefined ? b : obj.b; }

그래서 결국 이 with 문은 다음의 문장들 중에 하나와 같게 됩니다.

a = b;
a = obj.b;
obj.a = b;
obj.a = obj.b

이 문장들 중에 어떤 문장으로 실행될지는 프로그램을 봐서는 알 수 없습니다.

3. eval

eval 함수는 문자열을 자바스크립트 컴파일러에 넘긴 후 그 결과를 실행시킵니다. 
이는 심각한 성능저하의 요인이 됩니다. 또한 eval 함수는 보안상의 치명적인 문제점을 가지고 있습니다. 하지만, 서버로부터 전달된 JSON 텍스트를 파싱하기 위해 eval 함수를 사용할 수 있습니다. 서버로부터 문제없이 전달된 텍스트를 eval 함수로 파싱하는 것은 HTML이 로드되는 것처럼 안전합니다.

※ 지금은 그렇지 않겠지만, 자바스크립트를 처음 접했을때 객체를 얻기 위한 방법으로 eval 함수를 남용한 코드를 많이 보아왔습니다.

4. continue

continue 문은 루프의 처음으로 제어를 이동 시키고 이러한 방식은 성능저하의 원인이 됩니다.
리팩토링을 통해 continue문을 제거 했을때 성능이 향상되지 않았던 적이 없었다고 하네요.

5. switch/case

각각의 case절은 명시적으로 벗어나게 하지 않으면 다음 case절 까지 계속해서 실행됩니다.
언어에서 가장 나쁜 점은 명백하게 위험하거나 불필요한 속성이 아니라, 매력적으로 보이는 페단이 가장 나쁜 점이라고 하네요.

6. 블록이 없는 문장

아래와 같은 형식은 프로그램의 구조를 애매하게 만들어 후에 작업하는 사람이 쉽게 버그를 만들 수 있게 합니다.

다음의 코드는,

if (ok)
t = true;
advance();

다음의 의미가 아니라,

if (ok) {
t = true;
advance();
}

다음과 같은 의미입니다.

if (ok) {
t = true;
}
advance();

비단 자바스크립트에서만의 나쁜 점이 결코 아니라는 것에 크게 공감하는 부분입니다.

7. ++/--

증감 연산자를 사용하면 코드를 매우 간결하게 작성 할 수 있습니다.  하지만 심각한 보안 취약점을 만드는 대부분의 버퍼 오버런 버그는 이와 같은 스타일의 코드 때문에 발생합니다.

다음과 같은 코드는

var i = 1;
function() { return i + 1 }; //return 2
function() { return i++ }; //return 1

i++/++i의 동작방식(리턴방식)을 충분히 이해한다면 문제되진 않겠지만 일급 객체 표현에 있어서 의식적으로 사용하는 코딩 습관으로 인해 충분히 발생될 소지가 있다고 생각합니다.

8. 비트연산자

&, |, ^, ~, >>, >>>, << 등의 비트 연산자는 정수에 대해서만 동작합니다. 하지만 자바스크립트에는 정수형이 없고 부동 소수점 숫자형만이 존재하여 대상이 되는 숫자를 일단 정수형으로 변환한 다음에 비트 연산을 수행하고 다시 원래 타입으로 되돌립니다. 이와 같은 이유로 성능이 크게 나빠집니다.

9. 함수 문장 vs 함수 표현식

다음과 같은 함수 문장은,

function foo() {};

다음과 같은 의미 입니다.

var foo = function foo() {};

자바스크립트라는 언어를 잘 사용하기 위해서는 함수도 값(value)이라는 것을 이해하는 것이 중요합니다. 함수문장은 위로 끌어롤려지는 대상이 됩니다.(hoisting) 이 말은 함수가 위치한 곳과 관계 없이 함수가 정의된 곳의 유효범위 가장 상위로 이동된다는 뜻입니다. 이러한 특징은 함수를 사용하기 전에 반드시 미리 선언해야 한다는 요구사항을 경감시켜 구조를 엉성하게 만듭니다.

공식적인 문법은 function이라는 단어로 시작하는 문장을 함수 문장이라고 가정하고 있기때문에 문장의 첫 번째 부분에 함수 표현식을 사용할 수 없습니다. 이를 위한 대안은 함수 표현식을 다음의 예처럼 괄호로 묶는 것입니다.

(function () {
var hidden_varialble;
})();

함수표현식에서 익명 함수값은 IE에서도 미리 선언되지 않으면 에러를 발생시키지만 이름부에 함수명을 쓰게되면 IE는 함수 문장으로 인식되고 있습니다.

10. 데이터 타입 랩퍼

new Boolean, new Number, new String 등은 완전히 필요가 없습니다.
또한 new Object와 new Arrary의 사용도 피하고 {}, []를 사용하기 바랍니다.

11. new

자바스크립트의 new 연산자는 피연산자의 프로토타입 멤버들을 상속하는 객체를 생성하고 이 객체를 this에 바인딩하면서 피연산자를 호출합니다.

프로토타입에의한 OOP 상속에서 생성자를 통한 인스턴스의 사용을 위해 사용하게 됩니다. 이런한 방식에서의 this 누락으로 인한 잠재적인 프로그램상의 위험 요소를 줄이고자 스칼 표기법을 쓰라고 권고하고 있습니다. new 연산자를 사용하지 않으면 this는 새로운 객체에 바인딩 되지 않고 전역객체에 연결됩니다. 자바스크립트 OOP 상속의 구현 방식에있어서 프로토타입 기반의 자바스크립트의 근본과 명확한 OOP의 개념(closure 생성을 통한 캡슐화 포함) 구현 및 메모리 등에서 여러가지 이견들이 있는 것 같습니다. 클락포드는 new 연산자를 사용하지 않는 것이 더 나은 정책이라고 말하고 있습니다.
 
12. void

자바스크립트에서 void는 피연산자를 취한 후 undefined를 반환하는 연산자입니다. 이는 유용하지도 않고 혼동됩니다.

출처 : 더글라스 클락포드의 "자바스크립트 핵심가이드"
Top

prev 1 next