Основы JavaScript

Основы JavaScript

Andrey Gorokhov

Комментарии

Комментарии могут находиться в любом месте программы и никак не влияют на её выполнение.

Однострочные комментарии начинаются с двойного слэша //. Текст считается комментарием до конца строки:

//Команда ниже говорит "Привет"
alert('Привет');
alert('Мир'); //Второе сообщение выводим отдельно

Многострочные комментарии начинаются слешем-звездочкой /* и заканчиваются звездочкой-слэшем */, вот так:

/* Пример с двумя сообщениями.
Это - многострочный комментарий.
*/
alert('Привет');
alert('Мир');

Всё содержимое комментария игнорируется. Если поместить код внутрь /* … */ или после //, то он не выполнится.

/* Закомментировали код
alert('Привет');
*/
alert('Мир');

Вложенные комментарии не поддерживаются! В этом коде будет ошибка:

/*
  /* вложенный комментарий ?!? */
*/
alert('Мир');

Переменные

Для объявления создания переменной используется ключевое слово var:

var message;

После объявления можно записать в переменную данные:

var message;
message = 'Hello';

Эти данные будут сохранены в соответствующей области памяти и в дальнейшем доступны при обращении по имени:

var message;
message = 'Hello!';
alert(message); //Выведет содержимое переменной

Для краткости можно совместить объявление переменной и запись данных:

var message = 'Hello!';

Можно объявить несколько переменных сразу:

var user = 'John', age = 25, message = 'Hello';

Значение в переменной можно изменять сколько угодно раз:

var message;
message = 'Hello!';
message = 'World!'; //Заменили значение
alert(message);

При изменении значения старое содержимое переменной удаляется.

Можно объявить две переменные и копировать данные из одной в другую:

var hello = 'Hello world!';
var message;
// Cкопировали значение
message = hello;
alert(hello); // Hello world!
alert(message); // Hello world!

Имена переменных

На имя переменной в JavaScript наложены всего два ограничения.

  • Имя может состоять из: букв, цифр, символов $ и _.
  • Первый символ не должен быть цифрой.

Шесть типов данных

Число

var n = 123;
n = 12.345;

Единый тип число используется как для целых, так и для дробных чисел.

Существуют специальные числовые значения Infinity (бесконечность) и NaN (not a number, ошибка вычислений).

Например, бесконечность Infinity получается при делении на ноль:

alert(1 / 0); // Infinity

Ошибка вычислений NaN будет результатом некорректной математической операции, например:

alert("нечисло" * 2); // NaN

Строка

var str = "Мама мыла раму";
str = 'Одинарные кавычки тоже подойдут';

Булевый (логический) тип «boolean»

У него всего два значения: true (истина) и false (ложь).

Как правило, такой тип используется для хранения значения типа да/нет, например:

var checked = true; // Поле формы помечено галочкой
checked = false;    // Поле формы не содержит галочки

Значение «null»

Значение null не относится ни к одному из типов выше, а образует свой отдельный тип, состоящий из единственного значения null:

var age = null;

В JavaScript null не является «ссылкой на несуществующий объект» или «нулевым указателем», как в некоторых других языках. Это просто специальное значение, которое имеет смысл «ничего» или «значение неизвестно».

Значение «undefined»

Значение undefined, как и null, образует свой собственный тип, состоящий из одного этого значения. Оно имеет смысл «значение не присвоено».

Если переменная объявлена, но в неё ничего не записано, то её значение как раз и есть undefined:

var x;
alert(x); // undefined

Объекты

Первые 5 типов называют «примитивными». Особняком стоит шестой тип: «объекты».

Он используется для коллекций данных и для объявления более сложных сущностей.

Объявляются объекты при помощи фигурных скобок {...}, например:

var user = {name: "Вася"};

Условия

Синтаксис:

if (условие) {
    действие;
}

Условие с альтернативным действием:

if (условие) {
    действия;
} else {
    другие действия;
}

Вложенные условия:

if (условие1) {
    if (условие2) {
        действия;
    }
}

Как работают условия?

Выражение в круглых скобках (проверка) возвращает true или false. Действие внутри условия выполняется, если вернулось true. Если выражение вернуло false, действие не выполнится.

Код внутри проверок

Операторы сравнения:

Операторы равенства:

Логические операторы:

  • Оператор && или «логическое И» возвращает true только в том случае, если оба условия слева и справа от него возвращают true.
  • Оператор || или «логическое ИЛИ» возвращает true, если любое из условий слева или справа от него возвращает true.
  • Оператор ! или «логическое отрицание» меняет булево значение выражения справа от него на противоположное.

Циклы

Цикл for

Синтаксис:

for (var i = 0; i < 10; i++) {
    console.log(i) // 0 1 2 3 4 5 6 7 8 9
}

var i = 0; — подготовительная часть, исходное значение для счётчика. Задаётся с помощью var, как обычная переменная.

i < 10; — проверочная часть. Если условие возвращает true, цикл делает ещё одну итерацию иначе прекращает свою работу.

i++ — дополняющая часть, запускается на каждой итерации после выполнения кода из тела цикла. Меняет значение счётчика.

Накопление значений в цикле

var sum = 0;

for (var i = 1; i <= 5; i++) {
   sum += 2;
   console.log(sum); // 2 4 6 8 10
}

Проверки в теле цикла

var sum = 0;

for (var i = 1; i <= 5; i++) {
    if (i > 2) {
        sum += 1;
    }
}

Поиск чётного числа

Оператор % или «остаток от деления» возвращает остаток от деления.

10 % 5;  // 0
12 % 5;  // 2
7 % 3;   // 1
5.5 % 2; // 1.5

Если остаток от деления числа на 2 равен 0 — число чётное, иначе нечётное.

Цикл while

Синтаксис:

while (условие) {
    действия
}

Действия будут выполняться снова и снова, пока условие не вернёт false.

Накопление значений в цикле

var sum = 0;
var i = 0;

while (i <= 5) {
    sum += 1;
    i++;
    console.log(i); // 1 2 3 4 5
}

Поиск процента от числа

Самый простой способ найти процент от числа — разделить число на 100 и умножить на процент.

// Найдём 2 процента от 1000
1000 / 100 * 2 = 20;

// Найдём 7 процентов от 1200
1200 / 100 * 7 = 84;

Массивы

Массив — тип данных (объект), который представляет собой список элементов, у каждого из которых есть свой порядковый номер.

В массиве можно хранить любые данные: строки, булевы значения, числа и даже другие массивы.

Нумерация элементов массива начинается с нуля, поэтому порядковый номер (индекс) первого элемента равен нулю.

В качестве индекса можно использовать переменную.

Используйте команду length, чтобы узнать длину массива (сколько в нём элементов). С её помощью можно получить последний элемент массива.

var numbers = [1, 2, 3, 4, 5];
var index = 3;

console.log(numbers[0]); // 1
console.log(numbers[index]); // 4
console.log(numbers.length); // 5
console.log(numbers[numbers.length - 1]); // 5

Массивы можно перебирать в циклах. Например, цикл ниже выводит элементы массива в консоль по очереди и прекращает свою работу, когда i станет равно длине массива.

var numbers = [1, 2, 3, 4, 5];

for (var i = 0; i < numbers.length; i++) {
    console.log(numbers[i]); // 1 2 3 4 5
}

Альтернативный способ: 

var numbers = [1, 2, 3, 4, 5];

numbers.forEach(function(i) {
 console.log(i); // 1 2 3 4 5
});

Запись в массив происходит так же, как чтение, то есть через квадратные скобки.

var numbers = [];
var index = 1;

numbers[0] = 1;
numbers[index] = 2;

console.log(numbers); // [1, 2]

Сортировка массива

var numbers = [12, 3, 7, 9, 10, 5];

for (var i = 0; i <= numbers.length - 2; i++) {
    var minValue = numbers[i];

    for (var j = i + 1; j <= numbers.length - 1; j++) {
        if (numbers[j] < minValue) {
            minValue = numbers[j];
            var swap = numbers[i];
            numbers[i] = minValue;
            numbers[j] = swap;
        }
    }
}

console.log(numbers); // [3, 5, 7, 9, 10, 12];

Массив с числами numbers сортируется по возрастанию элементов. На каждой итерации мы сравниваем minValue с остальными элементами массива. Если какой-то из них окажется меньше, чем minValue, он запишется в minValue, перезаписав старое значение, и переместится в начало массива. Переменная swap — вспомогательная переменная, с помощью которой мы можем поменять элементы местами.

Самый короткий способ сортировки:

var numbers = [12, 3, 7, 9, 10, 5];

numbers.sort(function(a, b) {
    return a > b;
});

console.log(numbers); // [3, 5, 7, 9, 10, 12];

Суммирование всех значений в массиве

var nums = [100, 20, 3, 7, 9];
var total = nums.reduce(function(a, b) {
    return a + b;
});

console.log(total); // 139 

Нахождение минимального значения в массиве

var nums = [100, 20, 3, 7, 9];
var index = 0;
var minValue = nums[index];

for (var i = index + 1; i <= nums.length - 1; i++) {
    if (nums[i] < minValue) {
        minValue = nums[i];
    }
}

console.log(minValue); // 3

Альтернативный способ (нахождение минимального и максимального значения в массиве): 

var nums = [100, 20, 3, 7, 9];

var min = Math.min.apply(null, nums);
var max = Math.max.apply(null, nums);

console.log("Минимальное значение: " + min); // Минимальное значение: 3
console.log("Максимальное значение: " + max); // Максимальное значение: 100

Функции

Пример функции:

var calculateSum = function (numberFirst, numberSecond) {
    var sum = numberFirst + numberSecond;
    return sum;
};

calculateSum(); // NaN
calculateSum(2); // NaN
calculateSum(2, 5); // 7
calculateSum(9, 5); // 14

В этом примере:

  • calculateSum — имя, по которому можно обратиться к функции.
  • numberFirstnumberSecond — параметры функции.
  • return sum; — место кода, где происходит возвращение sum и выход из функции.
  • calculateSum(2, 5); — аргументы, которые передаются в функции при вызове. Порядок аргументов такой же, как у параметров функции. Первый аргумент 2 записывается в первый параметр numberFirst, аргумент 5 записывается в параметр numberSecond. Важно соблюдать порядок параметров при вызове функции, чтобы избежать неочевидных ошибок.

Объекты

Объект — тип данных, который хранит в себе информацию в виде пар «ключ-значение». Каждый элемент сопоставлен со своим ключом и порядок элементов совсем неважен.

Синтаксис:

var user = {
    name: 'Вася',
    age: 25
};

console.log(user.name); // 'Вася'
console.log(user.age); // 25
console.log(user.color); // undefined, такого ключа в объекте нет

user.age++; //Увеличили возраст пользователя на 1
console.log(user.age) // 26

user.name = 'Петя'; //Заменили снаружи значение свойства name
console.log(user.name); // 'Петя'

Передача по ссылке

Объект всегда один, в памяти не создаётся новое место под копию объекта. Каждая переменная содержит не новую отдельную сущность, а ссылку на один-единственный объект. Поэтому когда мы меняем что-то в объекте через одну из переменных, в которой содержится ссылка на него, изменения видны во всех других переменных, будь их хоть двадцать или сорок. Это важная особенность объектов, которую надо запомнить. Она так и называется — передача объектов по ссылке.

var firstUser = {
    name: 'Вася',
    age: 25
};

var secondUser = firstUser;
console.log(secondUser);
// {"name":"Вася","age":25}

firstUser.name = 'Петя';
console.log(secondUser);
// {"name":"Петя","age":25}

В объектах могут храниться любые типы данных, в том числе и функции. Такие свойства-функции называются методами объектов. Вызов метода записывается так: объект.метод().

Изнутри методов можно обращаться к свойствам и другим методам объекта с помощью ключевого слова this. Оно указывает на текущий объект и называется контекстом вызова.

Важная деталь: пока функция не вызвана, this не содержит никакого значения, контекст появляется только в момент вызова функции. 

var user = {
    name: 'Вася',
    age: 25,

    getGreeting: function() {
        return 'Привет! Меня зовут ' + this.name;
    }
};

console.log(user.getGreeting()); // 'Привет! Меня зовут Вася'

Мапы или словари очень удобны в использовании. В нашем примере они хранят соотношение имени пользователя и лакомства, которое по вкусу именно ему.

var userFavoriteFood = {
    Вася: 'рыба'
};

var printFavoriteFood = function(name) {
    //Используем скобочную нотацию
    return 'Моя любимая еда — ' + userFavoriteFood[name];
};

console.log(printFavoriteFood('Вася')); // 'Моя любимая еда — рыба'

Работа с DOM

Поиск элементов на странице

// Поиск элемента по тегу
var list = document.querySelector('ul');

// Поиск последнего элемента из списка
var lastProduct = document.querySelector('li:last-child');

// Поиск элемента по классу
var price = document.querySelector('.price');

// Поиск третьего элемента из списка товаров
var thirdProduct = document.querySelector('.product:nth-child(3)');

// Поиск всех элементов, подходящих по селектору
var listItems = document.querySelectorAll('.product');

querySelectorAll возвращает список (коллекцию) элементов. Этот список похож на массив, но им не является. Он называется псевдомассив и его можно перебирать с помощью цикла for.

Добавление класса элементу страницы

// Когда ищем элемент по классу, используем точку
var product = document.querySelector('.product');

// Но когда добавляем класс, точки нет!
product.classList.add('product--sale'); 

Результат работы classList.add() такой же, как при ручном добавлении класса в разметку:

<!-- Исходное состояние разметки -->
<li class="product">
  …
</li>

<!-- Состояние после вызова classList.add -->
<li class="product product--sale">
  …
</li>

Свойство DOM-элемент.children возвращает коллекцию дочерних, то есть вложенных, DOM-элементов.

Создание элемента и добавление его в DOM-дерево

var list = document.querySelector('.cards');

// Создаём новый элемент
var card = document.createElement('li');

card.classList.add('card');

// После вызова этого метода новый элемент отрисуется на странице
list.appendChild(card);

Вот что произойдёт с разметкой после вызова appendChild

<!-- Исходное состояние разметки -->
<ul class="cards">
  <li class="card">Существующий элемент</li>
</ul>

<!-- Состояние после вызова appendChild -->
<ul class="cards">
  <li class="card">Существующий элемент</li>
  <li class="card">Добавленный элемент</li>
</ul>

Работа с текстовым содержимым элемента

<p>Я — <em>текстовый элемент</em>.</p>
var p = document.querySelector('p');
console.log(p.textContent); // 'Я — текстовый элемент.'

p.textContent = 'Теперь у меня новое содержимое.';
console.log(p.textContent); // 'Теперь у меня новое содержимое.'

В HTML содержание тега изменится:

<p>Теперь у меня новое содержимое.</p> 

Report Page