понедельник, 9 февраля 2009 г.

JavaScript: язык, который так до сих пор и не поняли


Your Host: Даглас Крокфорд (Douglas Crockford)
Original: The World's Most Misunderstood Programming Language
Russified by: Денис Сахаров
Credits: Павел Кравцов (за ряд ценных замечаний)


JavaScript или Mocha, или LiveScript, или JScript, или ECMAScript, является одним из самых популярных языков программирования в мире. Практически на каждом компьютере установлен и активно используется как минимум один интерпретатор JavaScript. Такую популярность JavaScript заслужил только по одной причине - на нём разрабатываются сценарии или, как их ещё называют, скрипты для Всемирной Паутины.
Несмотря на такую популярность, немногие знают, что JavaScript - это отличный объектно-ориентированный язык программирования, пригодный для решения достаточно большого круга задач. Что ж, пора расставить все точки над j.

Что в имени тебе моём?

Префикс "Java" практически сразу вызывает ассоциации с языком Java, вследствие чего некоторые могут подумать, что JavaScript - это "младший брат" Java, тощий, слабенький и не такой способный. Такое впечатление, что это имя было выбрано специально, чтобы запутать народ, вот все и запутались.
Теперь внимание. JavaScript - это не Java и никак с последним не связан.

У них схожий синтаксис, примерно в том же отношении, как у Java к C. А тем, кто на основании такого сходства считает, что JavaScript - это подмножество Java, а Java - подмножество С, возможно, не стоит читать дальше. И ещё одно. JavaScript гораздо лучше решает те задачи, для которых изначально разрабатывался Java (в юности Java называли "Oak").

JavaScript, в отличие от Java, появился на свет не в операционной Sun Microsystems. JavaScript - это гордое детище корпорации Netscape. Первенца назвали LiveScript, но позже, видимо, решили что LiveScript - это слишком просто и понятно.

Суффикс "Script" сразу создаёт впечатление, что это НЕ НАСТОЯЩИЙ язык программирования, а простенькая игрушка, сработанная на коленке. На самом же деле, инструмент выбирают, исходя из поставленной задачи, а не наоборот. Да, JavaScript уступает С в производительности, но берёт своё в части интуитивности написания кода (expressive power of JavaScript) и отсутствия различных статических условностей (dynamism of JavaScript).

Lisp, в нарядах от С

Синтаксис JavaScript, так напоминающий С, например, фигурные скобки и все премудрости цикла "for", наводит на мысль, что перед нами обычный процедурный язык программирования. Это не так, поскольку JavaScript имеет гораздо большее сходство с функциональными языками, вроде Lisp или Scheme, чем с С или Java. Списки реализуются с помощью массивов, а списки свойств или атрибутов - с использованием объектов. Функции являются объектами первого рода. Поддерживаются замыкания (closures). Можно использовать lambda-выражения без необходимости бороться с бесчисленными скобками.

Заезженное амплуа

JavaScript был создан для программирования в браузере Netscape Navigator. Открывшиеся возможности, которые были успешно использованы разработчиками, привели к тому, что теперь он используется практически в каждом известном браузере. Что, в свою очередь, привело к определённому стереотипу:
JavaScript наилучшим образом подходит для программирования скриптов для браузеров, по аналогии с тем, как Савелий Крамаров наилучшим образом подходит на роли карикатурных персонажей советского кино. На самом деле, JavaScript прекрасно справляется с приложениями, вообще не связанными с Интернетом.

Движущаяся мишень

Первые версии JavaScript нельзя назвать особо выдающимися. Отсутствовали обработка исключений, вложенные функции, наследование. Современный JavaScript представляет из себя первоклассный объектно-ориентированный язык программирования, и большинство претензий следует относить к более ранним версиям.

JavaScript живёт и развивается по спецификациям, разрабатываемым организацией ECMA, которые, хотя и преследуют благие цели, но уже привели к тому, что существует слишком много рабочих версий языка.

Совершенна только Природа

Любой из языков программирования несёт с собой багаж недоделок, и JavaScript не является исключением: перегруженный оператор "+", означающий одновременно и операцию сложения и операцию конкатенации с предварительным преобразованием типов операндов; конструкция "with", которую следует боятся, как огня. Список зарезервированных слов вызывает много вопросов. Механизм автоматической подстановки ";" - такой же крупный промах, как и использование "/" для выделения тела регулярных выражений. Подобные ошибки приводят к ляпам в коде, что не делает чести разработчикам языка. К счастью, большинство этих проблем можно избежать, пользуясь хорошим анализатором.

И хотя в целом язык продуман достаточно хорошо, удивительно одно - специалисты группы ECMAScript не проявляют должных усилий для устранения существующих проблем. Похоже, что их усилия сосредоточены на создании новых.

Маленький уродец

В некоторых ранних версиях JavaScript имелось большое количество недочётов, что принесло ему дурную славу. А реализация тех версий в "корявых" браузерах ещё сильней навредила репутации JavaScript.

Чтиво

Практически, любая книга по JavaScript - это воплощение Зла.
В них куча ошибок, бестолковых примеров и плохих советов. Важные особенности языка либо плохо рассмотрены, либо не затрагиваются вовсе. Я прошёлся через десятки книг по JavaScript и могу рекомендовать только одну из них: JavaScript: The Definitive Guide (5th Edition) by David Flanagan. (Уважаемые авторы: Если вы написали хорошую книгу, пожалуйста, вышлете мне копию для ознакомления.)

Не "стандартный" подход

Официальная спецификация языка JavaScript опубликована организацией ECMA. Качество этих материалов оставляет желать лучшего. Читать трудно, а понять написанное еще трудней. Эти "стандарты" сыграли свою роль при написании тех книг, про которые я говорил выше, потому что авторы может быть и желали разобраться во всех тонкостях языка с помощью авторитетного источника, но не смогли. Специалистам из ECMA и TC39 должно быть стыдно.

Любители

Большинство из тех, кто программирует на JavaScript - не профессиональные программисты. У них отсутствуют специальные знания и навыки, необходимые для создания качественного кода. Даже несмотря на это, интуитивный синтаксис JavaScript всё равно позволяет создавать полезные вещи. За это JavaScript получил репутацию "любительского" инструмента, который настоящие парни не берут с собой в поход. Собственно, это очередное заблуждение.

А что у нас с ориентацией?

Можно ли назвать JavaScript объектно-ориентированным? Он поддерживает объекты, которые могут хранить данные и иметь методы доступа и манипуляции этими данными. Объекты могут включать в себя другие объекты. В JavaScript нет понятия класс, но есть конструкторы, с помощью которых можно реализовать основную функцию класса, такую, например, как контейнер переменных и методов. Отсутствует наследование от классов (class-oriented inheritance), но есть наследование от прототипа (prototype-oriented inheritance).

Существует два основных способа построения системы объектов - это наследование (is-a) и агрегация (has-a). В JavaScript доступны оба способа, а его динамическая суть позволяет более гибко реализовать агрегацию.

Некоторые господа, в качестве аргумента против того, что JavaScript является по-настоящему объектно-ориентированным, приводят то, что в нём отсутствует механизм инкапсуляции данных. Другими словами, у объектов не может быть скрытых (private) переменных и методов: доступ к ним открыт всем желающим.

Однако, на самом деле объекты JavaScript могут иметь скрытые переменные и методы. Правда, не все об этом знают, поскольку этот язык так до сих пор и не поняли.

А другие, в качестве ещё одного аргумента, напоминают об отсутствии наследования.
Однако, на самом деле JavaScript поддерживает не только классическое наследование, но и другие модели повторного использования кода.

Copyright 2001 Douglas Crockford.
All Rights Reserved Wrrrldwide.