{{JavaScript}} -- стандартный (де-факто) язык скриптования Web-страниц, выполняемый в браузере. По сей причине является наиболее используемым языком программирования, несмотря на значительные проблемы языка (поведение кода нередко оказывается неочевидным, разительно различается для разных типов, и даже может зависеть от используемого браузера -- написание кода, гарантированно работающего везде и всегда как задумано, задача весьма нетривиальная). Общую справку по стандарту JavaScript можно найти, в частности, [здесь|http://www.w3schools.com/jsref] и [здесь|https://developer.mozilla.org/en-US/docs/Web/JavaScript].

В браузерах реализована возможность использовать написанные на JavaScript интерпретаторы/трансляторы (в JS) для выполнения скриптов на других (более удобных) языках; также транслирование в JS может выполняться предварительно, как компиляция (в этом случае транслятор может быть написан не на JavaScript). Примеры: [CoffeeScript], [ClojureScript|Clojure].

Также виртуальные машины для выполнения JS существуют отдельно от браузеров ("headless WebKit"); они предназначены для автоматизированного тестирования JS-кода, и для повторного использования части кода на сервере (хотя в последнее время для этой цели нередко используются транслируемые на JS языки). На DL для тестирования JS используется [PhantomJS|http://phantomjs.org] версии [1.9.8|https://bitbucket.org/ariya/phantomjs/downloads].

(Внимание: запуск на DL выполняется внутри [скрипта|http://dl.gsu.by/images/agulenko/js/scripts/argrunner.js], изменяющего поведение по умолчанию: в частности, при ошибке работа PhantomJS завершается с кодом 1, а отсутствующие методы строк заменены эквивалентными реализациями.)

Вместо компиляции производится проверка синтаксиса программой [JavaScript Lint|http://www.javascriptlint.com/download.htm] (основанной на JS-движке Firefox) со слегка изменённым набором правил ([заархивированная версия|http://dl.gsu.by/images/agulenko/js/jsl-conf.zip]).

h2. Основы языка

{code:java|title=типы}
true, false // boolean, булевский
null // null-объект
undefined // undefined, значение по умолчанию
5, 5., .5, 0.5, Infinity, NaN // number, дробное число
'a', "b", 'cd', "ef" // string, строка (UTF-16)
[], [1, 2, 'a', null, NaN] // Array, массив
{}, {key: 'value'}, ... // object, любой объект
{code}
Синтаксис заимствован большей частью из C, так что операторы похожи.
{code:java|title=операторы}
a == b, a != b // равенство/неравенство (с приведением типов)
a === b, a !== b // равенство/неравенство (по фактическому значению)
+a, a + b, a += b, a++ // плюс, сложение, инкрементация
-a, a - b, a -= b, a-- // минус, вычитание, декрементация
a * b, a / b, a % b // умножение, деление, остаток от деления
a *= b, a /= b, a %= b // присваивание с умножением/делением/остатком
a & b, a | b, a ^ b // побитовые and, or, xor (с приведением к целому)
a && b, a || b // логические and, or
a << b, a >> b // побитовый сдвиг
a <<= b, a >>= b // присваивание с побитовым сдвигом
(a ? b : c) // условное выражение
{code}
Правда, с операторами нужно быть осторожным -- их поведение может оказаться довольно неожиданным:
{code:java|title=примеры}
'5,6' == [5.0,6.] // true
'5, 6' != [5, 6] // true
5 === 5.0000000000000001 // true
null !== undefined // true
[] + [] // ""
[] - [] // 0
[] + {} // object
{} + [] // 0 - но не всегда
{} + {} // NaN - но не всегда
[5] + "9" // "59"
[5] - "9" // -4
null || undefined || NaN || 0 // 0
undefined || 0 || 9 || 0 // 9
{code}
Общие правила синтаксиса похожи на C.
{code:java|title=конструкции языка}
// блок - работает как отдельная команда
something { // переносить не советую
do1();
do2();
}

// переменные (глобальные - по возможности избегать)
p = 'a';
q = "b";
// переменные (локальные для функции)
var x = {value: 0};
var
y = "1",
z = [y, 3];
// переменные (локальные для блока; не поддерживаются PhantomJS)
let i = 0;
let
j = 4,
k = [3, j];
// константы (запрещают присваивание; локальны для блока)
const
a = 9;
const
b = "8",
c = [b, NaN];

// условие
if (condition)
doSomething();
else
doSomethingElse();
switch (variable) {
case value1:
do1();
break;
case value2:
case value3:
do2();
break;
default:
do3();
}

// цикл
for (init(); condition; step())
doStuff(i);
while (condition)
doSomething();
do {
doSomething();
} while (condition);

// функция
function s (arg1, arg2) {
doThings([arg1, arg2]);
}
var func = function (args) { doThings(args) };
const f = function fact (n) {
return ((n < 2) ? n : (n * fact(n-1)));
};
{code}

h2. Ввод-вывод (+PhantomJS)

Для доступа к операциям ввода-вывода нужно использовать библиотеку PhantomJS:
{code:java|title=подключение модулей}
const
sys = require('system'), // модуль для взаимодействия с ОС
fs = require('fs'); // модуль для работы с файлами
{code}
Также имеется модуль под названием {{phantom}}, подключаемый автоматически.

Поскольку обычный JS-скрипт (в web-странице) никогда не "завершается", при решении задач на программирование вызывается команда завершения:
{code:java}
phantom.exit();
{code}
Поскольку в браузере JavaScript всегда подключён к (обычно скрытому) REPL, в нём есть команды вывода в консоль:
{code:java|title=встроенные команды вывода}
console.log(some, things); // стандартный вывод текста
console.error(message); // стандартный вывод ошибок
{code}
PhantomJS предоставляет ввод-вывод посредством файловых объектов:
{code:java|title=работа с файлами}
var
fin = fs.open("input.txt", 'r'),
s1 = fin.readLine(), // читает строку (до EOL)
s2 = fin.read(L), // читает 5 байт
s3 = fin.read(); // читает до EOL
fin.close();

var
fout = fs.open("output.txt", 'w');
fout.write(s2); // выводит текст
fout.writeLine(s1); // выводит строку + EOL
fout.close();
{code}
Для работы с консолью он предоставляет файловые объекты stdin, stdout и stderr:
{code:java|title=работа с консолью}
const s = sys.stdin.readLine();
sys.stdout.writeLine(s);
sys.stderr.writeLine(s);
{code}

h2. Примеры

{code:java|title=a+b}
const sys = require('system');

function readAll (fin) {
const l = fin.readLine().split(' ');
return {a: parseInt(l[0]),
b: parseInt(l[1])};
}

function printAll (fout, res) {
fout.writeLine(res);
}

calc = function (o) { return o.a + o.b };

printAll(sys.stdout, calc( readAll(sys.stdin) ));
{code}
или
{code:java|title=a+b (сокращённо)}
const sys = require('system');

const
l = sys.stdin.readLine().split(' '),
a = l[0], b = l[1];
console.log(parseInt(a) + parseInt(b));
{code}