Добавил:
Преподаватель Колледжа информационных технологий Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции / Глава 20. Введение в JS

.pdf
Скачиваний:
43
Добавлен:
08.05.2022
Размер:
1.04 Mб
Скачать

месте могло бы быть и более сложное выражение, которое бы вычислялось и

присваивалось при отсутствии параметра.

Например:

function showMessage(from, text = anotherFunction())

1

{

// anotherFunction() выполнится только если не

2

передан text

3// результатом будет значение text

4}

Функция может вернуть результат, который будет передан в вызвавший её код. Простейшим примером может служить функция сложения двух чисел:

1function sum(a, b) {

2return a + b;

3}

4let result = sum(1, 2);

5alert(result); // 3

Директива return может находиться в любом месте тела функции. Как только выполнение программы доходит до этого места, функция останавливается, и значение возвращается в вызвавший её код (присваивается переменной result выше). Если используется директива return без значения, то это приводит к немедленному завершению работы функции.

§20.7 Function Expression

Синтаксис, который мы использовали до этого при объявлении функции, называется Function Declaration (Объявление Функции):

1function sayHi()

2{

3alert( "Привет" );

4}

11

Существует ещё один синтаксис создания функций, который называется

Function Expression (Функциональное Выражение).

Оно выглядит вот так:

1let sayHi = function()

2{

3alert("Привет");

4};

Вкоде выше функция создаётся и явно присваивается переменной, как любое другое значение. По сути без разницы, как мы определили функцию,

это просто значение, хранимое в переменной sayHi.

 

 

Смысл обоих примеров кода одинаков: "создать функцию и поместить

её значение в переменную sayHi".

 

 

Мы можем даже вывести это значение с помощью alert:

 

 

 

 

1

function sayHi()

 

 

 

 

2

{

 

 

 

 

3

alert("Привет");

 

 

 

 

4

}

 

 

 

 

5

alert(sayHi); // выведет код функции

 

 

 

Обратите внимание, что последняя строка не вызывает функцию sayHi,

после её имени нет круглых скобок. Существуют языки программирования, в

которых любое упоминание имени функции совершает её вызов. JavaScript –

не один из них.

В JavaScript функции – это значения, поэтому мы и обращаемся с ними,

как со значениями. Код выше выведет строковое представление функции,

которое является её исходным кодом.

Мы можем скопировать функцию в другую переменную:

1 function sayHi() { // (1) создаём

2alert("Привет");

3}

12

4

let func =

sayHi;

// (2)

копируем

 

 

 

 

 

5

func(); //

Привет

// (3)

вызываем копию

(работает)!

 

 

 

 

 

 

 

 

6

sayHi(); // Привет

// прежняя тоже работает

 

 

 

 

 

Давайте подробно разберём всё, что тут произошло:

1.Объявление Function Declaration (1) создало функцию и присвоило её значение переменной с именем sayHi.

2.В строке (2) мы скопировали её значение в переменную func. Обратите внимание: нет круглых скобок после sayHi. Если бы они были, то выражение func = sayHi() записало бы результат вызова sayHi() в

переменную func, а не саму функцию sayHi.

3.Теперь функция может быть вызвана с помощью обеих переменных sayHi() и func().

Заметим, что мы могли бы использовать и Function Expression для того,

чтобы создать sayHi в первой строке:

1let sayHi = function() {

2alert("Привет");

3};

4let func = sayHi;

5// ...

§20.8 Функции-стрелки

Существует ещё более простой и краткий синтаксис для создания функций, который часто лучше, чем синтаксис Function Expression.

Он называется «функции-стрелки» или «стрелочные функции» (arrow functions), т.к. выглядит следующим образом:

let func = (arg1, arg2, ...argN) => expression

Такой код создаёт функцию func с аргументами arg1..argN и

вычисляет expression с правой стороны с их использованием, возвращая результат.

13

Другими словами, это более короткий вариант такой записи:

let func = function(arg1, arg2, ...argN) {return expression;};

Давайте взглянем на конкретный пример:

 

/* Более короткая форма для:

let sum = (a, b) => a + b;

let sum = function(a, b) {

 

return a + b;

alert(sum(1, 2)); // 3

};

 

*/

С фигурными скобками: (...args) => { body } – скобки позволяют нам писать многострочные инструкции внутри функции, но при этом необходимо указывать директиву return, чтобы вернуть какое-либо значение.

§20.9 Объекты

Объекты же используются для хранения коллекций различных значений и более сложных сущностей. В JavaScript объекты используются очень часто,

это одна из основ языка.

Объект может быть создан с помощью фигурных скобок {…} с

необязательным списком свойств. Свойство – это пара «ключ: значение», где ключ – это строка (также называемая «именем свойства»), а значение может быть чем угодно.

Пустой объект («пустой ящик») можно создать, используя один из двух вариантов синтаксиса:

1let user = new Object()

2let user = {}

Обычно используют вариант с фигурными скобками {...}. Такое объявление называют литералом объекта или литеральной нотацией.

При использовании литерального синтаксиса {...} мы сразу можем поместить в объект несколько свойств в виде пар «ключ: значение»:

1 let user = { // объект

14

name: "John", // под ключом "name" хранится значение

2

"John"

3age: 30 // под ключом "age" хранится значение 30

4};

Свойства объекта также иногда называют полями объекта.

У каждого свойства есть ключ (также называемый «имя» или

«идентификатор»). После имени свойства следует двоеточие ":", и затем указывается значение свойства. Если в объекте несколько свойств, то они перечисляются через запятую.

Для обращения к свойствам используется запись «через точку»:

1// получаем свойства объекта:

2alert(user.name); // John

3alert(user.age); // 30

Значение может быть любого типа. Давайте добавим свойство с логическим значением:

user.isAdmin = true;

Для удаления свойства мы можем использовать оператор delete:

delete user.age;

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

1let user = {

2name: "John",

3age: 30,

4"likes birds": true

5};

§20.10 Вычисляемые свойства

Мы можем использовать квадратные скобки в литеральной нотации для создания вычисляемого свойства.

Пример:

15

1

let fruit = prompt("Какой фрукт купить?", "apple");

 

 

2

let bag = {

 

 

3

[fruit]: 5, // имя свойства будет взято из переменной

fruit

 

 

 

4

};

 

 

5

alert(bag.apple); // 5, если fruit="apple"

 

 

Смысл вычисляемого свойства прост: запись [fruit] означает, что имя свойства необходимо взять из переменной fruit.

И если посетитель введёт слово "apple", то в объекте bag теперь будет лежать свойство {apple: 5}.

§20.11 Свойство из переменной

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

Например:

1

function

makeUser(name, age) {

 

 

 

2

return

{

 

 

3

name: name,

 

 

4

age: age,

 

 

 

5

};

 

 

 

 

6

}

 

 

 

7

let user = makeUser("John", 30);

 

 

8

alert(user.name); // John

 

 

 

В примере выше название свойств name и age совпадают с названиями переменных, которые мы подставляем в качестве значений этих свойств.

Такой подход настолько распространён, что существуют специальные

короткие свойства для упрощения этой записи.

Вместо name:name мы можем написать просто name:

1 function makeUser(name, age) {

16

2

return {

 

 

3

name, // то же самое, что и name: name

 

 

4

age, // то же самое, что и age: age

 

 

5

// ...

 

 

6

};

 

 

7

}

 

 

 

§20.12 Проверка существования свойства

Особенность объектов в том, что можно получить доступ к любому свойству. Даже если свойства не существует – ошибки не будет! При обращении к свойству, которого нет, возвращается undefined. Это позволяет просто проверить существование свойства – сравнением его с undefined:

let user = {};

alert(user.noSuchProperty === undefined); // true означает

"свойства нет"

Также существует специальный оператор "in" для проверки

существования свойства в объекте.

Синтаксис оператора:

"key" in object

Пример:

1 let user = {name: "John", age: 30}

alert("age" in user)

2

// true, user.age существует

alert("blabla" in user)

3

// false, user.blabla не существует

Обратите внимание, что слева от оператора in должно быть имя свойства. Обычно это строка в кавычках.

17

§20.13 Циклы

При написании скриптов зачастую встаёт задача сделать однотипное действие много раз.

Например, вывести товары из списка один за другим. Или просто перебрать все числа от 1 до 10 и для каждого выполнить одинаковый код.

Для многократного повторения одного участка кода предусмотрены циклы.

§20.13.1 Цикл while

Цикл while имеет следующий синтаксис:

while (condition) {

//код

//также называемый "телом цикла"

}

Код из тела цикла выполняется, пока условие condition истинно.

Например, цикл ниже выводит i, пока i < 3:

let i = 0;

while (i < 3) { // выводит 0, затем 1, затем 2 alert( i );

i++;

}

§20.13.2 Цикл do-while

Проверку условия можно разместить под телом цикла, используя специальный синтаксис do…while:

do {

// тело цикла

}while (condition);

Цикл сначала выполнит тело, а затем проверит условие condition, и

пока его значение равно true, он будет выполняться снова и снова.

18

Например:

let i = 0;

do {

alert( i );

i++;

} while (i < 3);

Такая форма синтаксиса оправдана, если вы хотите, чтобы тело цикла выполнилось хотя бы один раз, даже если условие окажется ложным.

§20.13.3 Цикл for

Более сложный, но при этом самый распространённый цикл — цикл for.

Выглядит он так:

for (начало; условие; шаг) {

// ... тело цикла ...

}

Давайте разберёмся, что означает каждая часть, на примере. Цикл ниже выполняет alert(i) для i от 0 до (но не включая) 3:

for (let i = 0; i < 3; i++) {

// выведет 0, затем 1, затем 2

alert(i);

}

Рассмотрим конструкцию for подробней:

часть

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

начало

 

 

i = 0

 

 

Выполняется один раз при входе в цикл

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Проверяется перед каждой итерацией цикла. Если оно

условие

 

 

i < 3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

вычислится в

false

, цикл остановится.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Выполняется после тела цикла на каждой

шаг

 

 

 

i++

 

 

 

 

 

 

 

 

итерации перед проверкой условия.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Выполняется снова и снова, пока условие вычисляется

тело

 

alert(i)

 

 

 

 

 

 

 

 

 

 

 

в

true.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

19

 

 

 

 

То есть, начало выполняется один раз, а затем каждая итерация заключается в проверке условия, после которой выполняется тело и шаг.

§20.13.4 Цикл for…in

Для перебора всех свойств объекта используется цикл for..in. Этот цикл отличается от изученного ранее цикла for(;;).

Синтаксис:

 

for (key in object)

 

{

 

// тело цикла выполняется для каждого свойства объекта

 

}

 

К примеру, давайте выведем все свойства объекта user:

 

 

1

let user = {

 

 

2

name: "John",

 

 

3

age: 30,

 

 

4

isAdmin: true

 

 

5

};

 

 

6

for (let key in user) {

 

 

7

// ключи

 

 

8

alert(key); // name, age, isAdmin

 

 

9

// значения ключей

 

 

10

alert(user[key]); // John, 30, true

 

 

11

}

 

 

 

§20.14 Копирование по ссылке

Одним из фундаментальных отличий объектов от примитивных типов данных является то, что они хранятся и копируются «по ссылке».

Примитивные типы: строки, числа, логические значения – присваиваются и копируются «по значению».

Например:

let message = "Hello!";

20