JavaScript — динамически типизируемый язык с синтаксисом, похожим на C. Программы состоят из инструкций, разделяемых точкой с запятой. Пробелы и переносы строк обычно игнорируются синтаксисом, но повышают читаемость.
Переменные объявляются через var и видимы в пределах функции (функциональная область видимости). Присваивание выполняется оператором =. Имена чувствительны к регистру.
// Объявление и присваивание
var x = 6;
var msg = "Hello";
// Выражение и оператор
var sum = x + 4; // 10
console.log(sum); // 10
Number в ES5 — это 64-битный формат IEEE-754. Существуют специальные значения: NaN, Infinity, -Infinity.
// NaN "липучий": любые операции с NaN дают NaN
console.log(0 / 0); // NaN
console.log(NaN === NaN); // false
console.log(isNaN("foo")); // true (строка приводится к NaN)
String — неизменяемая последовательность UTF-16 кодовых единиц. Индексация доступна, но менять символы по индексу нельзя.
var s = "Hello";
console.log(s[1]); // "e"
s[1] = "A";
console.log(s); // "Hello"
Boolean имеет значения true и false. В логическом контексте примитивы приводятся к булеву значению: «ложные» — 0, NaN, "", null, undefined, false. Остальное — «истинные».
undefined означает «значение не присвоено». null — осознанное «пустое значение».
4. Объекты (ссылочные типы)
Объект — это набор пар «ключ-значение». Ключи — строки. Каждое свойство имеет атрибуты: writable, enumerable, configurable. Объекты связаны цепочкой прототипов.
var user = { name: "Ann", age: 20 };
console.log(user.name); // "Ann"
user.role = "admin";
console.log("role" in user); // true
var a = { n: 1 };
var b = a;
b.n = 2;
console.log(a.n); // 2
5. Подробнее о массивах
Array — это объект со специальным поведением: числовые индексы и свойство length. Массивы могут быть «рваными» (с пропусками индексов).
var arr = [1, 2, 3];
arr.push(4); // [1,2,3,4]
var x = arr.pop(); // x=4, [1,2,3]
arr.unshift(0); // [0,1,2,3]
arr.shift(); // [1,2,3]
console.log(arr.length);// 3
Явное: используйте конструкторы как функции (Number(x), String(x), Boolean(x)), унарный +, parseInt/parseFloat. Неявное: происходит при сравнении ==, в логических операторах, при конкатенации строк, математике и т.д.
Функциональная область: переменные var видны во всей функции. Поднятие (hoisting) означает, что объявления var и function обрабатываются до выполнения кода.
// Hoisting переменной
console.log(a); // undefined (объявление поднято, присваивание — нет)
var a = 10;
// Hoisting функции (declaration)
foo(); // "ok"
function foo(){ console.log("ok"); }
// Выражение функции не поднимает саму инициализацию
bar(); // TypeError: bar is not a function
var bar = function(){};
Замыкание — функция «запоминает» окружающие переменные на момент создания.
function counter(){
var n = 0;
return function(){
n += 1;
return n;
};
}
var c = counter();
console.log(c()); // 1
console.log(c()); // 2
// IIFE для «захвата» i
var fns = [];
for (var i = 0; i < 3; i++) {
(function (j) {
fns.push(function () {
console.log(j);
}); // 0,1,2
})(i);
}
fns[0](); // 0
fns[1](); // 1
fns[2](); // 2
var obj = {
x: 10,
getX: function(){ return this.x; }
};
var unbound = obj.getX;
console.log(unbound()); // undefined в strict, иначе число из глобального контекста
var bound = unbound.bind(obj);
console.log(bound()); // 10
9. Подробнее об Object
Создание: литерал {} или Object.create(proto) для явного прототипа.
// Прототип от null
var dict = Object.create(null);
dict.key = "value";
console.log("toString" in dict); // false