Код состоит из спецсимволов ~!$%^&*()-_+=\|/?[]:;,.<>"'{}
, букв английского алфавита и цифр
'Словарь' языка делится на две основные части:
Эти слова описаны в стандарте языка, и имеют особый смысл. Например слово var
. С каждым или почти каждым мы ознакомимся в процессе изучения курса.
Переменные, имена функций - это идентификаторы. Вы можете их создавать сами. Каждый идентификатор начинается с буквы, $
или _
. Со второго символа так же допускается использование цифр:
var a15 = 15;
var camelCaseVariable = "Для отделения слов в идентификаторах можно использовать большие буквы";
var underscore_variable = "или подчерки";
const PI = Math.PI;
В JS принято использовать camelCase.
Это значит, что размер имеет значение. Букв. Т. е. переменные AaA
и aAa
это разные переменные. Ключевые слова в JS пишутся маленькими буквами, и подсветка это показывает:
var a = 5;
VAR b = 10;
Одна из основных операций, без которой не обходится практически ни одна строка кода - операция присвоения, т. е. связывания имени переменной с определенным значением:
var1 = value1;
Слева от знака равенства должна быть переменная, справа - выражение.
Присвоение происходит по следующему алгоритму:
Таким образом, в программировании имеют смысл бессмысленные с математической точки зрения вещи:
var a = 5;
a = a +1;
Во всех случаях, кроме присвоения, когда переменная встречается в коде, её значение подставляется в это место как подвыражение, т. е. происходит чтения значения переменной.
;
Во многих языках программирования, каждый оператор отделяется от других с помощью символа ;
. Это подсказка интерпретатору или компилятору языка. В JS практически всегда можно обойтись без этих символов, однако в некоторых случаях они обязательны, например, если
несколько операторов находятся в одной строке:
a = 5; b = a + 5;
Однако обычно нет причин для написания операторов в одну строку.
Тип данных - это множество допустимых значений, как было уже упомянуто.
Операции зависят от типа данных, и зачастую имеют смысл для одного типа данных и не имеют его для других. Например нет смысла делить на Boolean
или дату, однако иногда есть смысл делить на строку (если в ней число). С этим бывают определенные сложности.
Вы уже знакомы с числами:
var b = 5
var c = 6.57
const myPi = Math.PI
В JS для целых и дробных существует единый тип Number
. Так же этот тип имеет специальные значения NaN
(Not A Number), +Infinity
и -Infinity
(бесконечность).
4/"asdf" // бессмысленное выражение, как результат - NaN
15/0 // на ноль делить нельзя, но в высшей математике - можно :-)
console.log(0b1010)
console.log(0777)
console.log(0o555)
console.log(0xFF)
%
var b = 5;
b += 2;
var a = 5;
a %= 2;
Поэксперементируйте и объясните, что происходит в примере выше, а так же как выглядит не сокращенная форма операций выше.
++a
--a
a++
a--
Поэксперементируйте и объясните, в чем разница между пост- и пре- инкрементом и декрементом.
Math
Множество нужных операций по работе с числами есть в объекте-коллекции Math
, который является частью стандартной библиотеки:
alert(Math.random());
var a = 5;
var aBy2 = Math.floor(a/2);
var aModulo = a % 2;
Больше информации о Math
: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math
Строка - тип String
. Некое множество символов. Для перевода строки в число используйте +
или parseInt
( для целых ) или parseFloat
( для чисел
с дробной частью )
var someString = "foo";
var concatenatedString = someString + " bar";
var stringWithNumberInside = "123";
var integerNumberByString = +stringWithNumberInside;
var floatNumberByString = parseFloat("-15.15");
true
(правда) или false
(ложь)
В основном используется для двух задач:
isLoggedIn
может показывать залогинен пользователь на сайте или нет:var isLoggedIn = true
var isLoggedIn = false
var isLoggedIn = (password == rightPassword) && (login == rightLogin) //пользователь залогинен, если пароль и логин совпадают с верными
var isUserOldEnoughToSeeTheAdultVideos = age > 18 // пользователь может смотреть видео, если ему больше 18 лет.
Логическое выражение может использоваться в условиях, которые делают или не делают определенные операции в зависимости от истинности условия.
Сложная структура данных, обращение к элементам которого происходит по целочисленному индексу, начинающемуся с нуля:
var a = [0,1,2,3,4];
var squaresOfA = a.map(function(item){
return item*item;
});
Обращение к элементами приосходит с помощью []
:
alert(a[4]);
alert(squaresOfA[4]);
var cubesOfA = [];
cubesOfA[0] = a[0]*a[0]*a[0];
cubesOfA[1] = a[1]*a[1]*a[1];
cubesOfA[2] = a[2]*a[2]*a[2];
cubesOfA[3] = a[3]*a[3]*a[3];
cubesOfA[4] = a[4]*a[4]*a[4];
Объект. Сложная структура данных, которая в одной переменной может объединять данные других типов и операции над ними. Будет рассмотрена подробнее на следующих занятиях.
var person = {
name: "Ivan",
surname: "Ivanov",
age: 25
}
Доступ к полям происходит через .
или через []
по строковому ключу:
person["name"]
person.surname
Сформируйте объект с массивами и массив с объектами с осмысленными данными.
undefined
Если что-то в Javascript не определено, то это, обычно, undefined
:
var a; //значение a - undefined
undefined
- это и тип, и единственное его значение.
null
null
- в целом аналогичен undefined
, но предназначен для использования его программистом. Т. е. если вы хотите пометить переменную как пустую -
используйте null
typeof
позволяет узнать тип в виде строки
Каждое выражение можно сравнивать с другим выражением:
1 == 2
1 != 2
1 == 1
1 != 1
"text" == 5
"text" != 5
"text" == "Text"
"text" == "text"
true == "true"
true == false
false == 0
false === 0
"" == false
"" !== false
Равенства деляться на строгие (===
) и нестрогие (==
):
false == "0"
5 > 6
6 > 5
5.0 >= 5
"a" < "b"
"b" <= "a"
Результатом таких выражений является значение типа Boolean
, то есть true
или false
if
else
Любое значение, которое может быть приведено к типу Boolean
может стать условием для условного оператора if-else
:
Синтаксис:
if (cond){
//if cond is true
}
else {
//if cond is false
}
Например:
var age = prompt("Сколько вам лет?","");
if (+age < 18){
alert("Рано вам еще");
}
else {
alert("Смотрите на здоровье");
}
{}
Код, заключенный в фигурные скобки называется блоком кода. В зависимости от условия, он выполняется или невыполняется последовательно и целиком. Таким образом, фигурные скобки указывают интерпретатору, где начинается и где заканчивается блок кода для выполнения
или не выполнения. Так же в блоке кода могут быть свои локальные переменные, определенные с помощью let
(ES6).
if
, Краткие формы, выстрел в ногу и ;
//если у вас ОДИН оператор в блоке if или else, вы можете не использовать фигурные скобки:
if (+age < 18) alert("Рано вам еще");
else alert("Смотрите на здоровье");
//но учтите: ";" - тоже оператор:
if (+age < 18) alert("Рано вам еще");
else; alert("Смотрите на здоровье");
//эквивалентно:
if (+age < 18) alert("Рано вам еще");
else{
;
}
alert("Смотрите на здоровье");
// т.е. последний alert будет срабатывать ВСЕГДА.
Ставьте фигурные скобки всегда, и избавите себя от лишней траты времени на отладку :-)
if
может быть так же применен без else
:
var answer = confirm("будешь кексик?");
if (answer){
alert("кушай на здоровье");
}
alert("пока");
var age = +prompt("Сколько вам лет?","");
if (age < 18){
alert("школьник");
}
else if (age > 18 && age < 30){
alert("молодежь");
}
else if (age > 30 && age < 45){
alert("зрелость");
}
else if (age > 45 && age < 60){
alert("закат");
}
else if (age > 60){
alert("как пенсия?");
}
else {
alert("то ли киборг, то ли ошибка");
}
Добавьте условие отрицательного возраста в пример выше. Расставьте недостающие (но синтаксически необязательные) фигурные скобки.
var str = prompt("Поговори со мной!!!!","");
if (str){
alert("Ты такой милый " + str);
}
else {
alert("Козёл!!!!!11");
}
Данный оператор позволяет сократить пару if-else
в некоторых ситуациях:
var text = confirm("Нажмите что-нибудь") ? "Вы нажали Yes" : "Вы нажали No";
alert(text);
var text = confirm("Да, Нет, Наверное") ? "Да" : (confirm ("Нет или Наверное?") ? "Нет" : "Наверное") // вложенный тернарный оператор
alert(text);
Принципиально отличие тернарного оператора от if
-else
заключается в том, что тернарный оператор является выражением.
switch
switch
позволяет выполнять определенные блоки кода в зависимости от значения выражения:
var color = prompt("Введите цвет","");
switch (color){
case "red": document.write("<div style='background-color: red;'>красный</div>");
break;
case "black": document.write("<div style='background-color: black; color: white;'>черный</div>");
break;
case "blue": document.write("<div style='background-color: blue;'>синий</div>");
break;
case "green": document.write("<div style='background-color: green;'>зеленый</div>");
break;
default: document.write("<div style='background-color: gray;'>Я не понял</div>");
}
break
в switch
обеспечивает переход на конец конструкции switch
(т. е. на код, следущий за }
). Если break
не поставить, то можно объединить
несколько case
в один:
Перепишите пример выше, используя
if-else
var color = prompt("Введите цвет","");
switch (color){
case "red": document.write("<div style='background-color: red;'>красный</div>");
case "black": document.write("<div style='background-color: black; color: white;'>черный</div>");
break;
case "blue": document.write("<div style='background-color: blue;'>синий</div>");
case "green": document.write("<div style='background-color: green;'>зеленый</div>");
break;
default: document.write("<div style='background-color: gray;'>Я не понял</div>");
}
В примере выше "red" будет рисовать и "red" и "black", "blue" так же объединится с "green". Однако "black" и "green" будут работать так же как и ранее. Замечание: в силу особенностей реализации запуска кода со страницы, пара примеров выше не работают без копипасты в консоль.
!
5 == 5
5 != 5
!true
!false
!(5 == 5)
!(5 != 5)
!!0
Как видите, не позволяет инвертировать булево значение. Двойное не позволяет получить приведенное к типу Boolean
значение переменной.
||
Или позволяет объединять несколько булевых значений в одно, по следующей логике: Если A или B истинно, то результат - истина. Иначе - результат ложный:
var isDrunk = isDrunkByBeer || isDrunkByVodka //если пили или водку, или пиво, все равно пьяные :-)
var isFlyable = isFly || isBird || isAircraft || isBatman || isSuperman //что-то может летать, если это нечто - самолет, муха или птица, не важно что это.
Таблица истинности:
A | B | результат |
---|---|---|
false | false | false |
true | false | true |
false | true | true |
true | true | true |
&&
И требует что бы ВСЕ операнды были истинны, иначе результат ложен:
var isBodun = isDrunkByBeer && isDrunkByVodka //если пили и водку, и пиво, то бодун :-)
var isYoung = age > 16 && age < 30 // человек молод от 16 до 30.
Таблица истинности:
A | B | |
---|---|---|
false | false | false |
true | false | false |
false | true | false |
true | true | true |
Логические выражения выполняются оптимальным способом слева направо. То есть, если в ИЛИ попался true
, то следующая часть выражения даже не
будет обрабатываться, так как результат уже true
. ИЛИ ищет true
, и, когда находит, экономит ресурсы компьютера, сразу же возвращая true как результат выражения.
confirm('a') || confirm('b')
И, напротив, "ищет" false
. То есть, если найден false
, то нет смысла далее обрабатывать выражение - оно, так или иначе, будет false
.
confirm('a') && confirm('b')
Учтите, что ||
и &&
возвращают не true
или false
(значение булевского типа), а значения подвыражения как оно есть:
Как false
интерпретируются:
false
0
// 0 как число""
//пустая строкаnull
undefined
NaN
Как true
интерпретируются все остальные значения, в том числе:
Infinity
-Infinity
"0"
//строка не пуста. однако +"0" уже 0 как число, а значит false{}
//пустой объект - всё равно true
[]
//пустой массив [] == false
, но в остальных случаях работает как trueДля проверки используйте !!
, двойное отрицание: !!null
равен false
, таким образом мы можем почти всегда проверить как интерпретируется
то или иное значение.
В общем случае объект является true
, за исключением null
и [] == false
2
1+1
2*1
// bool type cast
!!2
!!0
!!1
// or
2 || 1
2 || 0
//and
2 && 1
1 && 2
0 && 2
// or and and difference
0 || 1 || 2
0 && 1 && 2
2 || 1 || 0
2 && 1 && 0
confirm('left') || confirm('right')
confirm('left') && confirm('right')
//null, undefined, so on
null || 2
undefined && 1
alert("Hello") && confirm('Are you sexy?');
alert("Hello") || confirm('Are you drunk?');
//brackets and complex expressions
(undefined || 2) && (2 || 0)
(2 && 1) || (null && 0)
(2 > 1) && "greater"
(2 < 1) && null
null && (2 < 1)
// ternary operator
1 ? "one" : "not one"
0 ? "zero" : "not zero"
"0" ? "\"zero\"" : "not `zero`"
parseInt("0") ? 'true' : 'false'
("" || 2) && (3 || "3.5") || (4 && 5)
(-1 + 1) && "zero"
"-1" + 1 && "oups"
(typeof null === 'object') ? "null is object" : "null is null"
// ternary && ||
Math.random() < 0.5 && 'less' || 'more'
(a = Math.random()) < 0.5 && 'less: '+a || 'more: '+a
//in for array
[2,3,5,7,11].indexOf(7) > -1 ? 'prime' : 'not found'
'random' in Math
'indexOf' in []
var a = b = c = d = 5;
Выражение в котором есть перечисление через запятую, возвращает значение после последней запятой, но при этом выполняются все выражения последовательно. Однако не надо путать такое выражение с массивом, объектом, списком параметров функций и прочими местами, где запятая имеет другой смысл.
var a = (Math.random(), Math.PI); // это выражение с запятой
var arr = [1,2,3]; // это массив
var obj = {a: 'b', c: 'd'} // это объект
Для лучшего понимания процесса отладки и написания кода, вы должны понимать, что каждая операция в коде отделена от других, вся связь происходит через данные в переменных. Таким образом для отладки вы можете внедрится в каждую часть кода, убедится в правильности работы этой части, подставив те или иные значения переменных, исправить баги, и быть спокойным конкретно за эту часть в дальнейшем.
Каждое корректное выражение может быть частью другого выражения. Вычисление выражений происходит согласно приоритетам операций и вложенности.
Напишите бессмысленное выражение, используя максимум усвоенных на текущий момент знаний.
Пунктуация в коде - это отступы. Обычно каждый вложенный блок кода должен быть сдвинут вправо на 4 пробела. Современные IDE неплохо справляются с этой задачей, так что, скорее всего, просто не мешайте им.