2008.06.05 12:18

JavaScript:
세상에서 가장 오해가 많은 프로그래밍 언어

Douglas Crockford | www.crockford.com
번역: Kwang Yul Seo | skyul.tistory.com

Mocha, LiveScript, JScript, ECMAScript 등으로도 불리는 JavaScript는 세상에서 가장 유명한 프로그래밍 언어 중에 하나입니다. 사실상 세상의 모든 개인 컴퓨터에 최소한 하나 이상의 JavaScript 인터프리터가 설치되어 있고 활발하게 사용되고 있습니다. 이러한 JavaScript는 인지도는 전적으로 월드와이드웹(WWW)의 스크립트 언어라는 역할 덕택입니다.
이런 인지도에도 불구하고, JavaScript가 매우 동적이며 객체지향의 범용 프로그래밍 언어라는 사실을 아는 이는 드뭅니다. 이런 사실이 어떻게 비밀이 될 수 있었을까요? 왜 이 프로그래밍 언어는 잘못 이해된 것일까요?

이름

Java- 접두사를 보면 JavaScript가 Java와 어떤 식으로는 연관 관계가 있을 것처럼 보입니다. 즉, JavaScript는 Java의 서브셋이거나 기능이 부족한 버전의 Java라는 인상을 줍니다. 이 이름은 혼란을 주기 위해 의도적으로 지어진 것으로 보이는데, 이런 오해가 혼란을 야기했습니다. JavaScript는 인터프리트되는 자바가 아닙니다. 자바 자체가 인터프리트되는 언어입니다. JavaScript는 Java와는 다른 언어입니다.
Java가 C와 문법적으로 유사하듯이 JavaScript는 Java와 유사합니다. 하지만 Java가 C의 서브셋이 아닌 것처럼 JavaScript도 Java의 서브셋이 아닙니다. JavaScript는 Java(초기의 Oak)과 원래 의도했던 응용 프로그램 부분에서는 Java보다 더 뛰어납니다.
JavaScript는 Java의 고향인 썬마이크로시스템즈(Sun Microsystems)에서 개발된 것이 아닙니다. JavaScript는 네스케이프(Netscape)에서 개발되었습니다. 원래는 LiveScript라고 불렸는데, 이 이름은 그다지 혼란스럽지 않았지요.
-Script 접미사는 JavaScript가 실제 프로그래밍 언어가 아니라 프로그래밍 언어보다 약한 스크립트 언어라는 인상을 줍니다. 하지만 이는 전문화의 문제입니다. C 언어와 비교해 보면, JavaScript는 표현력과 역동성(dynamism)을 위해 성능을 희생한 것입니다.

C 언어의 옷을 입은 Lisp

JavaScript의 C 언어 같은 문법(중괄호와 투박한 for 문을 포함)은 JavaScript가 일반적인 프로시저형 언어로 보이게 합니다. 이는 잘못된 오해인데, 왜냐하면 JavaScript는 C나 Java보다는 Lisp or Scheme와 같은 함수형 언어와 더 유사점이 많기 때문입니다. JavaScript는 리스트 대신에 배열이 있고, 속성 리스트(역주: 일종의 해시테이블) 대신에 오브젝트가 있습니다. 함수가 제1클래스이고, 클로저도 있습니다. 또한 괄호를 맞출 필요 없이 람다(lamda, 익명 함수)를 사용할 수도 있습니다.

고정역할

JavaScript는 네스케이프 네비게이터에서 동작하도록 설계되었습니다. 네스케이프에서의 성공은 JavaScript가 거의 모든 웹브라우저에서 표준 장치가 되도록 만들었습니다. 이는 JavaSciript가 웹 개발언어라는 이미지를 고정해 버렸습니다. JavaScript는 프로그래밍 언어계의 죠지 리브스(George Reeves), 슈퍼맨을 연기한 배우가 되었습니다. 하지만 JavaScript는 웹과 관련되지 않은 대규모의 응용 프로그램 개발에도 잘 어울리는 언어입니다.

움직이는 목표물

JavaScript는 첫 번째 버전은 매우 빈약했습니다. 예외 처리, 내부 함수, 상속 등의 기능이 없었습니다. 현재의 JavaScript는 완전한 객체지향 프로그래밍 언어입니다. 하지만 언어에 대한 여러 의견들은 여전히 예전의 성숙하지 못한 모습에 바탕을 두고 있습니다.
JavaScript 언어에 대한 관리 책임을 맡고 있는 ECMA 위원회는 비록 그 의도는 좋지만 이미 너무 많은 버전이 존재한다는 JavaScript의 가장 큰 문제점을 악화시키는 확장 작업을 하고 있습니다.

설계 오류

완벽한 프로그래밍 언어는 없습니다. JavaScript도 설계 오류를 포함하고 있습니다. + 를 자동 타입 변환과 함께 더하기와 문자열 병합이라는 두 가지 의미로 오버로딩한 것, 실수를 저지르기 쉬워서 사용을 피해야 하는 with 문 등이 여기에 해당합니다. 예약어 정책도 너무 까다롭습니다. 정규 표현식 기술 방법과 세미콜론 삽입은 아주 큰 실수입니다. 이런 실수는 프로그래밍 오류를 야기하고, 언어 설계 자체를 의문스럽게 만들게 됩니다. 다행히도, 이런 문제의 상당수는 lint라는 좋은 프로그램으로 완화가 가능합니다.
전체적인 언어 설계는 매우 안전합니다. 놀랍게도, ECMAScript 위원회는 이런 문제를 수정하는데 별로 관심이 없는 것처럼 보입니다. 아마도 그들은 새로운 것을 만드는데 더 관심이 많은 것 같습니다.

잘못된 구현들

JavaScript 초기 구현의 일부는 매우 버그가 많습니다. 이는 언어에 나쁜 영향을 미치고 있습니다. 설상가상으로 이런 구현들이 끔찍히도 버그가 많은 브라우저에 내장되어 있었습니다.

안 좋은 책들

사실상 JavaScript에 관한 거의 모든 책이 엉망입니다. 이 책들은 오류와 나쁜 예제투성이고, 잘못된 방법을 부추깁니다. 언어의 중요한 기능들이 잘못 설명되거나 아에 빠져있는 경우도 흔합니다. 필자는 십여 권의 JavaScript 책을 검토해보았는데, 다음 단 한 권의 책만 추천합니다. JavaScript: The Definitive Guide (5th Edition) by David Flanagan. (필자들에게: 좋은 책을 쓰셨다면 검토본을 보내주세요.)

불충분한 표준

언어의 공식 명세서ECMA가 작성하였습니다. 이 명세서는 품질이 매우 나쁩니다. 읽기도 어렵거니와 이해하기는 훨씬 어렵습니다. 이 제대된 책이 없는 문제와도 연결되는데, 저자들이 언어에 대한 그들의 이해를 높이기 위해 표준 문서를 활용할 수 없기 때문입니다. ECMA와 TC39 위원회는 깊이 반성해야 할 것입니다.

초보자들

JavaScript를 작성하는 대부분의 사람들은 개발자가 아닙니다. 그들은 좋은 프로그램을 쓰는 훈련을 받지 못했고 원칙이 부족합니다. JavaScript는 뛰어난 표현력을 가졌기에 그들은 어쨌건 유용한 프로그램을 작성할 수 있습니다. 이는 JavaScript는 단지 초보자들을 위한 것이지 전문가 용은 아니라는 인상을 주었습니다. 이는 사실이 아닙니다.

객체지향

JavaScript는 객체지향일까요? JavaScript는 데이터와 데이터를 처리할 수 있는 메서드를 담을 수 있는 오브젝트를 제공합니다. 오브젝트는 다른 오브젝트를 저장할 수도 있습니다. 클래스는 없지만, 클래스 변수와 메서드를 담을 수 있는 클래스 역할을 하는 생성자가 있습니다. 클래스 기반의 상속 기능은 없지만, 프로토타입 기반의 상속 기능을 제공합니다.
오브젝트 시스템을 만드는 두 가지 주요 방법은 상속(is-a)과 집합(has-a)이 있습니다. JavaScript는 두 가지 방법을 다 지원하지만, 언어의 동적인 속성은 집합(aggregation)일 때 더 빛을 발합니다.
일부에서는 JavaScript가 정보 은닉을 제공하지 않기 때문에 참된 의미의 객체지향이 아니라고 말합니다. 이는 오브젝트에 private 멤버와 메서드가 없다는 뜻입니다. 모든 멤버는 public입니다.
하지만 JavaScript 오브젝트는 private 변수와 private 메소드를 가질 수 있다.로 밝혀졌습니다. 물론, JavaScript는 세상에서 가장 오해가 많은 언어이기에 이를 이해하는 사람은 많지 않습니다.
또한 일부는 JavaScript가 상속을 지원하지 않기 때문에 진정한 의미의 객체 지향 언어라고 말합니다. 하지만 JavaScript는 전통적인 상속 방식뿐만 아니라 다른 코드 재활용 패턴 또한 제공한다. 라는 사실이 밝혀졌습니다.
Copyright 2001 Douglas Crockford. All Rights Reserved Wrrrldwide.

Posted by 부니기
2008.05.24 02:30
Three common mistakes in JavaScript / EcmaScript
Here are three common mistakes I've seen recently in script files.
  1. Undefined is not null.
    If you've been writing code in a strongly-typed language recently, you're used to checking the nullity of objects before you use them, like this:

    if
    (SomeObject != null) {

    Well, in JavaScript, which is a dynamic language, something that has not been assigned to is not null, it's undefined. Undefined is different from null. Why? Don't ask me. Well, anyways, you can use typeof to explicitly check for undefined, or use other more or less clean tricks, but the best way to deal with that is probably to just rely on the type-sloppiness of JavaScript and count on it to evaluate null and undefined as false in a boolean expression, like this:

    if
    (SomeObject) {

    It looks uglier, but it's more robust.
    It's very important to keep the undefined case in mind. Another case is when you expect a function to return a boolean value. What if the function forgets to return a value in some cases? Well, its return value is then undefined, which is false. So if your own default value should be true, you should really write this:

    if
    (SomeFunction() !== false) {

    Which is different from if (SomeFunction()). Cute, eh? By the way, note the strict equality here.
     
  2. You can't overload a function.
    Developers who are used to languages like Java and C# overload methods all the time. Well, in JavaScript, there are no overloads, and if you try to define one, you won't even get an error. The interpreter will just pick the latest-defined version of the function and call it. The earlier versions will just be ignored.
    The way you simulate overloading is twofold. First, if a parameter is omitted, it is undefined. And second, there is a special variable, arguments, which is an array of the function parameters. Based on the type of each parameter, you can do different things. But it's kind of ugly.
     
  3. Undeclared variables are global.
    Always, always declare your variables using the var keyword. If you don't, your variable is global. So anyone who makes the same mistake as you (or more likely, if you do the same mistake in two different places) will create nice conflicts which give rise to very difficult-to-track bugs. Even loop counters should be properly declared.
There is actually a good way to do some basic sanity checks on your script files (like multiple declarations, forgotten declarations, unassigned variables, etc.): in Firefox, go to the about:config url and look for the javascript.options.strict entry. Set it to true. Now, you can point the browser to your JavaScript file. You'll get a lot of new warnings that will point to the problems in your code (if any, but I doubt that you'll get zero warnings the first time you do that).
Posted by 부니기

티스토리 툴바