JavaScript: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[отпатрулированная версия][отпатрулированная версия]
Содержимое удалено Содержимое добавлено
Раздел о замыканиях
Добавлен раздел Литература
Строка 1663: Строка 1663:
== См. также ==
== См. также ==
* [[JSON]]
* [[JSON]]
* [[DOM]]
* [[Сравнение языков программирования]]
* [[Сравнение языков программирования]]

== Литература ==
{{начало цитаты|источник=В статье «JavaScript: The World's Most Misunderstood Programming Language»<ref>{{cite web
| last = Crockford
| first = Douglas
| datepublished = 2001
| url = http://javascript.crockford.com/javascript.html
| title = JavaScript: The World's Most Misunderstood Programming Language
| accessdate = 2009-10-23
| lang = en
| description = Статья Соответствие типов содержимого MIME-типам
}}</ref><ref>{{cite web
| last = Сахаров
| first = Денис
| datepublished = 9 февраля 2009 г.
| url = http://blog.digitalbank.org/2009/02/javascript-javascript-mocha-livescript.html
| title = JavaScript: язык, который так до сих пор и не поняли
| accessdate = 2009-10-23
| description = Перевод статьи Дугласа Крокфорда «JavaScript: The World's Most Misunderstood Programming Language»
}}</ref> Дуглас Крокфорд пишет:}}
Практически, любая книга по JavaScript — это воплощение Зла.
В них куча ошибок, бестолковых примеров и плохих советов. Важные особенности языка либо плохо рассмотрены, либо не затрагиваются вовсе. Я прошёлся через десятки книг по JavaScript и могу рекомендовать только одну из них: JavaScript: The Definitive Guide (5th Edition) by David Flanagan. (Уважаемые авторы: Если вы написали хорошую книгу, пожалуйста, вышлете мне копию для ознакомления.)
{{oq|en|Nearly all of the books about JavaScript are quite awful. They contain errors, poor examples, and promote bad practices. Important features of the language are often explained poorly, or left out entirely. I have reviewed dozens of JavaScript books, and I can only recommend one: JavaScript: The Definitive Guide (5th Edition) by David Flanagan. (Attention authors: If you have written a good one, please send me a review copy.)}}
{{конец цитаты}}

С момента публикации статьи ситуация улучшилась. Особенно в отношении англоязычных источников.

=== Систематические многоаспектные книги ===
* {{книга
|автор = Zakas N.
|заглавие = Professional JavaScript for Web Developers
|издание = 2nd ed
|место = USA, Canada
|издательство = Wiley Publishing, Inc.
|год = 2009
|allpages = 840
|isbn = 978-0-470-22780-0
}}
* {{книга
|автор = Flanagan D.
|заглавие = JavaScript: The Definitive Guide
|издание = 5th ed
|издательство = O'Reilly Media, Inc.
|год = 2006
|allpages = 1018
|isbn = 0596101996
}}
** {{книга
|автор = Флэнаган Д.
|заглавие = JavaScript. Подробное руководство
|оригинал = JavaScript. The Definite Guide
|ответственный = Перевод А. Киселева
|издание = 5-е изд
|место = СПб.
|издательство = [[Символ-Плюс (издательство)|«Символ-Плюс»]]
|год = 2008
|страниц = 992
|isbn = 5-93286-103-7
}}

=== ECMAScript ===
* {{книга
|автор = Crockford D.
|часть = A.3. Semicolon Insertion
|заглавие = JavaScript: The Good Parts
|год = 2008
|allpages = 170
|isbn: 978-0-596-51774-8
}}

=== ООП ===
* {{книга
|автор = Resig J.
|заглавие = Pro JavaScript™ Techniques
|издание = 1st ed.
|издательство = Apress
|год = 2006
|allpages = 384
|isbn = 1590597273
}}
** {{книга
|автор = Рейсиг Д.
|заглавие = JavaScript. Профессиональные приёмы программирования
|оригинал = Pro JavaScript™ Techniques
|ответственный = Перевод Н. Вильчинский
|место = СПб.
|издательство = [[Питер (издательство)|Питер]]
|год = 2008
|страниц = 352
|серия = Библиотека программиста
|isbn = 978-5-91180-904-1
|тираж = 2500
}}
* {{книга
|автор = Stefanov S.
|заглавие = Object-Oriented JavaScript: Create scalable, reusable high-quality JavaScript applications and libraries
|издание = 1st ed.
|издательство = Packt Publishing
|год = 2008
|allpages = 356
|isbn = 184719414
}}
* {{книга
|автор = Harmes R., Diaz D.
|заглавие = Pro JavaScript™ Design Patterns
|издание = 1st ed.
|издательство = Apress
|год = 2007
|allpages = 269
|isbn = 159059908X
}}

=== DOM ===
* {{книга
|автор = Keith J.
|заглавие = DOM Scripting: Web Design with JavaScript and the Document Object Model
|издание = 1st ed.
|издательство = friends of ED
|год = 2005
|allpages = 368
|isbn = 1590595335
}}
* {{книга
|автор = Sambells J., Gustafson A.
|заглавие = AdvancED DOM Scripting: Dynamic Web Design Techniques
|издание = 1st ed.
|издательство = friends of ED
|год = 2007
|allpages = 592
|isbn = 1590598563
}}

=== BOM ===
* {{книга
|автор = Kocj P.-P.
|заглавие = ppk on JavaScript
|издание = 1st ed.
|издательство = New Riders Press
|год = 2006
|allpages = 528
|isbn = 0321423305
}}

=== AJAX ===
* {{книга
|автор = Zakas N., McPeak J., Fawcett J.
|заглавие = Professional Ajax
|издание = 2nd ed.
|издательство = Wrox
|год = 2007
|allpages = 624
|серия = Programmer to Programmer
|isbn = 0470109491
}}
* {{книга
|автор = Keith J.
|заглавие = Bulletproof Ajax
|издание = 1st ed.
|издательство = New Riders
|год = 2007
|allpages = 216
|isbn = 0321472667
}}



== Примечания ==
== Примечания ==

Версия от 15:20, 23 октября 2009

JavaScript
Изображение логотипа
Класс языка
Тип исполнения интерпретация, компиляция в байт-код Java, JIT в машинные коды.
Появился в 1995
Автор Брендан Айх
Расширение файлов .js[1]
Выпуск 1.8.1 / 2009
Система типов утиная
Основные реализации SpiderMonkey, Rhino, не указано название статьи, JavaScriptCore, V8
Диалекты JScript, ActionScript, JScript .NET
Испытал влияние Self, Си, Scheme, Perl, Python, Java
Повлиял на Objective-J
Сайт ecma-international.org/… (англ.)
Логотип Викисклада Медиафайлы на Викискладе

JavaScript — скриптовый язык, чаще всего использующийся при создании сценариев поведения браузера, встраиваемых в веб-страницы. Является одной из реализаций языка ECMAScript. Существенной особенностью JavaScript является то, что им не владеет какая-либо компания или организация[2].

Название «JavaScript» является зарегистрированным товарным знаком компании Sun Microsystems, Inc.[3]

История

Предпосылкой появления языка JavaScript стало желание дать разработчикам HTML-документов возможность динамически управлять всеми объектами, описываемыми в коде Web-страницы. Разработанный Бренданом Айхом из компании Netscape язык был включён в браузер Netscape Navigator начиная с версии 2.0B3 в декабре 1995 года. Первоначально язык назывался Mocha, затем он был переименован в LiveScript. На синтаксис оказали влияние языки Си и Java, и, поскольку технология Java была в то время очень модной, LiveScript переименовали в JavaScript, получив соответствующую лицензию у Sun. Реализация компании Microsoft получила название JScript. Internet Explorer поддерживает JScript, начиная с версии 3.0, выпущенной в августе 1996 года. Стандартизация языка ассоциацией ECMA инициирована компанией Netscape. Стандартизированная версия имеет название ECMAScript, описывается стандартом ECMA-262. Первая версия данного стандарта примерно соответствовала JavaScript 1.1.

Популярность

Шаблон:Sect-stub

Возможности языка

JavaScript обладает рядом свойств объектно-ориентированного языка, но благодаря прототипированию поддержка объектов в нём отличается от традиционных ОО языков. Кроме того, JavaScript имеет ряд свойств, присущих функциональным языкам — функции как объекты первого уровня, объекты как списки, карринг (currying), анонимные функции, замыкания (closures) — что придаёт языку дополнительную гибкость.

JavaScript имеет C-подобный синтаксис, но по сравнению с языком С имеет следующие коренные отличия:

Семантика и синтаксис

Синтаксис языка JavaScript во многом напоминает синтаксис Си и Java, семантически же язык гораздо ближе к Self, Smalltalk или даже Лиспу[4][Спецификация 1].

В JavaScript:

Структура языка

Структурно JavaScript можно представить в виде объединения трёх чётко различимых друг от друга частей[5]:

Ядро

ECMAScript не является браузерным языком и на самом деле в нём не определяются методы ввода и вывода информации[5]. Это скорее основа для построения скриптовых языков. Спецификация ECMAScript описывает типы данных, инструкции, ключевые и зарезервированные слова, операторы, объекты, регулярные выражения, не ограничивая авторов производных языков от расширения их новыми составляющими.

Типы данных

В JavaScript поддерживаются пять примитивных типов данных:

Числовой тип данных в JavaScript соответствует 64-битному формату чисел с плавающей запятой, определённому стандартом IEEE 754-2008 за исключением того, что различные значения Not-a-Number, определяемые в стандарте[6], представляются в данном языке единственным специальным значением NaN[Спецификация 3].

Нулевой и неопределённый типы данных Дэвидом Флэнаганом неформально причисляются к тривиальным типам, поскольку каждый из них определяет только одно значение[7].

Также в языке имеется составной тип данных[7]:

Помимо перечисленных шести типов данных в JavaScript имеется поддержка ещё трёх, используемых исключительно для хранения промежуточных результатов вычисляемых выражений[Спецификация 4]:

Инструкции

В JavaScript имеется четырнадцать различных видов инструкций, данные о которых представлены в таблице ниже:

Типы инструкций, определяемые спецификацией языка[Спецификация 5]
Название Оригинальное название Краткие сведения Завершающая ;[Спецификация 6]
Блок Block {[<инструкции>]}
Объявление переменной VariableStatement var <список объявления переменных> +
Пустая инструкция EmptyStatement ; +
Выражение ExpressionStatement [строка до ∉ {{, function}] инструкция +
Условие IfStatement if (<инструкция>) <выражение>[ else <выражение>]
Цикл IterationStatement do <выражение> while (<инструкция>)

while (<инструкция>) <выражение>
for ([<инструкция до начала>]; [<инструкция>]; [<инструкция>]) <выражение>
for (<объявление переменных>; [<инструкция>]; [<инструкция>]) <выражение>
for (<lvalue-выражение> in <инструкция>) <выражение>
for (<объявление переменных> in <инструкция>) <выражение>

+/−[~ 1]
Продолжение ContinueStatement continue [<идентификатор>] +
Прерывание BreakStatement break [<идентификатор>] +
Возврат ReturnStatement return [<инструкция>] +
Сочетание WithStatement with (<инструкция>) <выражение>
Выбор SwitchStatement switch (<инструкция>) case <инструкция>: [<выражения>][ case <инструкция>: [<выражения>] …] [default: [<выражения>]]
Метка LabelledStatement <идентификатор>: <выражение>
Генерация исключения ThrowStatement throw <инструкция> +
Блок try TryStatement try <блок> catch (<идентификатор>) <блок>
try <блок> finally <блок>
try <блок> catch (<идентификатор>) <блок> finally <блок>
Автодополнение строк точками с запятой

Несмотря на обязательность точки с запятой в случаях, отмеченных в четвёртой колонке, спецификация декларирует механизм автодополнения строк точками с запятой, приводящий к тому, что при наличии переноса строки инструкция до переноса может быть снабжена этим знаком[Спецификация 6], что является объектом критики[8].

Инструкции, меняющие смысл при использования перевода строки внутри[Спецификация 6]

  • Унарный постфиксный ++
  • Унарный постфиксный --
  • Продолжение
  • Прерывание
  • Возврат
  • Генерация исключения

Пример изменения смысла инструкции

return
{ 
    status: "complete"
};

Здесь выделенная строка содержит допустимую языком инструкцию и, поскольку, далее следует перевод строки, срабатывает механизм автодополнения строк точками с запятой. Вместо того, чтобы в качестве своего значения функция, содержащая приведённый код, в качестве своего значения вернула объект с полем status, она вернёт undefined.

Помочь избежать трудноуловимых ошибок, возникающих из-за срабатывания механизма автодополнения строк точками с запятой, может учёт этой языковой особенности JavaScript при выработке стандарта оформления кода, а именно при выборе стиля отступов. В частности, широко распространённые сейчас стили Олмана и Уайтсмита, а также стиль Хорстмана и стиль GNU для кода JavaScript являются менее предпочтимыми, нежели стили K&R, 1TBS, BSD KNF или баннерный стиль.

Общепринято в стандартах кодирования прописывать обязательность проставления точек с запятой даже там, где синтаксически их можно опустить из-за механизма автодополнения строк точками с запятой[Стандарты кодирования 1][Стандарты кодирования 2][Стандарты кодирования 3][Стандарты кодирования 4].

Блоки и область видимости

Ещё одной особенностью JavaScript по отношению к другим C-подобным языкам является то, что в данном языке блоки не образуют не указано название статьи. Объявленные в блоке переменные распространяются на всю функцию, содержащей блок[9][10].

В данном участке кода имеет место повторное объявление переменной в выделенных строках:

function foo() {
    var sum = 0;
    for (var i = 0; i < 42; i += 2) {
        var tmp = i + 2;
        sum += i * tmp;
    }
    for (var i = 1; i < 42; i += 2) {
        sum += i*i;
    }
    alert(tmp);
    return sum;
}
foo();

Кроме того, к переменной tmp, объявленной внутри первого из циклов (строка 5), в соответствии с синтаксисом языка вполне законно обратиться извне цикла (строка 10).

Из-за особенностей, связанных с областью видимости и блоками, в целях поддержания качества исходного кода рекомендуется объявлять переменные в начале функций[9][Стандарты кодирования 1][Стандарты кодирования 4].

Объявление переменных

Синтаксис языка допускает явное и неявное объявление переменных. Явным образом переменную можно объявить с помощью ключевого слова var. В таком случае, переменная будет помещена в область видимости, соответствующую функции, в которой она объявляется. Ещё переменные, объявленные с помощью ключевого слова var называют долговременными, поскольку их нельзя удалить с помощью оператора delete[11]. В том случае если переменная объявляется вне функций, она становится глобальной[11]. Синтаксис языка допускает использование переменной без её предварительного объявления. В таком случае речь идёт о неявном объявлении переменной. Кроме того, формальные аргументы функций также могут быть использованы в качестве локальных переменных[12].

Фиксация в стандарте оформления кода необходимости обязательного объявления переменных до их использования[Стандарты кодирования 1][Стандарты кодирования 4] (либо фиксация необходимости использовать пространства имён для всех глобальных объектов[Стандарты кодирования 2]) позволяет избегать трудноуловимых ошибок, предотвращая опасность взаимодействия одинаково названных переменных в разных участках кода[12].

Ключевые и зарезервированные слова

Следующие слова являются зарезервированными в языке и не могут быть использованы как идентификаторы[Спецификация 7]:

 break    else       new    var
 case     finally    return void
 catch    for        switch while
 continue function   this   with
 default  if         throw
 delete   in         try
 do       instanceof typeof

Следующие слова используются как ключевые слова в предложенных расширениях и поэтому являются зарезервированными для возможности адаптировать эти расширения[Спецификация 8]:

 abstract enum       int       short
 boolean  export     interface static
 byte     extends    long      super
 char     final      native    synchronized
 class    float      package   throws
 const    goto       private   transient
 debugger implements protected volatile
 double   import     public

Наличие большого количества ключевых и зарезервированных слов, большинство из которых не используется в языке иногда подвергается критике[13].

Операторы

В JavaScript имеются как операторы, использующие в качестве названий ключевые слова, так и операторы, использующие в качестве названий знаки препинания.

Классификация операторов

По убыванию приоритета операторы JavaScript можно разбить в следующие группы:

  • . (обращение к свойству),[] (индексация массива),() (вызов функции), new (создание нового объекта),
  • ++ (инкремент), -- (декремент), - (унарный минус), + (унарный плюс), ~ (поразрядное дополнение), ! (логическое дополнение), delete (удаление свойства), typeof (определение примитивного типа данных), void (возврат неопределённого значения),
  • * (умножение), / (деление), % (остаток от деления),
  • + (сложение), - (вычитание), + (конкатенация строк),
  • << (сдвиг влево), >> (сдвиг вправо с расширением знакового разряда), >>> (сдвиг вправо с дополнением нулями),
  • < (меньше), <= (меньше или равно), > (больше), >= (больше или равно), instanceof (проверка типа объекта), in (проверка наличия свойства),
  • == (проверка на равенство), != (проверка на неравенство), === (проверка на идентичность), !== (проверка на неидентичность),
  • & (поразрядная конъюнкция),
  • ^ (поразрядное сложение по модулю 2),
  • | (поразрядная дизъюнкция),
  • && (конъюнкция),
  • || (дизъюнкция),
  • ?: (тернарная условная операция),
  • = (присваивание), *=, /=, +=, -=, <<=, >=, >>>=, &=, ^=, |= (присваивание с операцией),
  • , (множественное вычисление)[14].

Операторы ++, --, -, +, ~, !, delete, typeof, void, ?:, =, *=, /=, +=, -=, <<=, >=, >>>=, &=, ^=, |= правоассоциативны (то есть для них a op b op c эквивалентно a op b op c). Остальные операторы JavaScript левоассоциативны[15].

По арности операторы JavaScript делятся на следующие группы:

  • унарные (delete, void, typeof, ++, --, - (унарный минус), + (унарный плюс), ~, !, new)[Спецификация 9],
  • бинарные (., [], (), *, /, %, + (сложение), - (вычитание), + (конкатенация строк), <<, >>, >>>, <, <=, >, >=, instanceof, in, ==, !=, ===, !==, &, ^, |, &&, ||, =, *=, /=, +=, -=, <<=, >=, >>>=, &=, ^=, |=, ,),
  • тернарные (?:)[16],
  • операторы, не имеющие фиксированного количества операндов (())[17].

По положению знака операции относительно операндов операторы JavaScript делятся на следующие группы:

  • префиксные (например, new, ++ (префиксный инкремент),
  • инфиксные (например, +, -),
  • постфиксные (например, ++ (постфиксный инкремент), -- (постфиксный декремент).

Также операторы классифицируются по типу операндов[18] и по характеру осуществляемого действия.

Особенности операторов JavaScript

В JavaScript нет оператора, позволяющего проверить, относится ли метод или атрибут непосредственно к объекту или является унаследованным. Такая проверка осуществляется с помощью метода hasOwnProperty(). В связи с тем, что данный метод не является оператором, он может быть переписан у объекта другим методом, либо даже атрибутом[19].

Оператор + является единственным арифметическим операторов в языке, который перегружен для строковых аргументов. Таким образом, если оба его операнда являются числами, он вычисляет их сумму, но если хотя бы один из операндов — строка, + действует как конкатенатор[20].

В отличии от языков, где void является типом данных, в JavaScript это оператор, возвращающий значение undefined[21].

Оператор == перед проверкой на равенство осуществляет преобразование типов, что, в конечном счёте, может привести к неочевидным результатам[22].

Пример результатов работы == (во всех перечисленных случаях значением оператора с теми же аргументами будет false):

alert("NaN" == NaN);       // false
alert(NaN != NaN);         // true
alert(true == 1);          // true
alert(true == 42);         // false
alert(null == 0);          // false
alert(0 == "");            // true
alert("" == 0);            // true
alert("false" == false);   // false
alert(false == 0);         // true
alert(undefined == false); // false
alert(null == false);      // false
alert(undefined == null);  // true
alert(" \t\r\n " == 0);    // true

Функции

Функции в JavaScript являются объектами[23][24]. Конструктор, с помощью которого они создаются — Function(). Функции, как и любые другие объекты, могут храниться в переменных, объектах и массивах, могут передаваться как аргументы в другие функции и могут возвращаться функциями. Функции, как и любые другие объекты, могут иметь поля и методы. Существенной специфической чертой функций является то, что они могут быть вызваны[23].

Задание функций

В JavaScript имеется два типа функций:

  • внутренние функции (например, parseInt),
  • функции, определённые в тексте программы.

Внутренние функции представляют собой встроенные объекты (см. ниже), не обязательно реализованные на ECMAScript[Спецификация 10].

В тексте программы именованную функцию в JavaScript можно определить одним из следующих способов:

// объявление функции
function sum(arg1, arg2) {
    return arg1 + arg2;
}

// задание функции с помощью инструкции
var sum2 = function(arg1, arg2) {
    return arg1 + arg2;
};

// задание функции с использованием объектной формы записи
var sum3 = new Function("arg1", "arg2", "return arg1 + arg2;");

Последний способ наименее предпочтителен, поскольку де-факто сводится к заданию функции с помощью инструкции, но при этом порождает двойную интерпретацию кода (дополнительная интерпретация возникает при передаче кода в конструктор), что может негативно отразиться на производительности[24].

Первые два способа дают похожий, но не идентичный эффект. Усугубляет ситуацию то, что инструкция, использующаяся при задании функции может выглядеть очень похоже на объявление функции: во-первых, за ключевым словом function может следовать идентификатор[Спецификация 11], во-вторых, точка с запятой может быть опущена в силу механизма автодополнения строк точками с запятой[Спецификация 6]. Пример:

// объявление функции
function sum(arg1, arg2) {
    return arg1 + arg2;
}

// задание функции с помощью инструкции
var sum2 = function sum(arg1, arg2) {
    return arg1 + arg2;
}

function bar(){};  // использование объявления функции
а(function bar(){}) // использование соответствующей инструкции

Наиболее существенной разницей между заданием функции с использовании объявления и заданием функции с помощью инструкции является то, что объявления осуществляются до выполнения кода, а инструкции по мере его выполнения[24]. Пример, иллюстрирующий разницу в порядке выполнения кода:

alert(sum(3, 4)); // 7: объявление функции уже произошло к моменту выполнения этой строки
function sum(arg1, arg2) {
    return arg1 + arg2;
}

alert(sum2(3, 4)); // ошибка<ref name="zakasFunctionType"/>: sum2 ещё не задана
var sum2 = function(arg1, arg2) {
    return arg1 + arg2;
};

Объявлением функций не следует пользоваться внутри условных конструкций[25], хотя в Gecko-браузерах это обработается интуитивным образом за счёт реализованного механизма функций как выражений[26].

Присваивания функций

Поскольку функции в JavaScript являются объектами, то есть относятся к ссылочному типу данных, идентификаторы функций являются переменными, хранящими ссылку на функцию. Проиллюстрировать это можно следующим кодом:

var sum = function(arg1, arg2) {
    return arg1 + arg2;
};

alert(sum(3, 4));    // 7
var sum2 = sum;
alert(sum2(4, 2));   // 6
sum = null;
alert(sum2(42, 42)); // 84

В выделенной строке следует обратить внимание на отсутствие оператора вызова функции (()) в правой части присваивания. Если бы в этой строке вместо sum было указано sum(), переменной sum2 присвоилась бы не функция, а результат её вызова. Ещё внимания заслуживает то, что после присваивания sum2 указывает не на копию функции, а на ту самую функцию, на которую указывает sum.

Перегрузка функций

В JavaScript перегрузка функций не относится к свойствам языка, а её эффект обеспечивается за счёт использования других механизмов.

Пример, показывающий отсутствие перегрузки функций:

function sum(arg1, arg2) {
    return arg1 + arg2;
}

function sum(arg1, arg2, arg3) {
    return arg1 + arg2 + arg3;
}

alert(sum(3, 4));       // NaN
alert(sum(3, 4, 5));    // 12

Если объявлено несколько функций с одинаковыми названиями, более поздние объявления перезаписывают ранние объявления[24].

Тем не менее, эффект перегрузки функций достижим.

1. Проверка на undefined. Для того, чтобы проверить, передан ли в функцию фактический аргумент, можно осуществить проверку формального аргумента на идентичность значению undefined. Например:

function sum(arg1, arg2, arg3) {
    if (arg3 !== undefined) {
        return arg1 + arg2 + arg3;
    } else {
        return arg1 + arg2;
    }
}

alert(sum(3, 4));       // 7
alert(sum(3, 4, 5));    // 12

2. Проверка типа. Кроме того, typeof, instanceof, constructor могут быть использованы для выяснения типа фактических аргументов и кастомизации поведения функции в зависимости от них.

function sum(arg1, arg2, arg3) {
    switch (typeof arg3) {
        case "undefined":
            return arg1 + arg2;
        case "number":
            return arg1 + arg2 + arg3;
        default:
            return arg1 + arg2 + " (" + arg3 + ")";
    }
}

alert(sum(3, 4));       // 7
alert(sum(3, 4, 5));    // 12
alert(sum(3, 4, "!"));  // "12 (!)"

3. Обращение к данным об аргументах. В функциях JavaScript можно получить доступ к данным об аргументах с помощью псевдо-массива arguments. Он, в частности, позволяет воспользоваться индексированием для доступа к конкретным переданным аргументам[27][24] и полем length — для выяснения количества фактически переданных аргументов, что может быть полезно при применении парадигмы обобщённого программирования.

function sum() {
    var res = 0;
    for (var i = 0; i < arguments.length; i++) {
        res += arguments[i];
    }
    return res;
}

alert(sum(3, 4));           // 7
alert(sum(3, 4, 5));        // 12
alert(sum(3, 4, 5, 7, 9));  // 28
Рекурсия

Функции JavaScript допускают рекурсивный вызов. При задании функции с помощью инструкции без указания идентификатора после ключевого слова function внутри функции можно обратиться к ней с помощью метода callee псевдо-массива arguments.

Пример рекурсивного вычисления факториала:

var factorial = function(step, res) {
    res = res || 1; 
    if (step < 2) { 
        return res; 
    } 
    return arguments.callee(step - 1, step * res); 
}; 

alert(factorial(5));           // 120

На данный момент в JavaScript не реализована хвостовая рекурсия, применяемая для оптимизации рекурсивных вызовов[28].

Замыкания

Функциям в JavaScript присуща лексическая область видимости. Это означает, что область видимости определяется в момент определения функции (в отличии от динамической области видимости, при которой область видимости определяется в момент вызова функции)[29].

При раскомментировании выделенной строки на экран будет выводиться не number, а undefined:

var a = 42;
function foo() {
    alert(typeof a);
    // var a = 10;
}
foo();

При объявлении функции последовательность областей видимости, относящихся к вложенным функциям сохраняется как составляющая состояния функции. То есть в процессе выполнения JavaScript-программы функции, обладающие доступом к локальным переменным объемлющих функций, сохраняют такой доступ на протяжении всего выполнения программы[29].

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

(function() {

// Участок программы, доступ к переменным которого необходимо изолировать извне.

})();

При этом определённые в участке программы функции становятся вложенными по отношению к добавленной анонимной функции и в них возможно осуществление доступа к локальным переменным анонимной функции (которые до её введения были глобальными). Однако извне анонимной функции доступ к ним осуществить нельзя.

Замыкания используются не только для запрещения доступа к ряду переменных, но и к модификации такого доступа. Это достигается с помощью функций, возвращающих другие функции. Пример функции-генератора последовательных чисел:

var uniqueId = (function() {
    var id = 0;
    return function() { return id++; };
})();

var aValue = uniqueId();
var anotherValue = uniqueId();

За счёт использования замыкания доступ к переменной id имеет только функция, которая была присвоена переменной uniqueId.

Пример карринга:

var multNumber = function(arg) {
    return function(mul) {
        return arg * mul;
    };
};

var multFive = multNumber(5);
alert(multFive(7)); //35

Пример создания объекта, позволяющего осуществить доступ к полю исключительно с помощью своих методов[30]:

var myObject = function() {
    var value = 0; 
    return { 
        increment: function (inc) { 
            value += typeof inc === 'number' ? inc : 1; 
        }, 
        getValue: function (  ) { 
            return value; 
        } 
    } 
}();

alert(myObject.value === undefined); // true
alert(myObject.getValue()); // 0
myObject.increment(9)
myObject.increment(7)
alert(myObject.getValue()); 16

Пользуясь этим приёмом, можно использовать замыкание для эмуляции констант[31].

var getConstant = (function() {
  var constants = {
    UPPER_BOUND: 100,
    LOWER_BOUND: -100
  };
  return function(constantName) {
    return constants[constantName];
  };
})();

alert(getConstant("LOWER_BOUND")); // -100

Объекты

Реализация в языке

Объекты ECMAScript представляют собой неупорядоченные коллекции свойств, каждое из которых имеет один или более атрибутов, которые определяют как может быть использовано свойство — например, если в качестве значения атрибута ReadOnly установлена истина, то любая попытка выполняющегося ECMAScript-кода поменять значение этого свойства останется безрезультатной. Свойства представляют собой контейнеры, инкапсулирующие другие объекты, значения примитивных типов и методы.[Спецификация 12]

Атрибуты свойств объектов ECMAScript[Спецификация 13]
Название Описание
ReadOnly Свойство является свойством только для чтения. Попытка поменять значение этого свойства, предпринятая в программе, останется безрезультатной. В некоторых случаях значение свойства с установленным атрибутом ReadOnly меняется в силу действий среды расширения языка, поэтому ReadOnly не следует понимать как неизменное
DontEnum Свойство не перечисляется циклом for-in
DontDelete Попытки удалить это свойство будут проигнорированы
Internal Свойство является внутренним. Оно не имеет названия и к нему нельзя получить доступ с помощью аксессоров. Доступ к этим свойствам определяется реализацией языка.


Объекты ECMAScript подразделяются на базовые (native) и объекты расширения (host). Под базовыми понимаются любые объекты, независимые от окружения, относящегося к расширению языка. Некоторые из базовых объектов являются встроенными (built-in): существующими с самого начала выполнения программы. Другие могут быть созданы, когда программа выполняется. Объекты расширения предоставляются расширением ECMAScript, а для JavaScript это значит, что они входят в объектную модель документа или в объектную модель браузера.[Спецификация 2]

Базовые объекты ECMAScript[Спецификация 14]
Название Может использоваться как функция Может использоваться как конструктор
Global
Object + +
Function + +
Array + +
String + +
Boolean + +
Number + +
Math
Date + +
RegExp + +
Error + +
EvalError + +
RangeError + +
ReferenceError + +
SyntaxError + +
TypeError + +
URIError + +
Синтаксис

Для задания объектов может использоваться объектная и литеральная формы. Объектная форма задания объекта имеет синтаксис, аналогичный Java, но, в отличии от него, скобки в JavaScript требуется использовать только при передаче аргументов в конструктор[32]. Синтаксически следующие записи эквивалентны:

var obj1 = new Object();
var obj2 = new Object;
var obj3 = {};

Однако второй вариант использовать не рекомендуется[32]. Дуглас Крокфорд рекомендует избегать и первого варианта, отдавая предпочтение литеральной форме, по его мнению, относящейся к самым большим достоинствам языка[33].

Спецификация языка оперирует понятием свойства объекта, называя методом использующуюся в качестве свойства объекта функцию[Спецификация 2].

Каждый объект в языке имеет следующие свойства:

Свойства объектов JavaScript[32]
Название Краткое описание
constructor Функция, использованная для создания объекта (в примерах выше это Object())
hasOwnProperty(propertyName) Показывает, существует ли данное свойство в объекте (не в его прототипе)
isPrototypeOf(object) Определяет, является ли данный объект прототипом объекта-аргумента
propertyIsEnumerable(propertyName) Показывает, является ли свойство с данным названием перечислимым в цикле for-in
toString() Возвращает представление объекта в виде строки
valueOf() Возвращает значение this. Если же объект является результатом вызова конструктора объекта расширения, значение valueOf() зависит от реализации[Спецификация 2]. Зачастую в качестве возвращаемого значения выступает значение примитивного типа, соответствующее объекту. Как правило, результат данного метода совпадает с результатом toString(). Объекты, созданные с помощью конструктора Date() — яркий пример, где результаты toString() и valueOf() не совпадает[32].

Доступ к свойствам объекта осуществляется использованием точечной и скобочной записи:

var obj = new Object();
alert(obj.constructor === obj["constructor"]); // true — использование точечной и скобочной записи для доступа к полю

var foo = obj["toString"]; // использование скобочной записи для сохранения функции в переменную
var result = obj["toString"](); // сохранение результата вызова функции в переменную
alert(foo()); // вывод на экран результата вызова сохранённой функции
alert(result);

var boo = obj.toString; // аналогично с использованием точечной записи
var res = obj.toString();
alert(boo());
alert(res);

Задание новых свойств может осуществляться динамически.

var country            = new Object();
country["name"]       = "Russia"; // использование скобочной записи
country.foundationYear = 862; // использование точечной записи

var country2 = {
    "name":           "Russia",
    "foundationYear": 862
}; // использование литеральной формы

Регулярные выражения

Синтаксис и функциональность регулярных выражений в JavaScript сформировались под влиянием Perl 5[Спецификация 15] и допускают два вида синтаксиса: литеральный и объектный.

var literalWay = /pattern/flags;
var objectWay  = new RegExp(pattern, flags);

В первом случае шаблон (pattern) и флаги (flags) указываются явно, не сопровождаясь дополнительными избыточными синтаксическими знаками: их разделителями служат слеши. Во втором случае шаблон и флаги должны представлять собой переменные, содержащие строковые значения, либо непосредственно строковые значения. Литеральная форма записи предпочтительнее тем, что не требует двойного[~ 2] экранирования метасимволов регулярных выражений, в отличии от объектной формы[34].

В качестве флагов в JavaScript могут использоваться следующие символы:

Флаги регулярных выражений[34][Спецификация 15]
Флаг Описание
g глобальный режим: шаблон применяется ко всем соответствиям в строке, работа регулярного выражения не останавливается после первого найденного соответствия шаблону
i игнорирование регистра: при поиске соответствий регистр символов шаблона и строки игнорируются
m многострочный режим: строка, содержащая символы перевода строки, трактуется как несколько строк, разделённых символами перевода строки; работа регулярного выражения осуществляется во всех строках

Каждое регулярное выражение представляет собой объект со следующими полями:

Поля объекта регулярное выражение в JavaScript[34][Спецификация 15]
Поле Тип Описание
global логический показывает, установлен ли флаг g
ignoreCase логический показывает, установлен ли флаг i
multiline логический показывает, установлен ли флаг m
lastIndex числовой соответствует номеру позиции в строке, в которой обнаружилось совпадение с шаблоном в результате предыдущего применения регулярного выражения или 0, если регулярное выражение ранее не применялось
source строковый строка, соответствующая шаблону регулярного выражения

Кроме того, для регулярных выражений определены следующие методы:

Методы объекта регулярное выражение в JavaScript[34][Спецификация 15]
Поле Тип возвращаемого значения Описание
exec(handledString) объектный (массив) или null формирует массив подстрок, соответствующих заданному шаблону с учётом выставленных флагов. null, если никакая подстрока не соответствует шаблону
test(handledString) логический true, если нашлась строка, соответствующая шаблону и false в противном случае

Особенности наследования в JavaScript

Шаблон:Sect-stub

Эмуляция классов

В языке нет классов, однако их можно эмулировать за счёт использования конструкторов. Пример эмуляции класса в JavaScript:

function MyClass() {
    this.myValue1 = 1;
    this.myValue2 = 2;
}

MyClass.prototype.myMethod = function() {
    return this.myValue1 * this.myValue2;
}

var mc      = new MyClass();
mc.myValue1 = mc.myValue2 * 2;
var i       = mc.myMethod();

Объектная модель документа

Шаблон:Sect-stub

Объектная модель браузера

Шаблон:Sect-stub

Область применения

JavaScript в данный момент полностью занимает нишу браузерных языков.

JavaScript также находит применение в качестве скриптового языка доступа к объектам приложений. Платформа Mozilla (XUL/Gecko) использует JavaScript. Среди сторонних продуктов, например, Java, начиная с версии 6, содержит встроенный интерпретатор JavaScript на базе Rhino. Сценарии JavaScript поддерживаются в таких приложениях Adobe, как Adobe Photoshop, Adobe Dreamweaver, Adobe Illustrator или Adobe InDesign.

JavaScript используется и для написания прикладного ПО. Одним из ярких примеров является Mozilla Firefox, 57 % исходного кода которого написано на JavaScript (для сравнения, следующим языком программирования по объёму кодовой базы Firefox является C++, доля которого составляет 17 %)[35].

Использование на веб-страницах

Расположение внутри страницы

JavaScript-код включается в код страницы и исполняется интерпретатором, встроенным в браузер. JavaScript заключается в теги <script></script>.

Скрипт, выводящий модальное окно с классической надписью «Hello, World!» внутри браузера:

<script type="text/javascript">
alert('Hello, World!');
</script>
Расположение внутри тега

Следуя концепции интеграции JavaScript в существующие системы, браузеры поддерживают включение скрипта, например, в значение атрибута события:

<a href="delete.php" onclick="return confirm('Вы уверены?');">Удалить</a>
Отделение от разметки

В приведённом примере при нажатии на ссылку функция confirm('Вы уверены?'); вызывает модальное окно с надписью «Вы уверены?», а return false; блокирует переход по ссылке. Разумеется, этот код будет работать только если в браузере есть и включена поддержка JavaScript, иначе переход по ссылке произойдет без предупреждения.

Использование кода JavaScript в контексте разметки страницы в рамках ненавязчивого JavaScript расценивается как плохая практика. Аналогом (при условии снабжения ссылки идентификатором alertLink)

<a href="delete.php" id="alertLink">Удалить</a>

приведённого примера может выступать, например, следующий фрагмент JavaScript:

window.onload = function() {
    var linkWithAlert = document.getElementById("alertLink");
    linkWithAlert.onclick = function() {
        return confirm('Вы уверены?');
    };
};

Вынесение в отдельный файл

Есть и третья возможность подключения JavaScript — написать скрипт в отдельном файле, а потом подключить его с помощью конструкции

<script type="text/javascript" src="http://Путь_к_файлу_со_скриптом"></script>

Атрибуты тега script

Тег script, широко используемый для подключения к странице JavaScript, имеет несколько атрибутов.

  • обязательный[36] атрибут type для указания MIME-типа содержимого.

В запросе комментариев RFC-4329, определяющем[37] MIME-тип, соответствующий JavaScript, указано:[38]:

Известно, что использование «text» в качестве типа верхнего уровня данного типа содержимого проблематично. Поэтому данный документ определяет text/javascript and text/ecmascript, отмечая их «устаревшими». Использование экспериментальных и незарегистрированных медиа-типов, таких как перечисленные в части выше, не приветствуется.

Медиа-типы

  • application/javascript,
  • application/ecmascript,

которые также определяются в этом документе, предназначены для практического использования, им следует отдавать предпочтение.

Однако, согласно спецификации HTML 4.01 в качестве значения type должно быть[36] указано устаревшее[38][39] "text/javascript". Так как JavaScript является языком программирования по умолчанию во всех браузерах, начиная с Netscape 2[40], Дуглас Крокфорд придерживается мнения о нецелесообразности использования атрибута type, рекомендуя указывать его в XHTML, так как хотя он, по мнению Крокфорда и не нужен, но обязателен и не указывать в HTML[41].

  • необязательный атрибут src, принимающий в качестве значения адрес к файлу со скриптом.
  • необязательный атрибут charset, используемый вместе с src для указания используемой кодировки внешнего файла.
  • необязательный атрибут defer, используемый для того, чтобы показать, что скрипт не генерирует никакого содержимого (что означает, в частности, то, что в этом скрипте отсутствует вызов document.write()).

При этом атрибут language (language="JavaScript"), несмотря на его активное использование (в 2008 году этот атрибут был наиболее часто используемым у тега <script>[42]), относится к не рекомендуемым (deprecated), отсутствует в DTD, поэтому считается некорректным[43].

Браузерные операционные системы

Пример сеанса eyeOS

JavaScript широко используется в браузерных операционных системах. Так, например, исходный код IndraDesktop WebOS на 73% состоит из JavaScript[44], код браузерной операционной системы IntOS — на 70%[45]. Доля JavaScript в исходном коде eyeOS — 21%[46], однако и в рамках этой операционной системы JavaScript играет важную роль, участвуя в визуализации на клиенте и являясь необходимым механизмом для коммуницирования клиента и сервера[47].

Мобильные приложения

Перевод мобильных устройств Palm на использование Palm webOS в качестве операционной системы с Mojo SDK в качестве комплекта средств разработки[48] позволяет использовать JavaScript в качестве языка разработки мобильных приложений[49][50].

Букмарклеты

JavaScript используется для создания небольших программ, размещаемых в закладки браузера. При этом используются URL-адреса со спецификатором javascript:[51].

AJAX

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

Версии

JavaScript JScript ECMAScript
1.0 (Netscape 2.0, март 1996) 1.0 (ранние версии IE 3.0, август 1996) Оригинальная версия языка JavaScript. Имела много ошибок и на данный момент безусловно устарела.
1.1 (Netscape 3.0, август 1996) 2.0 (поздние версии IE 3.0, январь 1997) В данной версии был реализован объект Array и устранены наиболее серьезные ошибки.
1.2 (Netscape 4.0, июнь 1997) Реализован переключатель switch, регулярные выражения, а также ряд других особенностей. Практически приведён в соответствии со спецификацией ECMA v1.
1.3 (Netscape 4.5, октябрь 1998) 3.0 (IE 4.0, октябрь 1997) Редакция 1 (июнь 1997) / редакция 2 (июнь 1998). Исправлена несовместимость по JavaScript 1.2. Совместим с ECMA v1.
1.4 (только Netscape Server) 4.0 (Visual Studio 6, нет версии IE) Применяется только в Netscape-серверных продуктах.
5.0 (IE 5.0, март 1999)
5.1 (IE 5.01)
1.5 (Netscape 6.0, ноябрь 2000; также
поздние версии Netscape и Mozilla)
5.5 (IE 5.5, июль 2000) Редакция 3 (декабрь 1999).Реализовано исключение погрузочно-разгрузочных операций. Совместим с ECMA v3.
5.6 (IE 6.0, октябрь 2001)
1.6 (Gecko 1.8, Firefox 1.5, ноябрь 2005) Редакция 3 с некоторыми совместимыми улучшениями: E4X, дополнения к Array (например, Array.prototype.forEach), упрощения для Array и String [52]
1.7 (Gecko 1.8.1, Firefox 2.0, осень 2006), расширение JavaScript 1.6 Редакция 3, с добавлением всех улучшений из JavaScript 1.6, генераторов и списочных выражений (list comprehensions, [a*a for (a in iter)]) из Python, блоковых областей с использованием let и деструктурирующего присваивания (var [a, b] = [1, 2]) [53]
JScript .NET (ASP.NET; нет версии IE) (Считается, что JScript .NET разработан при участии других членов ECMA)
2.0 Редакция 4 (разработка не закончена[54], название зарезервировано ECMA, но не было использовано для публикации[Спецификация 16])
Редакция 5 (ранее известная под названием ECMAScript 3.1.[54] Финальная версия планируется к принятию до конца 2009 года.[54])

Библиотеки JavaScript

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

Среди известных JavaScript библиотек можно отметить Adobe life, Dojo Toolkit, Extjs, jQuery, Mootools, Prototype, Qooxdoo.

Отладка

В JavaScript доступ к отладчикам становится бесценным при разработке крупных нетривиальных программ, потому что в процессе разработки возникают разногласия с разными браузерами (в частности с DOM). Полезно иметь доступ к отладчику для каждого из браузеров, в которых будет работать веб-приложение. В настоящее время, Internet Explorer, Firefox, Safari, Google Chrome, а также Opera имеют отладчики сценариев.

Internet Explorer имеет три отладчика: Microsoft Visual Studio является самым полным из трёх, следом за ним следует Microsoft Script Editor (компонент Microsoft Office), и, наконец, свободный Microsoft Script Debugger, который гораздо более простой, чем два других. Бесплатный Microsoft Visual Web Developer Express предоставляет ограниченную версию с отладочной функцией JavaScript в Microsoft Visual Studio. В восьмой версии в IE вместе с инструментами для разработчиков появился встроенный отладчик.

В Opera также имеется собственный отладчик — Opera Dragonfly.

Разработку веб-приложений в Firefox можно отлаживать при помощи плагина Firebug или отладчика Venkman.

WebKit Web Inspector включает в себя отладчик JavaScript, в Safari от Apple.

Средства тестирования

FireUnit — плагин, написанный для аддона FireBug. FireUnit написан Джоном Резигом и Яном Одварко. Тестирование происходит на основе строковых переменных, поэтому тестирование с использованием данных внешних источников может оказаться нетривиальной задачей.

YUI test — является частью YUI.

JSUnit — порт JUnit для языка JavaScript. Из минусов можно отметить необходимость установки виртуальной машины Java (если необходимо использовать JsUnit Server, что в большинстве случаев не требуется).

Связь с другими языками

Взаимное влияние

Стандартизация JavaScript потребовала уйти от проблем с торговыми марками, поэтому стандарт ECMA 262 называет язык ECMAScript, три редакции которого были опубликованы с начала работы над ним в ноябре 1996 года.

Objective-J — это строгое компактное надмножество JavaScript, в котором к JavaScript добавлено традиционное наследование, динамической диспетчеризацией в стиле Smalltalk/Objective-C и псевдостатичная типизация.

VBScript от Microsoft, подобно JavaScript, может выполняться на стороне клиента в веб-страницах. VBScript имеет синтаксис, производный от Visual Basic и поддерживается только в Internet Explorer.

JSON, или объектная нотация JavaScript, это формат обмена данными общего назначения, определённый как подмножество JavaScript.

Scheme также является родственным JavaScript языком, поскольку оба представляют богатые возможности функционального программирования: JavaScript является динамическим языком, поддерживает гибкие массивы, может легко симулировать s-выражения, имеет поддержку лямбда-выражений.[55]

JavaScript и Java

Общим заблуждением является то, что JavaScript аналогичен или тесно связан с Java, это не так. Оба языка имеют C-подобный синтаксис, являются объектно-ориентированными и как правило широко используются в клиентских веб-приложениях, на этом их сходство заканчивается:

  • Java использует парадигму ООП из C++; JavaScript использует прототипный подход (где нет классов, а объект — просто хеш);
  • Java имеет статическую типизацию; JavaScript имеет динамическую типизацию (значение переменной может содержать объекты любого типа и даже функции);
  • Java загружается из скомпилированного байт-кода; JavaScript интерпретируется напрямую из файла (но часто с незаметной JIT-компиляцией).

Реализация

На JavaScript реализованы интерпретаторы ряда языков программирования, что позволяет использовать для них как среду выполнения веб-браузер. Им можно найти применение, например, в образовательных целях[56].

Quite BASIC представляет собой бесплатную проприетарную реализацию языка программирования Basic[57].

HotRuby — свободная реализация виртуальной машины Руби на JavaScript и Flash. Позволяет выполнять байткод, полученных в результате компиляции YARV. Реализует большую часть грамматики Руби. Пока не реализован механизм исключений и большая часть встроенных функций и классов[58]. При помощи HotRuby на веб-страницах можно использовать руби-скрипты. Для этого руби-код следует поместить в блок:

<script type="text/ruby">  </script>

HotRuby выделит его, пошлёт на компиляцию удалённому скрипту и затем отобразит результаты работы на странице[59]. Данная реализация позволяет осуществлять доступ из Руби к объектам JavaScript[60].

Также существуют свободная не указано название статьи-реализация интерпретатора JavaScript s-mr[61], реализация на JavaScript PostScript и PDF WPS, использующая HTML 5 Canvas[62], реализация ассемблера для восьмиразрядного микропроцессора MOS Technology 6502[63], реализация Objective-J Cappuccino[64], реализация Haskell ycr2js[65], реализации Prolog Monash Toy Prolog[66] и ioctl[67], а также реализация языка программирования не указано название статьи[68].

Взаимодействие

В некоторых языках программирования существуют средства поддержки взаимодействия с JavaScript-кодом.

  • Для PHP имеется пакет HTML_Javascript, предоставляющий интерфейс создания простых JavaScript-программ[69].
  • Соответствующий пакет для TCL называется ::javascript. Он предоставляет команды генерации кода HTML и JavaScript[70].
  • Пакет для Perl Data::JavaScript позволяет переносить структуры данных Perl в JavaScript-код[71].

Поддержка браузерами

На сегодняшний день поддержку JavaScript обеспечивают современные версии всех наиболее часто используемых браузеров. Тем не менее, иногда пользователи сталкиваются с сообщениями, что поддержку JavaScript следует включить для работы с тем или иным веб-приложением. Сделать это можно с помощью соответствующего пункта меню. Шаблон:Sect-stub

См. также

Литература

В статье «JavaScript: The World's Most Misunderstood Programming Language»[72][73] Дуглас Крокфорд пишет::

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

С момента публикации статьи ситуация улучшилась. Особенно в отношении англоязычных источников.

Систематические многоаспектные книги

  • Zakas N. Professional JavaScript for Web Developers. — 2nd ed. — USA, Canada: Wiley Publishing, Inc., 2009. — 840 p. — ISBN 978-0-470-22780-0.
  • Flanagan D. JavaScript: The Definitive Guide. — 5th ed. — O'Reilly Media, Inc., 2006. — 1018 p. — ISBN 0596101996.
    • Флэнаган Д. JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — 992 с. — ISBN 5-93286-103-7.

ECMAScript

  • Crockford D. A.3. Semicolon Insertion // JavaScript: The Good Parts. — 2008. — 170 p.

ООП

  • Resig J. Pro JavaScript™ Techniques. — 1st ed.. — Apress, 2006. — 384 p. — ISBN 1590597273.
    • Рейсиг Д. JavaScript. Профессиональные приёмы программирования = Pro JavaScript™ Techniques / Перевод Н. Вильчинский. — СПб.: Питер, 2008. — 352 с. — (Библиотека программиста). — 2500 экз. — ISBN 978-5-91180-904-1.
  • Stefanov S. Object-Oriented JavaScript: Create scalable, reusable high-quality JavaScript applications and libraries. — 1st ed.. — Packt Publishing, 2008. — 356 p. — ISBN 184719414.
  • Harmes R., Diaz D. Pro JavaScript™ Design Patterns. — 1st ed.. — Apress, 2007. — 269 p. — ISBN 159059908X.

DOM

  • Keith J. DOM Scripting: Web Design with JavaScript and the Document Object Model. — 1st ed.. — friends of ED, 2005. — 368 p. — ISBN 1590595335.
  • Sambells J., Gustafson A. AdvancED DOM Scripting: Dynamic Web Design Techniques. — 1st ed.. — friends of ED, 2007. — 592 p. — ISBN 1590598563.

BOM

  • Kocj P.-P. ppk on JavaScript. — 1st ed.. — New Riders Press, 2006. — 528 p. — ISBN 0321423305.

AJAX

  • Zakas N., McPeak J., Fawcett J. Professional Ajax. — 2nd ed.. — Wrox, 2007. — 624 p. — (Programmer to Programmer). — ISBN 0470109491.
  • Keith J. Bulletproof Ajax. — 1st ed.. — New Riders, 2007. — 216 p. — ISBN 0321472667.


Примечания

  1. Miller M., Borins M., Bynens M., Farias B. Updates to ECMAScript Media Types (англ.)IETF, 2022. — doi:10.17487/RFC9239
  2. Рейсиг Д. 4. Инструменты отладки и тестирования // JavaScript. Профессиональные приёмы программирования = Pro JavaScript™ Techniques / Перевод Н. Вильчинский. — СПб.: Питер, 2008. — С. 76. — (Библиотека программиста). — 2500 экз. — ISBN 978-5-91180-904-1.
  3. Sun Microsystems. Sun Trademarks (англ.). Официальный сайт Sun Microsystems. — Перечень торговых марок, зарегистрированных Sun Microsystems. Дата обращения: 24 сентября 2009.
  4. Mikkonen T., Taivalsaari A. Using JavaScript as a Real Programming Language (англ.). — USA: Sun Microsystems Laboratories, 2007.
  5. 1 2 Zakas N. 1. What is JavaScript? // Professional JavaScript for Web Developers. — 2nd ed. — USA, Canada: Wiley Publishing, Inc., 2009. — P. 3. — ISBN 978-0-470-22780-0.
  6. Aiken A., Applegate M., Bailey D. and others. 6.2. Operations with NaNs // IEEE Standard for Floating-Point Arithmetic / Chair Zuras D., Editor Cowlishaw M.. — USA, 2008. — P. 34. — ISBN 978-0-7381-5753-5.
  7. 1 2 Дэвид Флэнаган. 3. Типы данных и значения // JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — С. 39. — ISBN 5-93286-103-7.
  8. Crockford D. A.3. Semicolon Insertion // JavaScript: The Good Parts. — 2008. — 170 p.
  9. 1 2 Crockford D. A.2. Scope // JavaScript: The Good Parts. — 2008. — 170 p.
  10. Дэвид Флэнаган. 4.3.1. Отсутствие блочной области видимости // JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — С. 70 — 71. — ISBN 5-93286-103-7.
  11. 1 2 Дэвид Флэнаган. 4.2. Объявление переменных // JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — С. 68. — ISBN 5-93286-103-7.
  12. 1 2 Koch Peter-Paul. Chapter 5. Core. Section D. Variables // ppk on JavaScript / Editor: Wendy Sharp. — 1st ed. — New Riders Press, 2006. — 528 p. — ISBN 978-0-321-42330-6.
  13. Crockford D. A.4. Reserved Words // JavaScript: The Good Parts. — 2008. — 170 p.
  14. Дэвид Флэнаган. 5.2. Обзор операторов // JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — С. 78 — 79. — ISBN 5-93286-103-7.
  15. Дэвид Флэнаган. 5.2.4 Ассоциативность операторов // JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — С. 81. — ISBN 5-93286-103-7.
  16. Дэвид Флэнаган. 5.2.1 Количество операндов // JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — С. 79. — ISBN 5-93286-103-7.
  17. Дэвид Флэнаган. 5.10.8 Оператор вызова функции // JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — С. 98. — ISBN 5-93286-103-7.
  18. Дэвид Флэнаган. 5.2.2 Тип операндов // JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — С. 80. — ISBN 5-93286-103-7.
  19. Crockford D. A.13. hasOwnProperty // JavaScript: The Good Parts. — 2008. — 170 p.
  20. Crockford D. A.8. + // JavaScript: The Good Parts. — 2008. — 170 p.
  21. Crockford D. B.12. void // JavaScript: The Good Parts. — 2008. — 170 p.
  22. Crockford D. B.1. == // JavaScript: The Good Parts. — 2008. — 170 p.
  23. 1 2 Crockford D. 4.1. Function Objects // JavaScript: The Good Parts. — 2008. — P. 26.
  24. 1 2 3 4 5 Zakas N. The Function Type // Professional JavaScript for Web Developers. — 2nd ed. — USA, Canada: Wiley Publishing, Inc., 2009. — P. 122 — 130. — ISBN 978-0-470-22780-0.
  25. Juriy "kangax" Zaytsev. Named function expressions demystified (англ.). — Статья, детально описывающая разницу между заданием функции с помощью объявления и заданием функции с помощью инструкции. Дата обращения: 19 октября 2009.
  26. Все параметры шаблона {{cite web}} должны иметь имя. [https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Functions#Conditionally_defining_a_function Conditionally defining a function (англ.). Functions and function scope. — Описание деталей реализации функций как выражений в контексте объявлений внутри условий. Дата обращения: 19 октября 2009.
  27. Crockford D. 4.4. Arguments // JavaScript: The Good Parts. — 2008. — P. 31.
  28. Crockford D. 4.8. Recursion // JavaScript: The Good Parts. — 2008. — P. 35.
  29. 1 2 Дэвид Флэнаган. 8.8. Область видимости функций и замыкания // JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — С. 156 — 163. — ISBN 5-93286-103-7.
  30. Crockford D. 4.10. Closure // JavaScript: The Good Parts. — 2008. — 170 p.
  31. Harmes R., Diaz D. Constants // Pro JavaScript™ Design Patterns. — USA: Apress, 2008. — P. 37, 38. — ISBN 1-59059-908-X.
  32. 1 2 3 4 Zakas N. The Object Type // Professional JavaScript for Web Developers. — 2nd ed. — USA, Canada: Wiley Publishing, Inc., 2009. — P. 40 — 41. — ISBN 978-0-470-22780-0.
  33. Crockford D. JSON // JavaScript: The Good Parts. — 2008. — P. 136.
  34. 1 2 3 4 Zakas N. The RegExp Type // Professional JavaScript for Web Developers. — 2nd ed. — USA, Canada: Wiley Publishing, Inc., 2009. — P. 115 — 122. — ISBN 978-0-470-22780-0.
  35. Ohloh. Mozilla Firefox Code Analysis (англ.). — Анализ исходного кода Mozilla Firefox. Дата обращения: 25 сентября 2009.
  36. 1 2 W3C. 18.2.1 Элемент SCRIPT (англ.). Спецификация HTML 4.01 (24 декабря 1999). — Описание элемента Script. Дата обращения: 25 сентября 2009.
  37. Администрация адресного пространства Интернет. Application Media Types (англ.). — Соответствие типов содержимого MIME-типам. Дата обращения: 28 сентября 2009.
  38. 1 2 Hoehrmann B. RFC4329 (англ.) (txt). Рабочая группа сетевых технологий специальной комиссии интернет-разработок (апрель 2006). — Текст запроса комментариев RFC4329. Дата обращения: 28 сентября 2009.
  39. Zakas N. 2. JavaScript in HTML // Professional JavaScript for Web Developers. — 2nd ed. — USA, Canada: Wiley Publishing, Inc., 2009. — P. 13. — ISBN 978-0-470-22780-0.
  40. W3C. Client-side Scripting and HTML (англ.). — Использование клиентских скриптов с HTML. Дата обращения: октябрь 2009.
  41. Crockford D. JavaScript and HTML Script Tags (англ.). — Использование тега script для подключения JavaScript. Дата обращения: октябрь 2009.
  42. Wilson B. MAMA: HEAD structure (англ.). Opera Developer Community. Opera Software ASA (14 ноября 2008). — Статистика используемых элементов в секции head веб-документов. Дата обращения: 14 октября 2009.
  43. W3C. Перечень атрибутов (англ.). Спецификация HTML 4.01 (24 декабря 1999). — Сводная таблица атрибутов HTML. Дата обращения: 25 сентября 2009.
  44. Ohloh. IndraDesktop WebOS Code Analysis (англ.). — Анализ исходного кода IndraDesktop WebOS. Дата обращения: 16 октября 2009.
  45. Ohloh. IntOS Web Operating System Code Analysis (англ.). — Анализ исходного кода IntOS Web Operating System. Дата обращения: 16 октября 2009.
  46. Ohloh. eyeos Code Analysis (англ.). — Анализ исходного кода eyeos. Дата обращения: 16 октября 2009.
  47. eyeOS Team. 5.2 The JavaScript side and the PHP side // eyeos developer manual. — P. 23.
  48. Kairer, Ryan Palm Announces the Palm webOS (англ.) (8 января 2009). Дата обращения: 16 октября 2009.
  49. Целиков, Дмитрий Анонсировано первое руководство для программирования в среде Palm webOS (18 февраля 2009). Дата обращения: 16 октября 2009.
  50. Allen M. Palm webOS. The Insider's Guide to Developing Applications in JavaScript using the Palm Mojo™ Framework. — O'Reilly Media. — 2009. — 464 p. — ISBN 978-0-596-15525-4.
  51. Дэвид Флэнаган. 13.4.1. Букмарклеты // JavaScript. Подробное руководство = JavaScript. The Definite Guide / Перевод А. Киселева. — 5-е изд. — СПб.: «Символ-Плюс», 2008. — С. 267. — ISBN 5-93286-103-7.
  52. New in JavaScript 1.6 (англ.). Mozilla Developer Center. — Новое в JavaScript версии 1.6. Дата обращения: октябрь 2009.
  53. New in JavaScript 1.7 (англ.). Mozilla Developer Center. — Новое в JavaScript версии 1.7. Дата обращения: октябрь 2009.
  54. 1 2 3 ECMA. Final draft of ECMA-262 – the ECMAScript language standard – has been published (англ.). — Анонс окончательного варианта проекта пятой редакции ECMA-262. Дата обращения: 25 сентября 2009.
  55. Крокфорд Д. Малыш-программист на JavaScript (англ.). — Статья, раскрывающая связь между JavaScript и Scheme. Дата обращения: 28 сентября 2009.
  56. Толксдорф Р. Языки программирования для JavaScript (англ.). is-research. — Подборка реализаций языков программирования на JavaScript. Дата обращения: 12 октября 2009.
  57. Strom N. About Quite BASIC (англ.). Дата обращения: 12 октября 2009.
  58. hotruby. Ruby on JavaScript and Flash (англ.). Дата обращения: 12 октября 2009.
  59. Cooper P. HotRuby: A JavaScript & Flash Virtual Machine That Runs Ruby (англ.). Rubi Inside. Дата обращения: 12 октября 2009.
  60. Шустер В. HotRuby - Ruby 1.9/YARV opcode interpreter in Javascript (англ.). infoQ. — Описание HotRuby. Дата обращения: 12 октября 2009.
  61. Formiga A. s-mr. Self-made Rhino (англ.). Дата обращения: 12 октября 2009.
  62. Hlavaty T. WPS: PostScript for the Web (англ.). Дата обращения: 12 октября 2009.
  63. 6502asm.com - 6502 compatible assembler and emulator in javascript (англ.). Дата обращения: 12 октября 2009.
  64. Cappuccino Web Framework - Build Desktop Class Applications in Objective-J and JavaScript (англ.). Дата обращения: 12 октября 2009.
  65. Yhc/Javascript/Brief overview (англ.). Дата обращения: 12 октября 2009.
  66. Monash Toy Prolog (англ.). Дата обращения: 12 октября 2009.
  67. ioctl. Prolog in JavaScript (англ.). Дата обращения: 12 октября 2009.
  68. Online Cat Interpreter (англ.). Дата обращения: 12 октября 2009.
  69. Package Information: HTML_Javascript (англ.). PEAR - PHP Extension and Application Repository. Дата обращения: 12 октября 2009.
  70. TCLLIB — Tcl Standard Library: javascript (англ.). Дата обращения: 12 октября 2009.
  71. Data::JavaScript (англ.). Comprehensive Perl Archive Network. Дата обращения: 12 октября 2009.
  72. Crockford, Douglas JavaScript: The World's Most Misunderstood Programming Language (англ.) (2001). — Статья Соответствие типов содержимого MIME-типам. Дата обращения: 23 октября 2009.
  73. Сахаров, Денис JavaScript: язык, который так до сих пор и не поняли (9 февраля 2009). — Перевод статьи Дугласа Крокфорда «JavaScript: The World's Most Misunderstood Programming Language». Дата обращения: 23 октября 2009.

Спецификации ECMAScript

  1. TC39. 4. Overview // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 1.
  2. 1 2 3 4 TC39. 4.3. Definitions // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 4. Ошибка в сносках?: Неверный тег <ref>: название «specDefinitions» определено несколько раз для различного содержимого
  3. TC39. 8.5. The Number Type // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 24.
  4. TC39. 8. Types // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 24.
  5. TC39. 12. Statements // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 61 — 71.
  6. 1 2 3 4 TC39. 7.9. Automatic Semicolon Insertion // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 21 — 24.
  7. TC39. 7.5.2. Keywords // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 13 — 14.
  8. TC39. 7.5.3. Future Reserved Words // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 15.
  9. TC39. 11.4. Unary Operators // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 46 — 48.
  10. TC39. 10.1.1. Function Objects // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 37.
  11. TC39. 13 Function Definition // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 71.
  12. TC39. 4.2. Language Overview // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 2.
  13. TC39. 8.6.1. Property attributes // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 25, 26.
  14. TC39. 15. Native ECMAScript Objects // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 76 — 148.
  15. 1 2 3 4 TC39. 15.10. RegExp (Regular Expression) Objects // ECMAScript Language Specification. — 3rd ed. — 1999. — P. 129 — 145.
  16. TC39. Introduction // ECMAScript Language Specification. Final Draft. — 5th ed. — 2009.

Стандарты оформления кода JavaScript

  1. 1 2 3 Crockford D. Code Conventions for the JavaScript Programming Language (англ.). Douglas Crockford's JavaScript. — Стандарт оформления кода JavaScript Дугласа Крокфорда. Дата обращения: октябрь 2009.
  2. 1 2 NextApp, Inc. JavaScript Code Conventions (англ.). Echo Web Framework. — Стандарт оформления кода JavaScript, принятый для Echo Web Framework. Дата обращения: октябрь 2009.
  3. Amaram Rahul. Javascript Naming Conventions, Coding Guidelines and Best Practices (англ.). Echo Web Framework. — Стандарт оформления кода JavaScript Рауля Амарама. Дата обращения: октябрь 2009.
  4. 1 2 3 Komenda Klaus. JavaScript Coding Guidelines and Standards (англ.). Сайт австрийского веб-разработчика Клауса Коменда. — Стандарт оформления кода JavaScript Клауса Коменда. Дата обращения: октябрь 2009.

Комментарии

  1. Только в отношении do-while
  2. Одним обратным слешем экранируются метасимволы строк (например, \t). Для экранирования метасимволов регулярных выражений используется двойной обратный слеш (например, \\s)

Ссылки

Сайты

Документация

Форумы

Справочники

Блоги известных авторов книг по JavaScript

IRC