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

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

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

let phrase = message;

В результате мы имеем две независимые переменные, каждая из которых хранит строку "Hello!".

Переменная хранит не сам объект, а его «адрес в памяти», другими словами «ссылку» на него.

Проиллюстрируем это:

let user = {

name: "John"

};

Сам объект хранится где-то в памяти. А в переменной user лежит

«ссылка» на эту область памяти. Когда переменная объекта копируется – копируется ссылка, сам же объект не дублируется.

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

1let user = { name: 'John' }

2let admin = user

admin.name = 'Pete'

3

// изменено по ссылке из переменной "admin"

alert(user.name)

4// 'Pete', изменения видны по ссылке из переменной

"user"

Приведённый выше пример демонстрирует, что объект только один. Как если бы у нас был один ящик с двумя ключами, и мы использовали один из них (admin), чтобы войти в него и что-то изменить, а затем, открыв ящик другим ключом (user), мы бы увидели эти изменения.

§20.15 Сравнение объектов

JavaScript предоставляет два оператора сравнения равенства величин:

равенство («двойное равно») использует ==,

21

строгое равенство (или «тройное равно» или «идентично») использует

===.

В общих чертах, двойное равно перед сравнением величин производит приведение типов; тройное равно сравнивает величины без приведения (если величины разных типов, вернёт false, даже не сравнивая).

Следует отметить, что все эти различия в сравнениях применимы лишь для примитивов. Для любых не примитивных объектов x и y, которые имеют одинаковые структуры, но представляют собой два отдельных объекта

(переменные x и y не ссылаются на один и тот же объект), все операторы сравнения вернут false.

При сравнении значений разных типов JavaScript приводит каждое из них к числу.

Например:

alert('2' > 1); // true, строка '2' становится числом 2

alert('01' == 1); // true, строка '01' становится числом 1

Логическое значение true становится 1, а false – 0.

Например:

alert(true == 1); // true

alert(false == 0); // true

Использование обычного сравнения == может вызывать проблемы.

Например, оно не отличает 0 от false:

alert(0 == false); // true

Та же проблема с пустой строкой:

alert('' == false); // true

Это происходит из-за того, что операнды разных типов преобразуются оператором == к числу. В итоге, и пустая строка, и false становятся нулём.

Оператор строгого равенства === проверяет равенство без

приведения типов.

22

Другими словами, если a и b имеют разные типы, то проверка a === b

немедленно возвращает false без попытки их преобразования.

Давайте проверим:

alert( 0 === false ); // false, так как сравниваются разные

типы

Ещё есть оператор строгого неравенства !==, аналогичный !=.

Рассмотрим, как происходит сравнение строк. Чтобы определить, что одна строка больше другой, JavaScript использует «алфавитный» или

«лексикографический» порядок.

Другими словами, строки сравниваются посимвольно.

Например:

alert( 'Я' > 'А' ); // true alert( 'Коты' > 'Кода' ); // true alert( 'Сонный' > 'Сон' ); // true

Алгоритм сравнения двух строк довольно прост:

1.Сначала сравниваются первые символы строк.

2.Если первый символ первой строки больше (меньше), чем первый символ второй, то первая строка больше (меньше) второй. Сравнение завершено.

3.Если первые символы равны, то таким же образом сравниваются уже вторые символы строк.

4.Сравнение продолжается, пока не закончится одна из строк.

5.Если обе строки заканчиваются одновременно, то они равны.

Иначе, большей считается более длинная строка.

В примерах выше сравнение 'Я' > 'А' завершится на первом шаге, тогда как строки 'Коты' и 'Кода' будут сравниваться посимвольно:

1.К равна К.

2.о равна о.

23

3. т больше, чем д. На этом сравнение заканчивается. Первая строка больше.

§20.16 Клонирование и объединение объектов

Как мы узнали ранее, при копировании переменной объекта создаётся ещё одна ссылка на тот же самый объект.

Но что, если нам всё же нужно дублировать объект? Создать независимую копию, клон?

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

Например,

1

let user = {

 

 

 

 

2

name: "John",

 

 

 

 

3

age: 30

 

 

 

 

4

};

 

 

 

 

5

let clone = {}; // новый пустой объект

 

 

 

 

6

// скопируем все свойства user в него

 

 

 

 

7

for (let key in user) {

 

 

 

 

8

clone[key] = user[key];

 

 

 

 

9

}

 

 

 

 

10

// теперь в переменной clone находится абсолютно

 

независимый клон объекта.

 

 

 

 

 

 

11

clone.name = "Pete"; // изменим в нём данные

 

 

 

 

12

alert(user.name); // в оригинальном объекте значение

 

свойства `name` осталось прежним – John.

 

 

 

 

 

 

 

Кроме того, для этих целей мы можем использовать метод

Object.assign.

Синтаксис:

Object.assign(dest, [src1, src2, src3...])

24

Аргументы dest, и src1, ..., srcN (может быть столько, сколько нужно)

являются объектами.

Метод копирует свойства всех объектов src1, ..., srcN в объект dest. То есть, свойства всех перечисленных объектов, начиная со второго, копируются в первый объект. После копирования метод возвращает объект dest.

Например, объединим несколько объектов в один:

1let user = { name: "John" };

2let permissions1 = { canView: true };

3let permissions2 = { canEdit: true };

//копируем все свойства из permissions1 и permissions2

в user

5 Object.assign(user, permissions1, permissions2);

// now user = {name: "John", canView: true, canEdit:

6

true}

Если принимающий объект (user) уже имеет свойство с таким

именем, оно будет перезаписано.

Мы также можем использовать Object.assign для простого

клонирования:

1let user = {

2name: "John",

3age: 30

4};

5let clone = Object.assign({}, user);

Все свойства объекта user будут скопированы в пустой объект, и

ссылка на этот объект будет в переменной clone. На самом деле, такое клонирование работает так же, как и через цикл, но короче.

§20.17 Массивы

Для хранения упорядоченных коллекций существует особая структура данных, которая называется массив, Array.

25

Существует два варианта синтаксиса для создания пустого массива:

let arr = new Array();

let arr = [];

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

let fruits = ["Яблоко", "Апельсин", "Слива"];

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

alert(fruits[0]); // Яблоко alert(fruits[1]); // Апельсин alert(fruits[2]); // Слива

Мы можем заменить элемент:

fruits[2] = 'Груша';

// теперь ["Яблоко", "Апельсин", "Груша"]

Можем добавить новый к существующему массиву:

fruits[3] = 'Лимон';

// теперь ["Яблоко", "Апельсин", "Груша", "Лимон"]

Общее число элементов массива содержится в его свойстве length:

alert(fruits.length); //4

Вывести массив целиком можно при помощи alert:

alert(fruits); // Яблоко, Апельсин, Груша, Лимон

В массиве могут храниться элементы любого типа.

Например:

let arr = ['Яблоко', { name: 'Джон' }, true,

1

function() { alert('привет');}];

// получить элемент с индексом 1 (объект) и затем

2

показать его свойство

26

3

alert(arr[1].name); // Джон

 

 

4

// получить элемент с индексом 3 (функция) и

выполнить её

 

 

 

5

arr[3](); // привет

 

 

 

§20.18 Методы pop/push, shift/unshift

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

push добавляет элемент в конец.

shift удаляет элемент в начале, сдвигая очередь, так что второй элемент становится первым.

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

Существует и другой вариант применения для массивов – структура данных, называемая стек. Она поддерживает два вида операций:

push добавляет элемент в конец.

pop удаляет последний элемент.

Таким образом, новые элементы всегда добавляются или удаляются из

«конца».

Методы, работающие с концом массива:

pop

Удаляет последний элемент из массива и возвращает его:

1 let fruits = ["Яблоко", "Апельсин", "Груша"]

2 alert(fruits.pop()) // удаляем "Груша" и выводим его

3 alert(fruits) // Яблоко, Апельсин

push

Добавляет элемент в конец массива:

1 let fruits = ["Яблоко", "Апельсин"];

27

2

fruits.push("Груша");

 

 

3

alert(fruits); // Яблоко, Апельсин, Груша

 

 

Вызов fruits.push(...) равнозначен fruits[fruits.length] = ....

Методы, работающие с началом массива:

 

shift

 

Удаляет из массива первый элемент и возвращает его:

 

 

1

let fruits = ["Яблоко", "Апельсин", "Груша"];

 

 

2

alert(fruits.shift()); // удаляем Яблоко и выводим его

 

 

3

alert(fruits); // Апельсин, Груша

 

 

 

unshift

 

Добавляет элемент в начало массива:

 

 

1

let fruits = ["Апельсин", "Груша"];

 

 

2

fruits.unshift('Яблоко');

 

 

3

alert(fruits); // Яблоко, Апельсин, Груша

 

 

§20.19 Перебор элементов

Одним из самых классических способов перебора элементов массива

является цикл for по индексам элементов:

1

let arr = ["Яблоко", "Апельсин", "Груша"];

 

 

2

for (let i = 0; i < arr.length; i++) {

 

 

3

alert(arr[i]);

 

 

4

}

 

 

 

Но для массивов возможен и другой вариант цикла, for..of:

 

 

1

let fruits = ["Яблоко", "Апельсин", "Слива"];

 

 

2

for (let fruit of fruits) {

 

 

3

alert(fruit);

 

 

4

}

 

 

 

28

§20.20 Свойство length

Свойство length автоматически обновляется при изменении массива.

Если быть точными, это не количество элементов массива, а наибольший цифровой индекс плюс один.

Например, единственный элемент, имеющий большой индекс, даёт большую длину:

1let fruits = [];

2fruits[123] = "Яблоко";

3alert(fruits.length); // 124

Ещё один интересный факт о свойстве length – его можно перезаписать.

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

1 let arr = [1, 2, 3, 4, 5];

2 arr.length = 2; // укорачиваем до двух элементов

3 alert(arr); // [1, 2]

4 arr.length = 5; // возвращаем length как было

alert(arr[3]); // undefined: значения не

5

восстановились

Таким образом, самый простой способ очистить массив – это

arr.length = 0;.

§20.21 Метод splice для работы с массивами

Метод arr.splice() – это универсальный «швейцарский нож» для работы с массивами. Умеет всё: добавлять, удалять и заменять элементы.

Его синтаксис:

arr.splice(index[, deleteCount, elem1, ..., elemN])

29

Он начинает с позиции index, удаляет deleteCount элементов и

вставляет elem1, ..., elemN на их место. Возвращает массив из удалённых

элементов.

Пример удаления:

1 let arr = ["Я", "изучаю", "JavaScript"];

arr.splice(1, 1); // начиная с позиции 1, удалить

2

один элемент

3alert(arr); // осталось ["Я", "JavaScript"]

Вследующем примере мы удалим 3 элемента и заменим их двумя

другими.

let arr = ["Я", "изучаю", "JavaScript", "прямо",

1

"сейчас"];

2// удалить 3 первых элемента и заменить их другими

3arr.splice(0, 3, "Давай", "танцевать");

Здесь видно, что splice возвращает массив из удалённых элементов:

let arr = ["Я", "изучаю", "JavaScript", "прямо",

1

"сейчас"];

2// удалить 2 первых элемента

3let removed = arr.splice(0, 2);

§20.22 Тег <script>

Поместим фрагмент сценария на языке JS непосредственно в HTML-код.

Данный фрагмент содержит метод alert(), который выводит окно c

сообщением на экран. Код сценария должен размещаться внутри тега

<script>. Этот тег помещается в произвольное место HTML-кода, но обычно помещается внутрь заголовка <head>.

1

<script type="text/javascript">

2

function hello()

3

{

4

alert("Hello World!");

5

}

 

30