В этой главе приводятся основные особенности JavaScript, на уровне базовых конструкций, типов, синтаксиса.
Она будет особенно полезна, если ранее вы программировали на другом языке, ну или как повторение важных моментов раздела.
Всё очень компактно, со ссылками на развёрнутые описания.
Операторы разделяются точкой с запятой:
alert('Привет'); alert('Мир');
Как правило, перевод строки тоже подразумевает точку с запятой. Так тоже будет работать:
alert('Привет')
alert('Мир')
...Однако, иногда JavaScript не вставляет точку с запятой. Например:
var a = 2
+3
alert(a); // 5
Бывают случаи, когда это ведёт к ошибкам, которые достаточно трудно найти и исправить, например:
alert("После этого сообщения будет ошибка")
[1, 2].forEach(alert)
Детали того, как работает код выше (массивы [...]
и forEach
) мы скоро изучим, здесь важно то, что при установке точки с запятой после alert
он будет работать корректно.
Поэтому в JavaScript рекомендуется точки с запятой ставить. Сейчас это, фактически, общепринятый стандарт.
Поддерживаются однострочные комментарии // ...
и многострочные /* ... */
:
Подробнее: info:structure.
-
Объявляются директивой
var
. Могут хранить любое значение:var x = 5; x = "Петя";
-
Есть 5 "примитивных" типов и объекты:
x = 1; // число x = "Тест"; // строка, кавычки могут быть одинарные или двойные x = true; // булево значение true/false x = null; // спец. значение (само себе тип) x = undefined; // спец. значение (само себе тип)
Также есть специальные числовые значения
Infinity
(бесконечность) иNaN
.Значение
NaN
обозначает ошибку и является результатом числовой операции, если она некорректна. -
Значение
null
не является "ссылкой на нулевой адрес/объект" или чем-то подобным. Это просто специальное значение.Оно присваивается, если мы хотим указать, что значение переменной неизвестно.
Например:
var age = null; // возраст неизвестен
-
Значение
undefined
означает "переменная не присвоена".Например:
var x; alert( x ); // undefined
Можно присвоить его и явным образом:
x = undefined
, но так делать не рекомендуется.Про объекты мы поговорим в главе info:object, они в JavaScript сильно отличаются от большинства других языков.
-
В имени переменной могут быть использованы любые буквы или цифры, но цифра не может быть первой. Символы доллар
$
и подчёркивание_
допускаются наравне с буквами.
Подробнее: info:variables, info:types-intro.
Для того, чтобы интерпретатор работал в режиме максимального соответствия современному стандарту, нужно начинать скрипт директивой 'use strict';
'use strict';
...
Эта директива может также указываться в начале функций. При этом функция будет выполняться в режиме соответствия, а на внешний код такая директива не повлияет.
Одно из важных изменений в современном стандарте -- все переменные нужно объявлять через var
. Есть и другие, которые мы изучим позже, вместе с соответствующими возможностями языка.
Простейшие функции для взаимодействия с посетителем в браузере:
"prompt(вопрос[, по_умолчанию])"
: Задать вопрос
и возвратить введённую строку, либо null
, если посетитель нажал "Отмена".
"confirm(вопрос)"
: Задать вопрос
и предложить кнопки "Ок", "Отмена". Возвращает, соответственно, true/false
.
"alert(сообщение)" : Вывести сообщение на экран.
Все эти функции являются модальными, т.е. не позволяют посетителю взаимодействовать со страницей до ответа.
Например:
var userName = prompt("Введите имя?", "Василий");
var isTeaWanted = confirm("Вы хотите чаю?");
alert( "Посетитель: " + userName );
alert( "Чай: " + isTeaWanted );
Подробнее: info:uibasic.
-
Для сложения строк используется оператор
+
.Если хоть один аргумент -- строка, то другой тоже приводится к строке:
alert( 1 + 2 ); // 3, число alert( '1' + 2 ); // '12', строка alert( 1 + '2' ); // '12', строка
-
Сравнение
===
проверяет точное равенство, включая одинаковый тип. Это самый очевидный и надёжный способ сравнения. -
Остальные сравнения
== < <= > >=
осуществляют числовое приведение типа:alert( 0 == false ); // true alert( true > 0 ); // true
Исключение -- сравнение двух строк, которое осуществляется лексикографически (см. далее).
Также: значения
null
иundefined
при==
равны друг другу и не равны ничему ещё. А при операторах больше/меньше происходит приведениеnull
к0
, аundefined
кNaN
.Такое поведение может привести к неочевидным результатам, поэтому лучше всего использовать для сравнения с
null/undefined
оператор===
. Оператор==
тоже можно, если не хотите отличатьnull
отundefined
.Например, забавное следствие этих правил для
null
:alert( null > 0 ); // false, т.к. null преобразовано к 0 alert( null >= 0 ); // true, т.к. null преобразовано к 0 alert( null == 0 ); // false, в стандарте явно указано, что null равен лишь undefined
С точки зрения здравого смысла такое невозможно. Значение
null
не равно нулю и не больше, но при этомnull >= 0
возвращаетtrue
! -
Сравнение строк -- лексикографическое, символы сравниваются по своим unicode-кодам.
Поэтому получается, что строчные буквы всегда больше, чем прописные:
alert( 'а' > 'Я' ); // true
Подробнее: info:operators, info:comparison.
В JavaScript есть логические операторы: И (обозначается &&
), ИЛИ (обозначается ||
) и НЕ (обозначается !
). Они интерпретируют любое значение как логическое.
Не стоит путать их с побитовыми операторами И, ИЛИ, НЕ, которые тоже есть в JavaScript и работают с числами на уровне битов.
Как и в большинстве других языков, в логических операторах используется "короткий цикл" вычислений. Например, вычисление выражения 1 && 0 && 2
остановится после первого И &&
, т.к. понятно что результат будет ложным (ноль интерпретируется как false
).
Результатом логического оператора служит последнее значение в коротком цикле вычислений.
Можно сказать и по-другому: значения хоть и интерпретируются как логические, но то, которое в итоге определяет результат, возвращается без преобразования.
Например:
alert( 0 && 1 ); // 0
alert( 1 && 2 && 3 ); // 3
alert( null || 1 || 2 ); // 1
Подробнее: info:logical-ops.
-
Поддерживаются три вида циклов:
// 1 while (условие) { ... } // 2 do { ... } while (условие); // 3 for (var i = 0; i < 10; i++) { ... }
-
Переменную можно объявлять прямо в цикле, но видна она будет и за его пределами.
-
Поддерживаются директивы
break/continue
для выхода из цикла/перехода на следующую итерацию.Для выхода одновременно из нескольких уровней цикла можно задать метку.
Синтаксис: "
имя_метки:
", ставится она только перед циклами и блоками, например:*!*outer:*/!* for(;;) { ... for(;;) { ... *!*break outer;*/!* } }
Переход на метку возможен только изнутри цикла, и только на внешний блок по отношению к данному циклу. В произвольное место программы перейти нельзя.
Подробнее: info:while-for.
При сравнениях в конструкции switch
используется оператор ===
.
Например:
var age = prompt('Ваш возраст', 18);
switch (age) {
case 18:
alert( 'Никогда не сработает' ); // результат prompt - строка, а не число
case "18": // вот так - сработает!
alert( 'Вам 18 лет!' );
break;
default:
alert( 'Любое значение, не совпавшее с case' );
}
Подробнее: info:switch.
Синтаксис функций в JavaScript:
// function имя(список параметров) { тело }
function sum(a, b) {
var result = a + b;
return result;
}
// использование:
alert( sum(1, 2) ); // 3
-
sum
-- имя функции, ограничения на имя функции -- те же, что и на имя переменной. -
Переменные, объявленные через
var
внутри функции, видны везде внутри этой функции, блокиif
,for
и т.п. на видимость не влияют. -
Параметры копируются в локальные переменные
a
,b
. -
Функция без
return
считается возвращающейundefined
. Вызовreturn
без значения также возвращаетundefined
:function f() { } alert( f() ); // undefined
Подробнее: info:function-basics.
Функция в JavaScript является обычным значением.
Её можно создать в любом месте кода и присвоить в переменную, вот так:
var sum = function(a, b) {
var result = a + b;
return result;
}
alert( sum(1, 2) ); // 3
Такой синтаксис, при котором функция объявляется в контексте выражения (в данном случае, выражения присваивания), называется Function Expression, а обычный синтаксис, при котором функция объявляется в основном потоке кода -- Function Declaration.
Функции, объявленные через Function Declaration, отличаются от Function Expression тем, что интерпретатор создаёт их при входе в область видимости (в начале выполнения скрипта), так что они работают до объявления.
Обычно это удобно, но может быть проблемой, если нужно объявить функцию в зависимости от условия. В этом случае, а также в других ситуациях, когда хочется создать функцию "здесь и сейчас", используют Function Expression.
Детали: info:function-declaration-expression.
Если объявление функции является частью какого-либо выражения, например var f = function...
или любого другого, то это Function Expression.
В этом случае функции можно присвоить "внутреннее" имя, указав его после function
. Оно будет видно только внутри этой функции и позволяет обратиться к функции изнутри себя. Обычно это используется для рекурсивных вызовов.
Например, создадим функцию для вычисления факториала как Function Expression и дадим ей имя me
:
var factorial = function me(n) {
return (n == 1) ? n : n * me(n - 1);
}
alert( factorial(5) ); // 120
*!*
alert( me ); // ошибка, нет такой переменной
*/!*
Ограничение видимости для имени не работает в IE8-, но вызов с его помощью работает во всех браузерах.
Более развёрнуто: info:named-function-expression.
В этой главе мы повторили основные особенности JavaScript, знание которых необходимо для обхода большинства "граблей", да и просто для написания хорошего кода.
Это, конечно, лишь основы. Дальше вы узнаете много других особенностей и приёмов программирования на этом языке.