Переменная состоит из имени и выделенной области памяти, которая ему соответствует.
Для объявления или, другими словами, создания переменной используется ключевое слово var:
var message;
message = 'Hello'; // сохраним в переменной строкуЭти данные будут сохранены в соответствующей области памяти и в дальнейшем доступны при обращении по имени. Для краткости можно совместить объявление переменной и запись данных:
var message = 'Hello';Можно даже объявить несколько переменных сразу:
var user = 'John',
age = 25,
message = 'Hello';Значение в переменных можно изменять или копировать из других переменных
var hello = 'Hello world!';
var message = hello; // скопировали значение "Hello world!"Константа — это переменная, которая никогда не меняется. Как правило, их называют большими буквами, через подчёркивание. Например:
var COLOR_ORANGE = "#FF7F00";
var color = COLOR_ORANGE;Технически, константа является обычной переменной, то есть её можно изменить. Но мы договариваемся этого не делать.
Зачем нужны константы? Почему бы просто не писать var color = "#FF7F00";
Во-первых, константа COLOR_ORANGE — это понятное имя. По присвоению var color="#FF7F00";
непонятно, что цвет — оранжевый. Иными словами, константа COLOR_ORANGE является «понятным псевдонимом» для значения #FF7F00.
Во-вторых, опечатка в строке, особенно такой сложной как #FF7F00, может быть не замечена, а в имени константы её допустить куда сложнее.
Встроенные типы данных:
- null
var age = null;В JavaScript null не является «ссылкой на несуществующий объект» или «нулевым указателем», как в некоторых других языках. Это просто специальное значение, которое имеет смысл «ничего» или «значение неизвестно». - undefined
var x = undefined;Значение undefined, как и null, образует свой собственный тип, состоящий из одного этого значения. Оно имеет смысл «значение не присвоено». Если переменная объявлена, но в неё ничего не записано, то её значение как раз и есть undefined:
var x;
console.log( x ); // выведет "undefined"В явном виде undefined обычно не присваивают, так как это противоречит его смыслу. Для записи в переменную «пустого» или «неизвестного» значения используется null.
- boolean
var checked = true; - number
var n = 123; - string
var str = "Мама мыла раму"; - object
var user = { name: "Вася" };
Оператор typeof возвращает тип аргумента.
У него есть два синтаксиса: со скобками и без:
Синтаксис оператора: typeof x. Синтаксис функции: typeof(x). Работают они одинаково, но первый синтаксис короче.
typeof undefined // "undefined"
typeof 0 // "number"
typeof true // "boolean"
typeof "foo" // "string"
typeof {} // "object"
typeof null // "object" (1)
//Результат typeof null == "object" — это официально признанная ошибка в языке, которая сохраняется для совместимости. На самом деле null — это не объект, а отдельный тип //данных.
typeof function(){} // "function"
typeof typeof 2 //"string"Для работы с переменными, со значениями, JavaScript поддерживает все стандартные операторы, большинство которых есть и в других языках программирования. Несколько операторов — это обычные сложение +, умножение *, вычитание и так далее.
Операнд — то, к чему применяется оператор. Например: 5 * 2 — оператор умножения с левым и правым операндами. Другое название: «аргумент оператора». Унарным называется оператор, который применяется к одному выражению. Например, оператор унарный минус "-" меняет знак числа на противоположный:
var x = 1;
x = -x;Бинарным называется оператор, который применяется к двум операндам. Тот же минус существует и в бинарной форме:
var x = 1, y = 3;
console.log( y - x ); // 2, бинарный минус
var a = "моя" + "строка";
a; // "моястрока"Важно помнить, что в операции сложения, если хотя бы один из операндов является строкой, то второй будет также преобразован к строке! Причем не важно, справа или слева находится операнд-строка. Например:
console.log( '1' + 2 ); // "12"
console.log( 2 + '1' ); // "21"В других арифметических операциях (вычитание, умножение, деление), операнды-строки напротив будут преобразованы к числам:
console.log( 2 - '1' ); // 1
console.log( 6 / '2' ); // 3
console.log( '4' - '1' ); // 3Унарный, то есть применённый к одному значению, плюс ничего не делает с числами:
console.log( +1 ); // 1
console.log( +(1 - 2) ); // -1С точки зрения математики такое изобилие плюсов может показаться странным. С точки зрения программирования — никаких разночтений: сначала выполнятся унарные плюсы, приведут строки к числам, а затем — бинарный '+' их сложит.
var apples = "2";
var oranges = "3";
//Так писать не рекомендуется, (легко ошибиться)поскольку если забыть пробел, то можно вместо приведения к типу получить инкремент
console.log( +apples + +oranges ); // 5, число, оба операнда предварительно преобразованы в числаОбратим внимание, в таблице приоритетов также есть оператор присваивания =.
У него — один из самых низких приоритетов: 3.
Именно поэтому, когда переменную чему-либо присваивают, например, x = 2 * 2 + 1 сначала выполнится арифметика, а уже затем — произойдёт присвоение =.
var x = 2 * 2 + 1; // 5
var a, b, c;
//Такое присваивание работает справа-налево, то есть сначала
//вычислятся самое правое выражение 2+2, присвоится в c,
//затем выполнится b = c и, наконец, a = b.
a = b = c = 2 + 2;
console.log( a, b, c ); // 4 4 4Все операторы возвращают значение. Вызов x = выражение не является исключением. Он записывает выражение в x, а затем возвращает его. Благодаря этому присваивание можно использовать как часть более сложного выражения:
var a = 1;
var b = 2;
var c = 3 - (a = b + 1);
console.log( a ); // 3
console.log( c ); // 0Оператор взятия остатка % интересен тем, что, несмотря на обозначение, никакого отношения к процентам не имеет. Его результат a % b — это остаток от деления a на b.
console.log( 5 % 2 ); // 1, остаток от деления 5 на 2Инкремент ++ увеличивает на 1:
var i = 2;
i++; // более короткая запись для i = i + 1.
console.log(i); // 3Декремент -- уменьшает на 1:
var i = 2;
i--; // более короткая запись для i = i - 1.
console.log(i); // 1Вызывать эти операторы можно не только после, но и перед переменной: i++ (называется «постфиксная форма») или ++i («префиксная форма»).
Обе эти формы записи делают одно и то же: увеличивают на 1.
Тем не менее, между ними существует разница. Она видна только в том случае, когда мы хотим не только увеличить/уменьшить переменную, но и использовать результат в том же выражении.
var i = 1;
var a = ++i; // (*)
console.log(a); // 2Постфиксная форма i++ отличается от префиксной ++i тем, что возвращает старое значение, бывшее до увеличения.
var i = 1;
var a = i++; // (*)
console.log(a); // 1Инкремент/декремент можно использовать в любых выражениях
var i = 1;
console.log( 2 * ++i ); // 4var n = 2;
n = n + 5;// -> n += 5;
n = n * 2;// -> n *= 2Так можно сделать для операторов +,-,* ,/ и бинарных <<,>>,>>>,&,|,^. Вызов с присваиванием имеет в точности такой же приоритет, как обычное присваивание, то есть выполнится после большинства других операций.
Один из самых необычных операторов — запятая ','. Его можно вызвать явным образом, например:
var a = (5, 6);Запятая позволяет перечислять выражения, разделяя их запятой ','. Каждое из них — вычисляется и отбрасывается, за исключением последнего, которое возвращается. //Запятая// — единственный оператор, приоритет которого ниже присваивания. В выражении a = (5,6) для явного задания приоритета использованы скобки, иначе оператор '=' выполнился бы до запятой ',', получилось бы (a=5), 6. Зачем же нужен такой странный оператор, который отбрасывает значения всех перечисленных выражений, кроме последнего? Обычно он используется в составе более сложных конструкций, чтобы сделать несколько действий в одной строке. Например:
// три операции в одной строке
for (a = 1, b = 3, c = a*b; a < 10; a++) {
...
}Многие операторы сравнения знакомы нам из математики:
- Больше/меньше: a > b, a < b.
- Больше/меньше или равно: a >= b, a <= b.
- Равно a == b. Для сравнения используется два символа равенства '='. Один символ a = b означал бы присваивание.
- «Не равно». В математике он пишется как ≠, в JavaScript — знак равенства с восклицательным знаком перед ним !=.
- Оператор возвращает истинну в том случае, если операнды строго равны. В отличие от оператора равенства, данный оператор не приводит операнды к одному типу.
var a = 2;
var b = 3;
a == b; //false
a === b; //false
a > b; //false
a >= b; //false
a < b; //true
a <= b; //true
a != b; //true
a !== b; //true Оператор строгого неравенства возвращает истину в том случае, если операнды не равны, или их типы отличаются друг от друга.Аналогом «алфавита» во внутреннем представлении строк служит кодировка, у каждого символа — свой номер (код). JavaScript использует кодировку Unicode. При этом сравниваются численные коды символов. В частности, код у символа Б больше, чем у А, поэтому и результат сравнения такой.
В кодировке Unicode обычно код у строчной буквы больше, чем у прописной.
Поэтому регистр имеет значение:
'Вася' > 'Ваня'; //true т.к. 'c' > 'н'var a = 3;
var b = 3;
var c = a === b ? a + b : a - b; // 6var a = 3;
var b = 3;
var c;
if (a === b) {
c = a + b;
} else {
c = a - b;
}
c; // 6В js есть только один тип чисел - number. JS так же руководствуется стандартом IEEE 754, называющейся «плавающей точкой» , использует двойную точность. Кому интересно могут прочитать про этот стандарт, но в этом нет строгой необходимости.
var n = 123;
n = 12.345;Если целая часть равна 0, то необязательно его писать
var a = 0.42;
var b = .42;То же самое и для десятичной части
var a = 42.0;
var b = 42.;Но это плохая идея - потому как можете запутать других людей Обычно по-умолчанию, большенство чисел с десятичными значениями удаляют последние нули
var a = 42.300;
var b = 42.0;
console.log(a); // 42.3
console.log(b); // 42Очень большие/маленькие числа будут выводиться через экспоненту
var a = 5E10;
a; // 50000000000
a.toExponential(); // "5e+10"
var b = a * a;
b; // 2.5e+21
var c = 1 / a;
c; // 2e-11
var d = 1E3; // 1*10^3По умолчанию JavaScript переводит в экспоненциальную запись любые значения с плавающей точкой, содержащие как минимум шесть нулей после точки:
0.0000005; //5e-7
0.000005; //0.000005Нельзя так просто взять и вызвать методы у числа
// Не валидный синтаксис:
42.toFixed( 3 ); // SyntaxError
// Все следующие примеры валидны
(42).toFixed( 3 ); // "42.000"
0.42.toFixed( 3 ); // "0.420"
42..toFixed( 3 ); // "42.000"Числа можно так же записывать в других системах исчесления:
0xf3; // Шестнадцатиричная: 243
0Xf3; // то же самое
010; // восьмиричная: 8
08; // десятеричная: 8Восьмиричная система определяется тем что первым числом идет 0 затем числ от 0 до 7 иначе будет считаться что система десятеричная
в ES6 + strict 0363 больше не разрешается, есть новая форма записи. Всегда используйте нижний регистр, что бы не запутать других людей
0xf3; // Шестнадцатиричная: 243
0Xf3; // то же самое
0o10; // восьмиричная: 8
0O10; // восьмиричная: 8
0b10; // двоичная: 2
0B10; // двоичная: 20.1 + 0.2 === 0.3; // false
0.1 + 0.2; // 0.30000000000000004Всё дело в том, что в стандарте IEEE 754 на число выделяется ровно 8 байт(=64 бита), не больше и не меньше.
Число 0.1 (одна десятая) записывается просто в десятичном формате, а в двоичной системе счисления это бесконечная дробь (перевод десятичной дроби в двоичную систему). Также бесконечной дробью является 0.2 (=2/10). Двоичное значение бесконечных дробей хранится только до определенного знака, поэтому возникает неточность. Её даже можно увидеть:
console.log( 0.1.toFixed(20) ); // 0.10000000000000000555Есть несколько способов этого избежать:
-
Привести к целым числам провести операции и вернуться обратно
console.log( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
-
Использование эпсилон окрестности В ES6 есть константа
Number.EPSILON; //2.220446049250313e-16 //Можно заполифилить if (!Number.EPSILON) { Number.EPSILON = Math.pow(2,-52); } //Функци сравнения с учетом погрешности function numbersCloseEnoughToEqual(n1,n2) { return Math.abs( n1 - n2 ) < Number.EPSILON; } var a = 0.1 + 0.2; var b = 0.3; numbersCloseEnoughToEqual( a, b ); // true numbersCloseEnoughToEqual( 0.0000001, 0.0000002 ); // false
Интересный пример
`9999999999999999; //10000000000000000`
Причина та же — потеря точности.
Из 64 бит, отведённых на число, сами цифры числа занимают до 52 бит, остальные 11 бит хранят позицию десятичной точки и один бит — знак. Так что если 52 бит не хватает на цифры, то при записи пропадут младшие разряды.
Интерпретатор не выдаст ошибку, но в результате получится «не совсем то число», что мы и видим в примере выше. Как говорится: «как смог, так записал». Math
NaN
Если математическая операция не может быть совершена, то возвращается специальное значение NaN (Not-A-Number).
Например, деление 0/0 в математическом смысле неопределено, поэтому его результат NaN:
0/0; // NaN
2/"foo"; // NaNЗначение NaN — единственное, в своем роде, которое не равно ничему, включая себя.
NaN === NaN; // false
NaN == NaN; //falseЕсть специальный метод который поможет проверить
var n = 0/0;
isNaN(n); // true
isNaN('12'); // false, строка преобразована к числу
isNaN({}); // true и это правда
//Можно заполифилить
if (!Number.isNaN) { Number.isNaN = function(n) { return ( typeof n === "number" && window.isNaN( n ) ); }; }
//Или еще короче
if (!Number.isNaN) { Number.isNaN = function(n) { return n !== n; }; }infinity
Что должно происходить при попытке деления на ноль?
Как правило, ошибка в программе… Во всяком случае, в большинстве языков программирования это именно так.
Но создатель JavaScript решил пойти математически правильным путем. Ведь чем меньше делитель, тем больше результат. При делении на очень-очень маленькое число должно получиться очень большое. В математическом анализе это описывается через пределы, и если подразумевать предел, то в качестве результата деления на 0 мы получаем «бесконечность», которая обозначается символом ∞ или, в JavaScript: "Infinity".
1/0; // Infinity
-1/0; // -Infinity
var a = Number.MAX_VALUE; // 1.7976931348623157e+308
a + a; // Infinity
a + Math.pow( 2, 970 ); // Infinity
a + Math.pow( 2, 969 ); // 1.7976931348623157e+308
Infinity / Infinity; // NaNА что будет 0/ -infinity ?
Нули
Javascript 2 нуля, как бы это странно не звучало
var a = 0 / -3; // -0
var b = 0 * -3; // -0
a.toString(); // "0"
+"-0"; // -0
Number( "-0" ); // -0
var a = 0;
var b = 0 / -3;
a == b; // true
-0 == 0; // true
a === b; // true
-0 === 0; // true
0 > -0; // false
a > b; // false
//Проверка на отрицательный 0
function isNegZero(n) { n = Number( n ); return (n === 0) && (1 / n === -Infinity); }А нужно это в приложениях, где например в качестве направления берется знак числа, и если подставить 0, то знак не поменяется на противоположный
В отличии от строго типизированных языков, массивы в js могут содержать значения разных типов: объекты, строки, числа и даже другие массивы(многомерные массивы)
var a = [ 1, "2", [3] ];
a.length; // 3
a[0] === 1; // true
a[2][0] === 3; // trueНеобязательно указывать размер массива, нужно только лишь объявить его
var a = [ ];
a.length; // 0
a[0] = 1;
a[1] = "2";
a[2] = [ 3 ];
a.length; // 3Однако, если мы в качестве ключа будете использовать строковое значение, которое может быть приведено к 10-значному числу, то обработчик подумает, что используется числовое значение в качестве ключа.
var a = [ ];
a.length; // 0
a['13'] = 1;
a.length; // 14Метод Pop
var fruits = ["Яблоко", "Апельсин", "Груша"];
fruits.pop(); // удалили "Груша"
fruits; // Яблоко, АпельсинМетод Push
var fruits = ["Яблоко", "Апельсин"];
fruits.push("Груша"); // удалили "Груша"
fruits; // Яблоко, Апельсин, ГрушаДлина length — не количество элементов массива, а последний индекс + 1.
var arr = [1, 2, 3, 4, 5];
arr.length = 2; // укоротить до 2 элементов
arr ; // [1, 2]
arr.length = 5; // вернуть length обратно, как было
arr[3]; // undefined: значения не вернулисьМассив содержит численную индексацию, но так же могут иметь строковые ключи, но тогда длинна массива не будет учитывать элементы со строковыми значениями.
var a = [ ];
a[0] = 1;
a["foobar"] = 2;
a.length; // 1
a["foobar"]; // 2
a.foobar; // 2Другой способ создания массива
var arr = new Array(2, 3);
console.log( arr[0] ); // 2, создан массив [2, 3], всё ок
arr = new Array(2); // создаст массив [2] ?
console.log( arr[0] ); // undefined! у нас массив без элементов, длины 2- Спецификация - это самый главный, определяющий документ, в котором написано, как себя ведёт JavaScript, браузер, CSS и т.п. и есть перевод
- learn.javascript.ru
- MDN
- Safari Developer Library
- Can i use
- http://help.dottoro.com/
- You don't know JS: types&grammar


