Page 1

Майкл Моррисон

Изучаем J

a

v

a

S

c

r

i

p

t

Улучшай качество взаимодействия пользователя с веб-страницей

ШЛІя«ЖіТоЧ

Научись оптимизировать

Освой концепцию и синтаксис JavaScript максимально эффективно

Управляй НТМЬ-кодом с помощью ООМ

J a v a S c rip t-к o д

Избавься от страха перед обработчиком событий

Проверяй свои знания с помощью сотен упражнений и примеров


Head First JavaScript Wouldn't it be dreamy if th e re was a way to learn JavaScript from a book w ithout wanting to set fir e to it halfway through and swearing o f f th e Web forever? I know, it's probably ju s t a fantasy...

M ichael M orrison

O ’R E IL L Y ' Beijing • Cambridge • Farnham • Koin • Sebastopol • To/cyo


Изучаем JavaScгipt Как было бы здорово изучить JavaScгipt, не испытывая желания бросить все на половине пути и никогда больше не заходить в Интернет! Наверное, об этом можно только мечтать...

Майкл Моррисон

Москва ■Санкт-Петербург ■Нижний Новгород ■Воронеж Ростов-на-Дону ■Екатеринбург • Самара ■Новосибирск Киев • Харьков ■Минск

2012


Майкл Моррисон

Изучаем JavaScript Перевела с английского И. Рузмайкина Заведующий редакцией Руководитель проекта Ведущий редактор Научный редактор Литературный редактор Художественный редактор Корректоры Верстка

А. Кривцов А, Юрченко Ю. Сергиенко С. Бойко Е. Пасечник Л. Адуевская В. Листова, И, Тимофеева Л. Харитонов

ББК 32.988.02-018.1 УДК 004.43

Моррисон М. М80

Изучаем JavaScript. — СПб.: Питер, 2012. — 608 с.: ил. ISBN 978-5-459-00322-2 Вы готовы сделать щаг вперед в своей практике веб-программирования и перейти от верстки в HTML и CSS к созданию полноценных динамических страниц? Тогда пришло время познако­ миться с самым «горячим» языком программирования — JavaScript! С помощью этой книги вы узнаете все о языке JavaScript: от переменных до циклов. Вы пойме­ те, почему разные браузеры по-разному реагируют на код и как написать универсальный код, поддерживаемый всеми браузерами. Вам станет ясно, почему с кодом JavaScript никогда не при­ дется беспокоиться о перегруженности страниц и ошибках передачи данных. Не пугайтесь, даже если ранее вы не написали ни одной строчки кода, — благодаря уникальному формату подачи материала эта книга с легкостью проведет вас по всему пути обучения: от написания простейше­ го java-CKpHHTa до создания сложных веб-проектов, которые будут работать во всех современных браузерах. Особенностью данного издания является уникальный способ подачи материала, вьщеляющий серию «Head First» издательства O ’Reilly в ряду множества скучных книг, посвященных про­ граммированию.

ISBN 978-0596527747 англ.

ISBN 978-5-459-00322-2

© Authorized Russian translation of the English edition of Head First JavaScript © O'Reilly Media, Inc. This translation Is published and sold by permission of O'Reilly Media, Inc., the owner of all rights to publish and sell the same. © Перевод на русский язык ООО Издательство «Питер», 2012 © Издание на русском языке, оформление ООО Издательство «Питер», 2012

Права на издание получены по соглашению с O’Reilly. Все права защищены. Никакая часть данной книги не может быть воспроизведе­ на в какой бы то ни было форме без письменного разрешения владельцев авторских прав. Информация, содержащаяся в данной книге, получена из источников, рассматриваемых издательством как надежные. Тем не менее, имея в виду возможные человеческие или технические ошибки, издательство не может гарантировать абсолютную точность и полноту приводимых сведений и не несет ответственности за возможные ошибки, связанные с использованием книги.

ООО «Мир книг», 198206, Санкт-Петербург, Петергофское шоссе, 73, лит. А29. Налоговая льгота — общероссийский классификатор продукции ОК 005-93, том 2; 95 3005 — литература учебная. Подписано в печать 27.09.11. Формат 84x100/16. Уел. п. л. 63,840. Тираж 2500. Заказ 26462. Отпечатано по технологии CtP в ОАО «Первая Образцовая типография», обособленное подразделение «Печатный двор». 197110, Санкт-Петербург, Чкаловский пр., 15.


П освящ ается ребятам из Ые15саре, которы е ещ е в про­ шлом веке мечтали, чтобы И н терн ет стал чем-то боль­ шим, чем гигантской книгой с массой гиперссылок. Х отя, конечно, это они намечтали ужасный тег < Ы 1пк>... продем онстрировав, что в мечтах не следует заходить слишком далеко!


обавтщге

Автор книги Head First JavaScript оЗаренныМ & о6а с т и J a v a S c r ip t .

И Эйже сейчас он ост ался .ребенком, который никак не хочет раст и.

П ервы м ком пью тером М ай кла М о р р и со н а был Т1-99/4А, укомплектованны й эргоном ичной клавиату­ рой, черно-белым «монитором», роль которого играл телевизор, и набором кассет со стереосистем ой. С того врем ени он сменил множ ество компью теров, но до сих пор скучает по играм в Parsec на стареньком TI. В настоящ ее время интересы М айкла сместились в сто­ рону создания и нтерактивны х веб-прилож ений и... катания на роликовой доске. К реш ению технических проблем он подходит с той ж е беспечной отвагой, как к рискованному спорту. Создав несколько видеоигр, изобретя пару игрушек, написав дюжину ком пью терны х книг и основав множ ество ком пью терны х курсов, Майкл наконец приш ел к идее написать книгу, посвященную JavaScript. Впрочем, по-настоящему подготовиться к написанию книг серии H ead First невозможно. Нужно просто п ри ­ нять красную пилюлю и провалиться в М атрицу, которая назы вается H ead First. Получив такой опыт, Майкл уже никогда не будет см отреть на процесс обучения постарому. Чему он крайне рад. Сейчас он с ж еной сидит на берегу своего пруда с золоты м и рыбками, отраж аю щ е­ го чудеса и нтерактивного И нтернета.


содержание -т-

<^ацЖ ое содерж ание

Введение

23

1

И н теракти вн ая сеть: Реакции виртуального мира

35

2

Х ранение данных: Все на своем месте

65

3

И сследование клиента: Знакомство с браузером

115

4

G

Если на дороге развилка...

163

5

Ц иклы : Рискуя повториться

215

6

Функции: Многократное использование

267

7

Ф орм ы и п ровер ка данных: Л ) ) с т ои все р а с с ж а ж т

311

8

У правление страницами: Управление H T M L с DOM

363

9

О ж т ляем р,гншле:: Объекты как франкенданные

411

10

С пециальны е объекты; Работа со специальными объектами

465

11

Охота па. ош ибки: Когда сценарий не работает

499

12

Д инам ические данные: Удобные вебприложения

549

'Д е ] ^ ж а н и е

Введение В а ш м о з г д у м а е т о и а уа 8 с г1 р 1 . Вы сидите за книгой и пытае­ тесь что-нибудь выучить, но ваш мозг продолжает считать, что вся эта писанина не важна. Ваш мозг говорит; «Выгляни в окно! На свете есть более важные вещи. Например, серфинг или голодный тигр, ког­ да ты попался на его пути». Как заставить ваш мозг думать, что ваша жизнь действительно зависит от знания иауаЗспр!?

Д ля кого н аписана эта книга?

24

Мы знаем, о чем вы думаете

25

М етапознание: наука о мыш лении

27

Как заставить м озг повиноваться?

29

П рим и те к сведению

30

Т ехнические редакторы

32

Благодарности

33


содержание

и н т п е р а к т и Б н а я с е зп ь

Реакции виртуального мир Устали представлять Интернет набором пассивных стра­ ниц? Кто из нас не держал в руках книг. Их читаешь, в них находишь информацию. Но они не интерактивны. Как и интернет-страницы без JavaScript. Без сомнения, отправить данные формы и проделать другие трюки можно и при помощи кода HTML и CSS, но реальная интерактив­ ность требует более умного подхода и большей работы... зато и резуль­ тат впечатляет намного больше.

То, что нужно людям

36

и ничего... как будто говориш ь со стенкой

37

A JavaScript отвечает

3g

Свет, кам ера, взаимодействие!

40

Т ег <script>

45

Ваш браузер поним ает HTM L, CSS И JavaScript

46

П ом оги виртуальному другу человека

49

С делайте iRock и н терактивны м

50

Веб-страница iRock

51

Т ести рован и е

51

С обы тия

52

О повещ ение пользователей

53

iRock приветствует вас

54

Сделайте объект iRock действительно и н терактивны м

56

В заимодействие долж но бы ть Д В У С ТО РО Н Н И М

57

Как узнать имя пользователя

58

П олученны й результат

61

П роверка п ри лож ен и я iRock 1.0

62

ft is good to meet you, Paul.

10


содержание

Kl

»аш К ое с о д е р ж а н и е

Введение

23

1

И н теракти вн ая сеть: Реакции виртуального мира

35

2

Х ранение данных: Все на своем месте

65

3

И сследование клиента: Знакомство с браузером

115

4

П р и н яти е реш ений: £сли иа Эо/)оге^)(Мвгмка...

163

5

Ц иклы : Рискуя повториться

215

6

Функции: Многократное использование

267

7

Ф орм ы и п ровер ка данных: Пусть он все расскажет

311

8

У правление страницами: Управление H T M L с DOM

363

9

Ож ивляем данные: Объекты как франкенданные

411

С пециальны е объекты: Работа со специальными объектами

465

10 11

Охотг. на ош ибки: Когда сценарий не работает

499

12

Д и нам и ч ески е данные: Удобные вебприложения

549

О одержание Введение В а ш м о з г д у м а е т о и а уа З сг1 р 1 . Вы сидите за книгой и пытае­ тесь что-нибудь выучить, но ваш мозг продолжает считать, что вся эта писанина не важна. Ваш мозг говорит; «Выгляни в окно! На свете есть более важные вещи. Например, серфинг или голодный тигр, ког­ да ты попался на его пути». Как заставить ваш мозг думать, что ваша жизнь действительно зависит от знания иауаЗспр!?

Для кого н аписана эта книга?

24

Мы знаем, о чем вы думаете

25

М етапознание: наука о м ыш лении

27

К ак заставить м озг повиноваться?

29

П рим и те к сведению

30

Т ехнические редакторы

32

Благодарности

33


содержание

)(|> ан ен и е Д аннъ1х

Все на своем месте в реальном мире люди часто не придают значения местам для хранения своего имущества, в иауаЗспр! такое поведение не­ возможно. Ведь там не существует роскоши в виде огромных шкафов и га­ ражей на три машины, В иауаЗспр! все имеет свое место, и ваша задача в этом убедиться. Мы поговорим о данных — как их представить, как хранить их и как их найти после сохранения. Вы научитесь превращать захламленые комнаты с данными в аккуратные помещения с ящиками, каж­ дый из которых имеет пометку С охранение данны х

66

Т ипы данны х

67

Константы и переменны е: постоян н ое и изм еняем ое

72

И сходное состоян и е перем енны х

76

П р и своен и е значений

77

У прямы е константы

78

Ч то в им ени тебе моем?

82

К орректн ы е и н екорректн ы е им ена

83

СтильВерблю да

84

Следующий этап

87

П ланируем веб-страницу

88

И нициализируйте данные... или...

93

МаМ —это Н Е число

94

Складывать м ож но не только числа

96

М етоды раг 5е 1пс() и раг8еР1оа1()

97

Откуда берутся лиш ние пончики?

98

Дункан обнаруж ивает ш пиона

102

М етод getElem entB yId()

103

П роверка данны х ф орм ы

104

И нтуитивны й ввод данны х

109

11


содержание

Ц ссЛ еД оБ ан ие к л и е н т а

Знакомство с браузером Иногда иауаЗспр! хочет знать, что происходит в окружаю­ щем мире. Ваши сценарии могут существовать в качестве кода на веб­ страницах, но по большей части они живут в мире, создаваемом браузером или клиентом. Умным сценариям часто необходимо знать больше о мире, в котором они живут, в этом случае они могут общаться с браузером, чтобы узнать про него как можно больше. Независимо от того, что требуется узнать: размер экрана или нажата ли кнопка в браузере, они постоянно поддержива­ ют отношения с браузером.

12

К лиент, сервер и JavaS cript

Ц6

Ч то браузер мож ет сделать для вас?

118

О бъект 1Коск слиш ком счастлив

119

Т айм еры

122

Как раб о тает тайм ер

123

М етод 5е 1Т 1т е о и 1()

124

А нализ м етода 8е Ш т е о и 1()

125

Зависим ость от разм ера экрана

129

Ш и ри н а окна браузера

130

Задание ш и рины окна

131

Вы сота и ш ирина объекта 1Коск

132

1Коск долж ен соответствовать стран и ц е

133

С обы тие опге51ге

137

С обы тие опге 812е ДЛЯ камеш ка

138

Мы уже встречались?

140

Время ж изни сцен ари я

141

П родление врем ени ж изни сц ен ари я

142

Свойства куки

147

Код JavaScript ВНЕ веб-страницы

149

П ри ветстви е пользователя

150

М етод greetU ser() н а основе куки

151

С оздание куки

152

Влияние на безопасность

154

М ир без куки

156

Разговор с пользователям и... это лучше, чем н ичего

159


содержание

|> и н я1ц ие р»е1Нений

Если на дороге развилка... Жизнь неотделима от принятия решений. Стоять или идти,

пойти на сделку с негодяем или пойти в суд... Результата невозможно добиться без выбора. То же самое происходит в иауаЗспр! — вам приходится выбирать между различными вариантами сценария. Приходится то и дело при­ нимать решения. Стоит ли поверить данным, введенным пользователем, и отправить его охотиться на львов? Или же проверить еще раз, может быть, он всего лишь пытался заказать билет до Львова? Выбор за вами!

Welcone fo

S T IC K FIGURE ADVEW TURE flickeiiher buitoN to Start...

Счастливчик, спускайся ко мне!

164

«Уели» так, то сделай что-нибудь

166

О пер ато р if

167

Когда вариантов два

169

Вы м ож ете сделать м нож ественны й выбор

170

Клю чевое слово else

171

П ерем ен н ы е как двигатель истори и

174

Н едостаю щ ие части истори и

175

Совмещ ение усилий

176

Запись п ри помощ и if/e ls e

182

В лож енны й о п ер ато р if

183

У правление при помощ и методов

185

П севдокод

186

П роблем ы н арисованного человечка

190

!= т-с-с-с, мне нечего тебе сказать...

191

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

192

К ом м ентарии

194

К ом м ентарии начинаю тся с / /

195

О бласть видимости

197

П ровери м область видимости

198

Где ж ивут м ои данные?

199

Вы бор из пяти

202

П ереуслож нение конструкции

203

О п ер ато р sw itch /case

205

А нализ о п ер ато р а switch

206

Тест-драйв нового вари ан та «П риклю чений»

211

13


содержание

ДиКЛы

Рискуя повториться Говорят, что повторение — мать учения. Заниматься новыми и ин­ д

тересными делами здорово, но наши дни, как правило, состоят из рутины. Доведенное до автоматизма мытье рук, нервный тик, щелчок на кнопке Reply То АП при получении любого дурацкого сообщения! Кажется, повторение не самая лучшая вещь в этом мире. А вот в мире JavaScript без него никак. Вы удивитесь, как часто бывают востребованы одни и те же фрагменты кода. Здесь вам на помощь приходят циклы. Без них пришлось бы снова и снова набирать один и тот же код.

Available

seat_avail.png

Unavailable

I)

seaLunavaiI.png

Select

seat_selectpng

14

М есто пом ечено крестом

216

и снова дежавю... цикл for

217

О хота за сокровищ ам и с циклом for

218

Составны е части цикла for

219

Специальны е места для мачо

220

П роверка доступности мест

221

Ц иклы, H TM L и свободные кресла

222

Места, как перем енны е

223

М ассивы

224

Значен и я сохраняю тся с ключами

225

О т JavaScript к H TM L

229

Визуализация кресел

230

П роверка

235

Бескон ечн ы е циклы

236

Условие выхода и з цикла

237

П реры ван и е действия

238

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

244

Ц икл while

248

А нализ цикла while

249

Выбор подходящ его цикла

251

К и н отеатр —место м оделирования данных

257

Двумерные массивы

258

Д ва клю ча доступа

259

Двумерная версия M andango

261

Ц елы й ки н о театр мест для мачо

264


содержание

срункД ии

М ногократное использование Начни иауа8 сг1р1 выступать за экологию, это выступление возглавили бы функции. Ведь именно они увеличивают эффектив­ ность кода и позволяют использовать его многократно. Они ориентированы на решение задач и позволяют все систематизировать. Функции дают воз­ можность упростить любой сценарий, ну кроме разве что и так простых. Их значение невозможно оценить, поэтому просто скажем, что именно функции делают сценарии такими экологичными.

Lthrotjgh3mSow4areavaiia^e.Accept?

И сточн и к всех проблем

268

ф ункции как способ реш ения

270

И з чего состои т ф ункция

271

Уже знаком ы е вам функции

272

Улучшаем наш терм остат

275

П ередача и н ф орм ац и и функциям

276

Аргументы как данны е

277

И збавляем ся от дублирующегося кода

278

Функция, задающая места

281

Ф ункция 8е 18еа 1()

283

О братн ая связь

285

В озврат данных

286

Возвращ аемые значения

287

И н ф о р м ац и я о статусе места

291

О тображ ение статуса

292

Связь функции с изображ ением

293

Дублирующ ийся код

294

О тделите функциональность о т содерж имого

295

Ф ункции —это тож е данные

296

Вызов функции и ссылка на нее

297

С обы тия, обратн ы й вы зов и атрибуты Н ТМ Ь

301

Ссылки на ф ункции

302

Л и терал функции

303

А где ж е связывание?

304

О болочка Н ТМ Ь-страницы

307

15


содержание

и г 1]=>оБе|>ка Данных

Пусть он все р а сс ка ж ет Для получения информации от пользователей при помо­ щи иауа8сг1р1 вам не потребуется быть джентльменом. Но вы должны быть аккуратны. Люди часто делают ошибки, а это озна­ чает, что данные, полученные при помощи веб-форм, далеко не всегда корректны. Проверяя вводимые данные при помощи иауаЗспр!, вы увеличиваете надежность веб-приложений и снимаете дополнительную нагрузку с серверов. Полоса пропускания нам пригодится для восхити­ тельных видеороликов и чудесных фотографий.

^*осИу...Ьапое*

16

Н ТМ Ь-форма ф и рм ы Ваппегос11у

313

Когда язы ка Н ТМ Ь недостаточно

314

Доступ к данны м ф орм ы

315

Ц еп очка собы тий

317

С обы тие опЫ иг

318

С ообщ ение п роверки

319

П ро вер ка полей н а наличие данных

323

П роверка без предупреждаю щ их всплываю щ их окон

324

Усложняем наш валидатор

325

Разм ер им еет значение...

327

П ро вер ка длины

328

П ро вер ка индексов

333

П ро вер ка даты

338

Регулярны е вы раж ения н е «регулярны»

340

Задание ш аблона

341

М етасимволы

343

К оличество повторен и й

344

П ро вер ка данны х п ри помощ и регулярны х вы раж ений

348

Д иапазон вхож дений

351

Вы бери это... или то

353

Н икаких случайностей

354

Вы м еня слышите?

355

Вам письмо

356

И склю чение —это правило

357

Д ополнительны е символы

358

П ро вер ка адреса электрон н ой почты

359


содержание

Ул|=*аБЛение с т р а н и ц а м и

Управление HTML с DOM Управление содержимым веб-страницы при помощи Java­ Script напоминает приготовление еды. Конечно, это не настолько грязное занятие... И, увы, вы не сможете съесть результат своих трудов. Тем не менее вы получаете полный доступ к НТМи-тгрер,\лентам, из кото­ рых состоит веб-страница, и, что еще важнее, вы можете менять исходный рецепт. Ведь JavaScript дает возможность управлять HTML-кодом веб­ страницы, что открывает для вас целый ряд интереснейших перспектив, ко­ торые реализуются посредством набора стандартных объектов DOM.

html

j|;

r { ""‘‘у ^ ^ 0^ ------- 1

^

§

ф ункциональны й, но неудобный

364

Б ез всплываю щ их окон

365

Доступ к H TM L-элементам

367

Внутренний код элем ента

368

О бъектная модель документа (DOM)

373

Страница как набор узлов

374

Свойства узлов

377

Р едактирование текста

380

«П риклю чение», совместим ое со стандартами

385

П роекти рован и е лучше, варианты чищ е

387

И снова замена текста в узлах

388

Функция, заменяю щ ая текст узла

389

Д инам ические п арам етры

390

И нтеракти вн ость

391

Зн ачен и е стиля: CSS и DOM

392

Зам ена классов стилей

393

С тильны е варианты

394

П ро вер ка работы прилож ения

395

Пустая кнопка

396

Н астрой ка «а л я style»

397

кнопок Б ез ф и кти вн ы х кнопо

399

Усложняем «П риклю чения»

400

П оход по дереву реш ений

402

П ревратим историю в НТМ Т

403

О бработка НТМЕ-кода

404

О тслеж ивание «Приклю чений*

407

17


содержание

О ж ивляем данны е

Объекты к а к ф ранкенданны е Объекты иауа8сг1р1 вовсе не так ужасны, как заставил вас думать доктор. Зато они интересны тем, что соединяют друг с другом отдельные части языка иауаЗспр!, делая его более мощным. Объекты объединяют данные с действиями в новый тип, намного более «жи­ вой», чем все, что вы использовали раньше. Вы познакомитесь с масси­ вами, которые сортируют себя сами, со строками, которые умеют ис­ кать в своем составе указанные последовательности символов, и многими другими замечательными особенностями.

D ata

A c tio n s

var who;

function display(what, when, where) {

var what;

}

var when;

function deliver(who) {

var where;

1

O bject

function displayO

var who;

function deliver 0 {

var what; var when; var where;

18

{

Вечеринка в стиле JavaScript

412

Д анны е + действия = объект

413

Д анны е —это собственность объекта

414

Ссылка на члены объекта

415

Специальны е объекты

419

К онструктор

420

Структура конструктора

421

Создание объектов blog

422

Н еобходим ость сорти ровки

427

О бъект для дат

428

Вы числение времени

429

П ересм отр дат в блоге

430

О бъект внутри другого объекта

431

П реобразован и е объектов в текст

434

Доступ к ф рагм ентам даты

435

М ассивы как объекты

438

П ользовательская сортировка

439

У прощ ение сорти ровки

440

П оиск по массиву

443

М етод indexO f()

445

П оиск по блогу

446

П оиск заработал!

449

О бъект M ath

452

Генерация случайных чисел

454

П ревращ ен и е функции в метод

459

В осхитительны й новы й объект blog

460

Ч то даю т объекты блогу YouCube?

461

Ц


содержание

^оеД иаЛ ьН ы е о б ъ е к т ы

Работа со специальны ми объектами Если бы все было так легко, мы бы, конечно, так и сделали. иауаЗспр! не гарантирует возврат денег, но вы действительно можете делать с ним все, что захотите. Специальные объекты — это эквивалент тройного эспрессо с сахаром и корицей. Вот такая специальная чашка кофе! Точно так же в специальных объектах вы можете смешивать код, добиваясь именно того результата, который вам нужен, и пользуясь преимуществами свойств и методов. И в конце получается объектно-ориентированный код, расширяю­ щий язык иауаЗспр!... только для вас!

Objwr Instames

С нова о методах блога Y ouCube

466

П ерегрузка методов

467

Классы и реализации

468

Реализации

469

К лю чевое слово this

470

М етоды классов

471

П рототи п ы

472

Классы, п ро то ти п ы и Y ouCube

473

С войства общ его доступа

478

Создание свойств класса

479

П одписан и доставлен

481

Н ет дублирующемуся коду!

483

М етод ф орм ати рован и я данных

484

Р асш ирение стандартны х объектов —улучшенный блог

486

М етоды классов

487

Функция сравнения

489

Вызов м етода класса

490

К арти н ка стоит ты сячи слов

491

Вставка и зображ ений

492

Д обавление галереи

494

Блог н а основе объектов

496

19


содержание

0 х о г п а н а оШ ибки

Когда сценарий не работает Даже самые лучшие планы в иауаЗспр1 иногда не реализу­ ются. и когда это происходит, главное — не паниковать. Лучшие програм­ мисты не те, которые никогда не делали ошибок, — на самом деле это про­ сто лгуны. Лучшие — это те, кто может успешно обнаружить и устранить ошибку. Отладчики высокой квалификации нарабатывают хорошую манеру написания кода, минимизирующую вероятность появления неприятных оши­ бок. Лучше предотвратить, чем потом бороться. Тем не менее ошибки то и дело встречаются, и вам нужен арсенал средств борьбы с ними...

20

У странение деф ектов

500

П роблем ы с калькулятором для

501

Различны е баузеры

502

Н еслож ная отладка

505

Н еоп ределен н ы е перем енны е

509

Р абота с циф рам и

511

Звонки на радио

512

Н ачинаем расследование

513

П роверка синтаксиса (ош ибка #1)

514

А ккуратнее со строкам и

515

К авы чки и апостроф ы

516

Евс-символы

517

Н еоп ределен н ость ф ункции (О ш ибка #2)

518

П обеж даю т все (О ш ибка #3)

520

О тладка с помощ ью всплываю щ их окон

521

Следим за значением п ерем енной

522

Н еко р р ектн ая логика

524

П рои гры ваю т все! (О ш ибка #4)

528

Атака всплываю щ их окон

529

П ользовательская консоль

531

Самая проти вная ош ибка

538

Т ри самых популярны х ти п а ош ибок

539

К ом м ентарии

542

Дважды объявленны е перем енны е

544


содержание

инаМ иЧ есК ие д а н н ы е

Удобные веб-приложения Современный Интернет очень отзывчив, страницы умеют реагировать на каждый каприз пользователя. Именно об этом мечтают многие разработчики. JavaScript играет важную роль в осущест­ влении этой мечты при помощи технологии Ajax, позволяющей эффектив­ но менять «чувствительность» страниц. Благодаря Ajax страницы научились

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

youcube.html

шт

Ж аж да динам ических данных

550

Блог, управляем ы й данными

551

Ajax как возм ож ность для общ ения

553

Ф орм атирование с помощ ью XML

555

XML + H TM L = XH TM L

557

XML и данны е блога Y ouCube

559

Добавим к блогу Ajax

562

И н тер ф ей с X M L H ttpR equest

564

Запрос с объектом X M L H ttpR equest

567

А нализ запросов Ajax

571

Создание запросов

575

Закончиш ь —вы зови меня

576

О бработка ответа

577

DOM как выход из полож ения

578

Y ouCube, управляем ы й данными

583

Н еработаю щ ие кнопки

585

Кнопкам нужны данны е

586

Функция, экономящ ая время

589

Зап и сь данны х в блог

590

Т реб овани я РНР

593

Д анны е для РН Р-сценария

594

О тп равка данны х на сервер

597

Делаем работу с блогом еще удобнее

602

А втозаполнение полей

603

П овторяю щ аяся задача?

604

21


J’a ë o m a m b с э т ° й к н и Г о й

Введение

на JavaScript?»

23


как работать с этой книгой

Для кого написана эта книга? Если вы ответите «да» на все следующие вопросы. Имеете ли вы доступ к компьютеру с браузером, текстовым редактором и выходом в Интернет? Хотите ли ли вы научиться создавать веб­ страницы, превращающие работу в Интернете в по-настоящему интерактивный опыт? Вы предпочитаете оживленную беседу сухим, скучным академическим лекциям?

С нашей пом ощ ью вы научит есь JavaScrip t код M H ^ e c Z Z ^ ''^ ст^ан ы ц м делат ь вещей

““ “ ■’« в » » ...то эта книга для вас.

Кому эта книга не подойдет? Если вы ответите «да» н а лю бой из следующих вопросов. Вы никогда не создавали веб-страниц? (Быть знатоком HTML не обязательно, но вы должны понимать, какую роль в появлении страниц играют HTML и CSS и как опубликовать страницу в Интернете.) Считаете себя мастером написания сценариев и ищете справочник по JavaScript? Вы боитесь попробовать что-нибудь новое? Скорее пойдете к зубному врачу, чем наденете полосатое с клетчатым? Считаете, что техническая книга, в которой компоненты Java изображены в виде человечков, серьезной быть не может?

...эта книга не для вас.

В о о б щ е -т о

Z fS o z o ,

эт а книга и у кого ест ь деньги.I

24

введение


введение

Мы знаем, о чем Вы думаете «Разве серьезны е книги по програм м ированию нaJavaScript такие?» «И почему здесь столько рисунков?» ‘'« о э т о

«Можно ли так чему-нибудь научиться?»

и мы знаем, что думает Ваш мозг М озг жаждет новы х впечатлений. О н постоянно ищ ет, анализиру­ ет, ожидает чего-то необы чного. О н так устроен, и это помогает нам выжить. Как ж е наш мозг поступает со всеми обычными, повседневны ми вещами? О н всеми силами пы тается отгородиться от них, ч то­ бы он и не мешали его настоящей работе —сохранению тогб, что действительно важно. М озг не считает нужным сохранять скучную информ ацию . О на не проходит ф ильтр, отсекаю щ ий «очевидно несущественное». Н о как же мозг узнает, что важно? П редставьте, что вы выехали на прогулку и вдруг прямо перед вами появляется тигр. Ч то п ро­ исходит в ваш ей голове и в теле? Активизирую тся нейроны . Вспыхиваю т эмоции. П роисходят хим ические реакции. И тогда ваш мозг поним ает...

13дця

Конечно, это важно! Не забывать! А теп ерь представьте, что вы находитесь дома или в библиотеке, в теплом, уютном месте, где тигры не водятся. Вы учитесь —гото­ витесь к экзамену. И ли пы таетесь освоить сложную техническую тему, на которую вам выделили неделю... максимум десять дней. И тут возникает проблема: ваш мозг пытается оказать вам услугу. О н старается сделать так, чтобы на эту очевидно не­ существенную инф орм ацию не тратились драгоценны е ре­ сурсы. И х лучше потратить на что-нибудь важное. Н а тигров, например. И ли на то, что к огню лучше не прикасаться. Или на то, что вам не следовало соглашаться на просьбу друга по­ сидеть с его домашней анакондой. Н ет простого способа сказать своему мозгу: «Послушай, мозг, я тебе, конечно, благодарен, но какой бы скучной ни была эта книга, и пусть мой датчик эмоций сейчас на нуле, я запом нить то, что здесь написано».

дальше >

25


как работать с этой книгой

кяига ДЛЯ « е^ . Kffiкак мь, что-то затолкать в голову „ования. в

Х Т н е й р о б ш л о г и . и поихолоп.и обучения, для чем лросгой текст на отранице,

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

Основные принципы серии «Head First» .о

лучше, чем обычный текст, и значи-

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

тестировании составляло до 40 %.

лекций) улучшение результатов

^е относитесь к себе слишком се-

'’ ^ Т н Г Г Л ^ о Г е Г п р «

занимательная беседа за столом или лекция.

■ пока вы не начнете напрягать извилины, в вашей голове ниА кти в но е у частие читателя. Пока вы не ,^ _ ^ з р е с о в а н в результате; он должен решать чего не произойдет, читатель

знаниями. А для этого необходимы

;г :н е Г и Т а С : “

^р—

мозга и разные чувства. привлечение ,и

на интересное, странное,

И н т е р е с н о е узнается намного быстрее.

моииям И зве стн о , что н аш а с п о с о б н о с т ь за л о м и -

“? гп г™ .. . . .

;ь г :« р е о , з „ о „ . .- .я ь » ™ » « „ = » . -

Иы ,.п о » и и а ™ то, что . а » „е б е а р а э -ч н о , М » » " » " " " • ■ что-™ ч , . с . , е » . И .,, с е к ,.м .н т » . . е с . к» п р . ч .» : P J -

„дет о таких w o * . K , как ,» « .п е » « е , л к Л о п ы т с о , « г е р . ^ ........... .. .,«ТГ,ПУЮ окоужающие счиГ я кр утГп р и решении задачи, которую окружающие счи-

кот.. . »

4 .0 разбираетесь . т е .е „ у ч .е ,

чем всезнайка Боб из технического отдела.

26

введение

М


введение

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

Как бы теперь заставить свой мозг все это запомнить...

Н о раз вы читаете эту книгу, то, вероятно, вы хотите изучить п аттерны проектирования, и по возмож ности бы стрее. Вы хотите запомнить п рочи тан н ое и применять новую инф орм ацию на п ракти­ ке. Ч тобы извлечь максимум пользы из учебного процесса, нужно заставить ваш мозг восприним ать новы й м атериал как Н ечто Важ­ ное. К рити чное для вашего сущ ествования. Такое ж е важное, как тигр. И наче вам предстоит бесконечная борьба с вашим мозгом, которы й всеми силами уклоняется от запоминания новой инф орм ации.

Как же УБЕДИТЬ мозг, что иауаЗспр! так же важна, как и голодный тигр? Есть способ м едлен н ы й и скучны й, а есть б ы стры й и эф ф екти в н ы й . П ер вы й осн ован н а тупом п о вто р ен и и . Всем и звестн о , ч то даж е самую скучную и н ф о р м ац и ю можно зап ом н и ть, если п о в то р я ть ее сн ова и снова. П р и д о стато ч н о м кол и честве п о в то р е н и й ваш м озг п рикиды вает: «Вроде бы несущ ественно, но раз одно и то ж е п о в то р я етс я столько раз... Л адно, уговорил». Бы стры й способ основан на повышении активности мозга, и особенно на сочетании разны х ее видов. Д оказано, ч то все ф акторы , перечисленны е на предыдущей странице, помогаю т вашему мозгу работать на вас. Н априм ер, исследования показали, что разм ещ ение слов внутри рисунков (а не в под­ писях, в основном тексте и т. д.) заставляет мозг анализировать связи между текстом и граф икой, а это приводит к активизации большего количества нейронов. Больш е н ей ронов = выше вероятн ость того, что инф орм ация будет сочтена важ ной и достойной запоминания. Разговорны й стиль тож е важен: обычно люди проявляю т больше внимания, когда они участвуют в разговоре, так как им приходится следить за ходом беседы и высказы вать свое мнение. П ри чем мозг соверш енно не интересует что вы «разговариваете» с книгой! С другой стороны , если текст сух и ф о р ­ мален, то мозг чувствует то же, что чувствуете вы на скучной лекции в роли пассивного участника. Его клонит в сон. Н о рисунки и разговорны й стиль —это только начало. дальше

27


как работать с этой книгой

В о т что сделали МЫ: Мы использовали рисунки, потому что мозг лучше приспособлен для восприя­ ти я граф ики, чем текста. С точки зрен и я мозга картинка томгга ты сячи слов. А когда текст комбинируется с графикой, мы внедряем текст прямо в рисунки, потому что мозг при этом работает эффективнее. Мы используем избыпючность: повторяем одно и то же несколько раз, применяя разные средства передачи информ ации, обрапцаемся к разным чувствам —и все для повыш ения вероятности того, что материал будет закодирован в нескольких областях вашего мозга. Мы используем концепции и рисунки несколько неожиданным образом, потому что мозг лучше воспринимает новую информацию . Кроме того, рисунки и идеи обычно имеют эмоциональное содержание, потому что мозг обращ ает внимание на биохимию эмоций. То, что заставляет нас чувствовать, лучше запоминается — будь то шутка, удивление ш т интерес. Мы используем разговорный стиль, потому что мозг лучше воспринимает и нф ор­ мацию, когда вы участвуете в разговоре, а не пассивно слушаете лекцию. Это происходит и при чтении. Так как проделанное запоминается намного лучше прочитанного, в книге вы найдете более 80 упражнений. Надеемся, они заставят вас испы тать победное чувство «я смог это сделать!». Мы совместили несколько стилей обучения, потому что одни читатели лю бят по­ шаговые описания, другие стремятся сначала представить «общую картину», а третьим хватает фрагмента кода. Н езависимо от ваших личны х предпочтений полезно видеть несколько вариантов представления одного материала. Мы постарались задействовать оба полушария вашего мозга, это повыш ает веро­ ятность усвоения материала. П ока одна сторона мозга работает, др)тая имеет возможность отдохнуть; это повыш ает эф ф ективность обучения в течение про­ должительного времени. А еще в книгу включены истории и упражнения, отражаю щ ие другие точки зре­ ния. Мозг качественнее усваивает информацию , когда ему приходится оцени­ вать и выносить суждения. В книге часто встречаю тся вопросы, на которы е не всегда можно дать простой от­ вет, потому что мозг быстрее учится и запоминает, когда ему приходится что-то делать. Невозможно накачать мышцы, наблюдая за тем, как занимаются другие. Однако мы позаботились о том, чтобы усилия читателей были прилож ены в вер­ пом направлении. Вам не придется ломать голову над невразумительными приме­ рами или разбираться в сложном, перенасыщ енном техническим жаргоном или слишком лаконичном тексте. В историях, прим ерах, картинках «живут» люди. Ведь вы человек. И ваш мозг больше внимания уделяет людям, а не вещам.

28

введение

О Условие

о

Действие

Ш ТУРМ


введение

Ч то cMO}keme сделать ВЫ, чтобы заставить cßoü мозг повиноваться Мы свое дело сделали. О стальное за вами. Эти советы станут отправ­ н ой точкой; прислуш айтесь к своему мозгу и определите, что вам подходит, а что не подходит. П робуйте новое. В р е ж ь т е а прикрепит е ня холодильник.

©

Не торопитесь. Чем больше вы поймете, тем меньше придется запоминать. Н е просто читайте. Обдумывайте. Н а­ ты каясь на вопрос, не читайте ответ сразу. П редставьте, что вам его задал человек. Чем больше вы заставляете мозг думать, тем больше инф орм ации вы пойм ете и запомните.

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

Читайте раздел «Часто задаваемые вопросы». Это не просто вкладки с факультативной и нф орм ацией —это часть основного материала! Н е пропускайте их.

Читайте эту книгу перед сном. Ч асть обучения (особенно перенос инф орм ац ии в долгосрочную память) п ро­ исходит посмтото, как вы отклады ваете книгу. Ваш мозг не сразу усваивает и н ф ор­ мацию. Если во время обработки посту­ пит новая и нф орм ация, часть того, что вы узнали ранее, мож ет бы ть потеряна.

Пейте воду, и побольше воды. М озг лучше всего работает при избы тке жидкости. О безвож ивание уменьшает способность к познанию .

Говорите вслух. Речь активизирует другие участки мозга. Если вы пы таетесь что-то понять или получше запомнить, п роизн есите вслух. А еш;е лучше —попробуйте объяснить кому-нибудь другому. Вы будете бы стрее усваивать материал и, возможно, откроете для себя что-то новое.

Прислушивайтесь к своему мозгу. С тарайтесь понять, не перегруж ен ли мозг. Если только что прочи тан н ое сразу забы ва­ ется, явно пора на отдых. П ы таясь выучить сразу слишком много, вы не ускорите процесс усвоения материала, а, наоборот, зам едлите его.

Пусть это станет реальностью! П редставляйте себя героем историй. Д е­ лайте собственны е подписи к картинкам. хихикать над плохой шуткой, чем оставаться равнодушным.

Просто работайте! Н аучиться програм м ировать можно только одним способом: писать код. И м енно этим вам и предстоит заняться. Н е пропускайте упраж нения —обучение происходит в про­ цессе реш ения задач, даже таких необы чны х, как «П риклю чения нарисованного человеч­ ка», поиск мест в ки н отеатре для настояш;их мачо или заполнение блога YouCube. Н е переходите к следуюш;им страницам, не закончив упражнений. И, если вам доведет­ ся п оработать над реальны м проектом , не забы вайте использовать приемы , описанны е в книге. дальше >

29


как работать с этой книгой

Примите к сведению Это учебник, а не справочник. Мы нам еренно убрали из книги все, что могло бы помеш ать изучению материала, над которы м вы работаете. И при первом ч тен ии книги начинать следует с самого начала, потому что книга предполага­ ет наличие у читателя определенны х знаний и опыта.

Мы даем сведения, которые вам действительно требуются. Если вы по другим источникам изучаете историю разви тия JavaScript, продол­ ж айте это делать, так как данная книга вам не поможет. О н а призвана научить вас реш ать практические, каждодневные задачи по созданию интерактивны х веб-страниц, с которы м и пользователям будет п риятно работать. Мы п ере­ ш агиваем через ф ормализм и рассматриваем только те п онятия из JavaScript, которы е действительно потребую тся вам для работы .

Здесь не рассматриваются все нюансы языка JavaScгipt. Разумеется, можно было бы описать все оп ераторы , собы тия, объекты и клю­ чевы е слова JavaScript, но было реш ено ограничиться более компактным изданием, которое удобно иметь под рукой. П оэтому основной упор дается на концепции, которы е используются программистами в 95 % случаев. Ч тобы в результате вы получили способность самостоятельно писать сложны е сцена­ рии. Суш;ествует больш ая библиотека уже готовых ф рагм ентов кoдaJavaScript, и поэтому крайне важно понимать, когда следует писать собственны й вариант функции или метода, а когда можно ограничиться стандартным. Слово «спе­ циальный» в этой книге означает, что код долж ен быть написан вами лично, а не взят из библиотеки JavaScript.

В процессе чтения желательно пользоваться разными браузерами. Н есм отря на то т факт, что все соврем енны е браузеры поддерж иваю т JavaScript, имею тся небольш ие различия в процедуре обработки кода сце­ нариев. И м енно поэтому ж елательно п роверять результаты своей работы по крайней мере в двух браузерах. И звестно, что лучше всех с обработкам и ош ибок справляется Firefox. Н о не стесняйтесь п опросить друзей и знакомых п ротести ровать ваши сценарии и в их браузерах также.

30

введение


введение

Упражнения обязательны. У праж нения являю тся частью основного материала книги. О дни упражне­ ния способствую т запоминанию материала, другие помогаю т лучше понять его, тр етьи ориен тирован ы на его п рактическое прим енение. Не пропу­

скайте упражнения. Повторения применяются намеренно. У книг этой серии есть одна принципиальная особенность: мы хотим, что­ бы вы действительно xojbomoусвоили материал. И чтобы вы запомнили все, что узнали. Больш инство справочников не ставит своей целью успеш ное запоминание, но это не справочник, а учебник, поэтому н екоторы е концеп­ ции излагаю тся в книге по нескольку раз.

Примеры кода были сделаны по возможности компактными. Наш и читатели не лю бят п росм атривать по 200 строк кода, чтобы найти две нужные строки. Больш инство прим еров книги приводится в минималь­ ном контексте, чтобы та часть, которую вы непосредственно изучаете, была п онятной и простой. Н е ждите, что весь код будет стопроцентно устойчивы м или даже просто заверш енны м —прим еры написаны в учебных целях и не всегда являю тся полнофункциональными. Все варианты кода из наш ей книги помещ ены в И н терн ет, чтобы дать вам возмож ность скопировать их к себе и исследовать. Скачать их мож но по адресу http: //w w w . headfirstlabs. сот/books/hfjs/

Упражнения «Мозговой штурм» не имеют ответов. Б некоторы х из них правильного ответа вообщ е нет, в других вы должны сами реш ить, насколько правильны ваши ответы (это является частью п ро­ цесса обучения). В некоторы х упраж нениях «М озговой штурм» приводятся подсказки, которы е помогут вам найти нужное направление.

дальше *

31


обзор команды

Технические редакторы Ты Ви Сканнел

Ф летчер М ур

Алекс Л и —студент Хью­ стонского университета, специализирую щ ийся на автом атизированны х систе­ мах управления. О бож ает бег, ком пью терны е игры и изуче­ н ие новы х язы ков програм ­ мирования,

К ат ерина С ент -Дж он

Элейн Нельсон

Стивен Т аллент

Захарий Кессии

А лекс Ли

тм Холденер III

Ти Ви Сканнел и з города С истерс, ш тат О регон, за­ ним ается програм м ировани­ ем с 1995 года. Разработчик каркаса Ruby on Rails. Элейн Н ельсон заним ается разработкой веб-сайтов около 10 лет. Как она говори т своей м атери, ученая сте­ пень в английском язы ке много где мож ет пригодиться. У знать о текущ их увлечениях Э лейн вы мож ете на ее сайте — elainenelson.org. Ф летчер Мур является веб-разработчиком и дизайнером в институте G eorgia Tech. Увлекается велоспортом , музыкой, садоводством и является ф анатом бейсбольной команды R ed Sox. П рож и вает в А тланте с ж еной К атариной, дочерью С эйлор и сыном Сэтчелом. Энтони Ти Х олденер III является разработчиком веб-прилож ений и автором книги Ajax: T h e Definitive G uide, такж е выш едш ей в издательстве O ’Reilly. Захарий К есси н заним ается веб-програм мированием около 15 лет. П рож и вает в И зраи ле с ж еной и трем я детьми. Катерина Сент-Джон —доцен т каф едры и н ф орм ати ки и математики в университете города Н ью -Й орк, зан и ­ мается исследованием в области вы числительной биологии и случайных структур. Стивен Таллент ж ивет и работает в городе Н эш вилле ш тата Т еннеси, разрабаты вая спортивны е прилож ения и воспиты вая м аленьких детей. К ром е того, он увлекается катанием н а роликовой доске и кулинарией. И даже готовится сделать вторую карьеру в качестве повара в буфете.

32

введение


введение

Благодарности Моему редактору; П омните, в начальной школе нам предоставляли возмож ность п ерепи­ сы ваться с детьми из других городов, обмениваясь инф орм ац ией о своей жизни? И м енно таким другом по переписке стала для меня Катрин Но­ лан с момента начала этого проекта. Мы общ ались по телефону, элек­ тр о н н о й почте, факсу. В процессе этого общ ения К атрин стала больше чем коллегой по работе над изданием. О н а стала моим другом. И часто «деловые» звонки заканчивались переходом от разговоров п ро JavaScript к обсуждению других наших увлечений. Мы оба получили удовольствие от работы и от ее конечного результата. Спасибо, К атрин. Я помню, что задолжал тебе несколько мартини.

Команда издательства O’Reilly:

К ат рин Нолан, покло н­ ница десятичной с и с т е ­ мы счисления.

Сложно подобрать слова для команды H ead First. Н о я попробую.

Бретт МакЛафлин с момента моего появления в лагере ново­ бранцев H ead First заставил меня сконцентрироваться. Этот парень одинаково серьезно относится как к необходимости Б р ет т М акЛаф лин анализа сценариев в процессе обучения, так и к игре на гитаре. команды Heat Я уверен, что даже ко сну он отходит, предварительно задав себе поклонник вопрос; «Зачем я это делаю?» Н о именно его вклад помог создать такую выдающуюся книгу. Спасибо, Бретт! Лу Барр стала ещ е одним моим другом по переписке. Мне кажется, она спустилась к нам откуда-то с дизай­ нерского Олимпа. Б ез нее мы никогда не получили бы столь прекрасно сверстанной книги. Вряд ли процесс работы над книгой протекал бы столь гладко без Сандерса Кляйфелда. И м енно он нашел выход из многих слож ны х ситуаций. Я не забыл и об остальны х членах команды O ’Reilly.

Лари Петриски поверила в меня настолько, что­ бы запустить данны й проект, Кетрин МакКаллох -Лу Барр, богиня ди^ зайна.

обеспечила поддержку сайта (www.headfirstlabs.com), а Кейт МакНамара с удивительной точностью запол­ нила все пробелы. Спасибо, ребята! Ну и наконец, самой теплой благодарности заслу­ жили, наверное, Кетти Сьерра и Берт Байте за их потрясаю щ ее видение всех серий H ead First. Работа в этой команде была для меня счастьем...

дальше »

33


/

и н ш ер ак ш и Б н ая

сеш ь

+ Реакции виртуального мира %

Устали представлять Интернет набором пассивных стра­ ниц? Кто из нас не держал в руках книг. Их читаешь, в них находишь информацию. Но они не интерактивны. Как и интернет-страницы без JavaScript. Без сомнения, отправить данные формы и проделать другие трюки можно и при помощи кода HTML и CSS, но реальная интерактив­ ность требует более умного подхода и большей работы... зато и резуль­ тат впечатляет намного больше.


нужды пользователей

То, что ну)кно людям Мы знаем, что И н терн ет —это виртуальная реальность, но пользуются им вполне реальны е люди, с реальны м и нуждами. Им требую тся убойные рецепты мясного рулета, возмож ность скачать любимую песню или даже купить новы й дом. К счастью, когда дело доходит до ваш их нужд, сеть ведет себя по-разному!

©оо„

H ouse F inder

О

Ready to find a new house? Enter your annua} income; jSOOOO Enter the numtier of bedrooms; Enter your ZIP code;

Done

36

глава 1

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

ввод данных пользоват елем .


интерактивная сеть

и ничего... как будто говоришь со стенкой Сеть не всегда реагирует так, как вам хотелось бы. Б олее того, зачастую она каж ется соверш енно равнодуш ной, отдельной от внеш него м ира и никак не отвечаюш,ей нуждам м ногочисленны х пользователей. Вы ож идаете реакции на введенны е вами данные... но ничего не происходит. Н е приним айте это близко к сердцу, ста­ тический И н тер н ет по-другому просто не умеет.

П ользователь ввел данные.■■ но ничего не произошло. \

дальше >

37


интерактивность с Javascript

А JavaScript отвечает Я зы кJavaScript подобен выключателю, переводящ ему страницу в интерактивны й режим. О н активирует функции, которы е п ри ­ слушиваются к нуждам пользователей, обрабаты ваю т вводимые данны е и отвечаю т на запросы . Возможно, это некоторое преуве­ л ичение, но им енно JavaScript позволяет п реврати ть веб-страницу в и нтеракти вное прилож ение, вдохнув в нее жизнь!

0ОО

Щ е л к й е т на кнопке для получения результ ат а.

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

глава 1


интерактивная сеть

Please enter a number.

f

OK - " ?

codT Z iZ r

e o e

H ouse Finder - Matches_

T he following h o u s e s w ere found: Поиск ииф орМ йцыы на сервере осущ ест вляет ся в соответствии^^ с заданными парам ет рам и.

110 Etm Street View

1

400 Map!© Lane

View {

847 Main Street

View

Done

Vou can affo rd a house that costs up , 0 , 3 2 0 0 0 0 .

Расчет произведен, исходя из введен­ ных пользоват елем данных. ^

дальше *

39


HTML, CSS и JavaScript B s a u iM v o

C6em, камера,

^ действие!

HTM L, CSS и JavaScript —это три ки та соврем енного конструирования веб-страниц. HTM L обеспечи­ вает структуру, CSS добавляет стиль, а JavaScript обеспечивает «сцепление с дорогой». Ч тобы п рой ­ ти путь к интерактивны м веб-страницам, вы долж ны следовать от структуры (HTML) в стиле (CSS) к действию (JavaScript). Как и в CSS, в JavaScript код часто находится непосредственно внутри веб­ страницы.

<html>

СТРУКТУРА

<head> </head> <body> ^‘^idii'*idi"heIdsr">Ready to find a new house?</dlv> <div id="left"> <img src-"house.png" alt-'House

/>

</div> <form name= <style type="text/css"> <div clas body { <input font:14px arial; </div> text-align:center; <div clas } <input </div> #frame { <div clas width:400px; <input } </div> <input tyi #header { <script type="text/javascript"> <input ty] font:l6px arial; function v a l i d a t e N u m b e r (value) { </form> font-weight:bold; // Validate the number </div> margin-bottom:15px / / i f (!isNumber (value)) </body> alertC'Please enter a number."); ) </html> #left { float: left; width:llOpx;

д ействие!

JavaScript

} e) { function v a l i d a t e Z I P C o d e (value) // Validate the ZIP code

} div.field { margin-bottom;lOpx text-align:right;

} </style>

function calcPriceO var maxPrice =

{

document.getE l e m e n t B y I d ( " i n c o m e ) .value

d4,

alert("You can afford a house that costs up to maxPrice +

7

function findHouses(form)

{

var bedrooms =

do c u m e n t . getElementById("bedrooms ) .value,

HTML дает нам каркас.

var zipCode = document.getElementByld("zip") .value; // Display a list of matching houses from the server

form.submitO ; || </script>

r

CSS добавляет в и ­ зуальный ст иль.

40

глава 1

JavaScript добавляет ^ФУ^Щ иоиальность, fпозволяя ст ранице ^вы полнят ь различные 1о'ействия.


интерактивная сеть

О

House finder

@ 0в

Rgfirfy tn flndanew bouse?

Enter your annual income: | EnKsr fte numbo-of E m s your ZIP wS--*-----— Done

__ _

Все компонент ы ст раницы Нй м ест е, но они не о т ­ ф орм ат ированы и не очень красиво выглядят...

House Finder

Ready to find a new house? Enter your annual Income: jioooo

О

Эта стрлнии,й выглядит, намного м ц м г Т ^ она пока ничего н е д г т е £ л -

____У

Enter the number of tiedrooms: Enter your ZIP code: [95014

c >

Calculate Wee 1 Shop for H q u ^

Done

А вот т еперь вы мож ете получит ь от вет !

You c m afford а h ouse th aï co sts up to 5320000.

а

к

э

Спасибо, JavaScгipt! Я вот-вот найду холостяцкую берлогу, о которой давно мечтал.

JavaScripl начинает работу, как только пользователь просит страницу выполнить какую-либо задачу. дальше *

41


зачем нужен JavaScript?

А разве все то же самое нельзя сделать средствами HTML и CSS? Интернет прекрасно работал и до появления JavaScript.

HTML u CSS недостаточно интерактивны П роблема именно в недостаточной интерактивности HTM L и CSS. В CSS существует набор приемов, позволяю щ их управ­ лять стилями в специф ических ситуациях, наприм ер при на­ ведении указателя мыши на ссылки, но ваши возмож ности все равно крайне ограничены . Благодаря JavaScript вы зам ечаете все происходящ ее на стра­ нице, наприм ер щ елчки пользователя на кнопках, изменение разм еров окна обозревателя или ввод данны х в текстовое поле. А так как JavaScript —это язы к написания сценариев, вы можете написать код, отвечаю щ ий на действия пользователя, н апри­ мер, вы полнением вы числений, динам ической зам еной изобра­ ж ения или п роверкой данных.

ГАССЛА 1) 1>Т1 С1)

Не беспокойтесь о дета­ лях.

JavaScript позволяет очень многое, но вы пока в самом начале знакомства с этим языком. Смею вас заверить, что собы тия, функции и многие другие элементы JavaScript со временем станут для вас понятны ми. К роме того, есть вероятность, что вы уже знаете намного больше, чем вам кажется.

HTML + CSS + JavaScript = РЕАЛЬНАЯ интерактивность 42

глава 1


интерактивная сеть

Возьми В руку карандаш Вы уже знаете больше, чем вам кажется. Посмотрите на код для страницы House Finder и напишите, что делает каждый из выделенных фрагментов кода. Не бойтесь строить догадки.

<html> <head> <title>noMCK f l O M O B < / t i t l e > <script type="text/javascript"> function validateNumber(value)

{

// Проверка ввода числа // if (!isNumber(value)) a l e r t ("Пожалуйста, введите число.");

} / J ^ t i o n validateZIPCode (value)

I

{

// Проверка ввода индекса // if (iisZIPCode(value)) a l e r t ("Пожалуйста, введите индекс в формате Х Х Х Х ^

ler' t:'("tibi' м о ж е т е ^ озвоТить дом стоимостью до $

function findHouses (form) { ^ „„.м valuevar bedrooms = d o c u m e n t .g e t E l e m e n t B y l d ( bedroom ). var zipCode = document.g e t E l e m e n t B y I d ( " z i p " ) .value, // Отображение списка подходящих домов с сервера f o r m.submit();

} </script> </head> <body> <div id="frame"> <div id="header">r0T0Bbi к поиску нового д о т <div id="left"> <img src="house.png" alt="House" />. < f o m name="orderform" a c t i o n = " . . ^ e t h o d = " P O S T " > <div class="field">Укaжитe ва 1^ г о д о в о и доход: size^l2 <S^biur="validateNumber(this.value)"7^</div> <di7Tlass="iield" >Б55дитЪ~^^^гаю^Н5лен: <input id="bedrooms" type="text" size-"6'^ onblur="validateNumber(this.value) " / > < / d ± v > <div olass="field">BBeflHTe индекс: <input id="zip" type="texj:L.ai^e;:;^ /></div> onblur="validateZIPCode W j i ^ a l u e цену" <input type="button" уа1ие="ВычИСТО1 oncliclc="calcPrice() /> ^innnt f.vpe="button" у а 1 и е = " К у п и т ^ , « H ^ Tcl?^itodHouses (this .f o r m ) 7 > / </fOrifL5 </div> </body> </html>

дальше *

43


решение упражнения

Возьми Вруку карандаш Решение

Вот какую функцию выполняют выделенные фрагменты кода. Надеемся, ваши догадки совпали с правильными ответами.

<html> <head> < t i t l e > n o M C K flOMOB</title>

<script type="text/javascript"> function validateNumber(value) // Проверка ввода числа //if

{

(!i s N u m b e r ( v a l u e ) )

a l e r t ("Пожалуйста,

введите число.");

двести индекс в ф о р ­

}

м а т е ХХХХХ.

✓f^I^ction validateZIPCode (value) { ~ I I Проверка ввода индекса ( 11 if (IisZIPCode(value)) V a l e r t ("Пожалуйста, введите индекс в формате ХХХХХ.

f

Вьічисляет м аксим альную

1 —--------------—-------

цену дома, умножая доход пользоват еля на четыре.

");

function findHouses (form) { , var bedrooms = document.getElementByld("bedrooms ) .value, var zipCode = d o c u m e n t .g e t E l e m e n t B y l d ("zip").value.

// Отображение списка подходящих домов с сервера form.submit (); </script> </head>

I <Ьody> <div id="frame"> <dlv id="header">Гoтoвы к поиску нового д о м а ? < ^ 0 ^ <div id="left"> <1тд згс="Ьоизе.рпд" a l t = " H o u s e ' ' ^ ^

П роверяет, было ли введено число в поле income.

<£огт name="orderform" a c t j ^ p « ? < ^ method="POST"> <div class="field">Укaяa^*€ ваш годовой доход: тr^-<^■vnгnmp"^fype="text" з 1 ^ = " 1 2 "

<Г^lur="validateNumber (this.value^5/></dlv> <^1у class="ileld">Uвeдитe число спален: <iпput id="bedrooms" type="text" 31ге="6"

onblur="validateNumber(this.value)"/></div>

К ,., Значение в поле вво -

да ZIP co d e.

<div class="field">Bвeдитe индекс:

<input id="zip" type="teль::-.aiz^l0j^ onblur="validateZIPCode<tth^• уа1и^ ”/></dxv> < input tvpe="button" уа1ие="5ачистпТть цену"

OTiclick="calcPrice О ; ияТие="Купить дом" onclick="findHouses (this .form) ; />

гртпп у р ё - ' bULLun" >Гщ: </form> </div> </body> </html>

44

глава 1

^После щелчка на кнопке вычисляет м аксим альную т ну дома.


интерактивная сеть

Тег < script > П оместим ф рагм ент на язы ке JavaScript непосредственно в НТМЬ-код, как было показано на предыдущей странице. П ервы м делом вы долж ны дать по­ нять браузеру, что он будет иметь дело с JavaScript... и здесь вам на помощь п ридет тег < s c r i p t > . Этот тег добавляется в произвольное место НТМЬ-кода, но обы чно его по­ мещают внутрь заголовка. Вот таким образом:

<html> <head> <title>House Finder</title>

Э т от т ег говорит о т о м , чт о внут ри находится некий сце- . яяккоМ нарии

Тег script на HTML-

function validateNumber(value) { // Проверка ввода числа / / i f (!isNumber(value)) alert ("Please enter a number.'')

ст ранице

oSmmo по­ м ещ ает­

ся внут рь т ега head.

и

иа

JavaSc^nlpt.

<script type="teKt/javascript">

ф рагм ент между от кры ваю щ им и закры ваю щ им т егам и scrip t н а ­ писан на языке JavaScript... браузер поним ает , чт о эт о уже не HTML, а язык написания си,енариев.

}

</script>

бюацзерц, дальше опятс/ п <body> ет ся оШиный HTML-код. <!— Остальная часть HTML-кода — > </body> </html> Чаап°

---- <аДаБаеМые -

Б:

То есть все, что я помещу между тегами < s c r i p t > , будет относиться к JavaScript?

О

; Не обязательно... тег <script> говорит браузеру, что начинается сценарий, но он может быть и на другом языке. Язык сценария определяется вчасти type="text/javascript'

3

------------

Б о ц р * о с :ь 1

/ I То есть я могу использовать и другие языки сценариев?

Q;

Конечно. Microsoft предоставляет

вам VBScript (версия языка Visual Basic) и разновидность Ajax, которая называется ASP.NET AJAX. О последней мы поговорим в главе 12. Существуют и другие языки сценариев. Но в этой книге мы всегда будем использовать

javascript.

text/

Должны ли элементы < s c r i p t > располагаться внутри тегов < h e a d > ? расп

0.

Поместить теги < s c r i p t > можно

куда угодно... но их расположение вне заголовка считается дурным тоном. Это все равно что вставить в середину веб­ страницы стили CSS... фрагменты на JavaScript лучше выделять в отдельную группу, и для этого прекрасно подходит часть страницы, ограниченная тегами

<head>.

дальше *

45


команды браузеру

Ваш браузер понимает HTML, CSS U JavaScript Как вы знаете, браузеры умеют отображ ать HTM L-код. Н а язы ке CSS мы объясняем браузерам, как именно показы вать различны е части HTML. С оответственно, язы к JavaScript — это всего лиш ь ещ е один способ вашего общ ения с браузе­ ром... Н о на этот раз вы уже не указываете способ отобра­ ж ения, а подаете команды.

St" открываете, браузер и вводи т е URL... Г"

S e 6 - c e p 6ep определяет ,

кйкую стрлнмцу в а м показать.

Ш

®

в о е

браузер отобража&т H T M L - к о З в со о т ­ вет ст вии с правилам и С55... ^ ■

H0U5« FMer...

...

Веб-страница

Ready to find a new house?

Enter your annual Income; jsoooo Enter the number of bedrooms: |3 Enter your ZIPcode: |5ioi4

Ctone

__

Запц-

you can afford a house that costs up to $320000.

G ЯЖИ

46

глава 1

Сервер о т д а е ^ ¥ а у з е р у страны-* чу, полную т е HTML, правил


интерактивная сеть _

часщо

ЧаДаБаеМые Б о їїр о с ь і

Б

Каким образом браузеры запускают код иауа8сг1р1?

Насколько безопасно работать

с JavaScript?

0 » В браузеры встроено специальное программное обеспечение, называемое интерпретатором иауаЗспр!. Именно он запускает написанный на этом языке код. Именно поэтому иауаЗспр! называют инт ерпрет ируемы м языком программирования, в отличие от т ранслируемого. Транслируемые языки, например С++ или С#, необходимо сначала преобразовать в исполняемый файл при помощи компилятора. Программам на иауаЗспр1 этого не требуются, так как они интерпретируются непосредственно браузером.

О

атрибута

! По большей части безопасно. иауаЗспр! исходно разработан таким образом, чтобы затруднить выполнение вредоносного кода. К примеру, средствами JavaScript невозможно осуществлять чтение и запись файлов на жестком диске пользователя. Это ограничивает возможность применения большинства вирусов. Разумеется, можно написать вредоносный код и на иауаЗспр!. В прошлом, из-за конструктивных недостатков браузеров хакеры нашли ряд дыр в безопасности иауаЗсг1р1, так что назвать этот язык совершенно надежным, увы, не получится.

Как заставить веб-страницу запустить код иауаЗсг1р1?

Тег < s c r i p t > в программе House Finder относится к HTIVIL или

0 * В большинстве случаев такой код запускается после какого-то действия, например загрузки страницы или щелчка

к JavaScript?

пользователя на кнопке. Включение кода иауаЗсг1р1 после каких-то действий производится при помощи механизма, называемого «событием».

гіражнше • у г ір ажн

сценариев, вы указываете, на каком языке будет написан ваш сценарий, при помощи

0 ; Сам по себе тег <script> принадлежит HTML и предназначен для встройки сценариев в код веб-страниц. Внутри тега <script> вы видите код JavaScript. Так как сам тег разработан для поддержки нескольких языков написания

type.

Кажется, я встречал интерактивные страницы, к примеру, с формами, проверяющими корректность введенных данных, созданные без JavaScript. Такое возможно? Конечно. Сделать страницу интерактивной можно и без JavaScript, но в большинстве случаев такая реализация будет неэффективной и тяжеловесной. К примеру, проверка корректности введенных данных может быть осуществлена на сервере при отправке формы. При этом вы ждете ответа сервера в виде новой страницы. С таким же успехом для проверки можно воспользоваться карандашом и бумагой! JavaScript позволяет обойтись без загрузки новых страниц и ненужной передачи данных на сервер и обратно. А многие функции, реализуемые при помощи JavaScript, альтернативно могут быть реализованы только при помощи сторонних встроенных программ для браузеров.

Определите, является ли фрагмент кода стандартным выражением JavaScript или же это выражение введено программистами, которые написали страницу House Finder (вариант Custom):

alert

JavaScript / Custom

onblur

JavaScript I Custom

calcPrice

JavaScript I Custom

onclick

JavaScript I Custom

zipCode

JavaScript I Custom

findHouses

JavaScript I Custom

var

JavaScript I Custom

value

JavaScript I Custom

дальше

47


решение упражнения

п'ражнение

Итак, какие же куски кода являются стандартными выражениями язы­ ка иаУзЗспр!, а какие были введены программистами:

решение

Всплывающ ее окно, указывающее на некоррект ное число.

<head>

<title>noHCK flOMOB</title> <script type="text/javascript"> function validateNumber(value) // Проверка ввода числа / / i f (!isNumber(value)) alert("Пожалуйста, введите число. }

с— --- alert

П ользовательский кусок кода, вычисляющий ст оим ост ь

’);

дом с^

^

function validateZIPCode(value) { // Проверка ввода индекса // if (IisZIPCode(value)) , alert ("Пожалуйста, введите индекс в формате ХХХХХ.

)

_

^ c a lc P ric e

JavaScript

/(сйзБгтГ)

Задает внешнее м ест о хранения данных.

'p 'r a x p f i f e " i 'd o L L n t . g e t E l e m e n t B y I d ( " l n c o m ^ 4 . v a l u e * 4;

' f f 'alert("Вы '"

CjavaSc^/ Custom

C JavaScri^ Custom

можете позволить дом стоимостью до S

1

П ользовательский код поиска подходящих домов.

/

function findHouses (form) { valuevar bedrooms = document. getElementById( bedrooms^)-val var “ document.getElementByld( zip ). // Отображение списка подходящих домов

findHouses

JavaScript ( j^u s to n T )

Z ip C o d e

JavaScript (^CustoirT)

сервера

form.submitO ; </script> </head> <body> <div id="frame"> <div id="header">r0T0Bbi к поиску нового дoмa.</dlV <dlv id="left"> <img src="house.png" alt="House

М есто хранения введенного пользоват елем индекса.

/> _____________

опЫ иг <div claз«^field">Укaжитe ваш годовой <inpi^^d="income" type="text" size="12" onblu?="validateNumber(this. value)"/></div> <div class="field">BBeflHTe число спален: <input id="bedrooms" type="text" size-"6" onblur="validateNumber (this . v ^ e ) "/></div> <div class="field">Bвeдитe индек(^^;^^ id="zip" type-"text" s i z e = -n^ <lnput ia="ZipLYpeonblur="validateZIPCode (this.value) /></div> <input type="button" value="Bычиcлить цену" o n c l i c k = " c a l c P r i c e ( ) /> <input type="button" value="KynnTb дом" oncliclc="findHouses (this .form) ;" />

(^Ja va S crlp Q Custom

^У к а зы ва ет , чт о пользоват ель переш ел к следую щ ем у полю ввода. - v a ii^

( j a v a S c r l ^ Custom

Текущ ее значение поля ввода индекса. ■o n c ii^ c k

(JavaS cript)/ Custom

Указывает,, чт о была наж йм й кнопка „ К уп и т ь

48

глава 1


? I

I

интерактивная сеть

Помоги виртуальному другу человека С веж енаняты й успеш ный программист на HTM L и CSS вызван к начальству для дем онстрации последнего и зобретения, которое назы вается iRock. Виртуальный домаш ний лю бимец наделал шума на всех конф еренц и ях игрушек, но пользователи недовольны его поведением. О ни щ елкаю т на изображ ении и ждут чего-то необычного... Значит, вы долж ны сделать iRock интерактивным и прославиться... или кануть в небы тие вместе с ним. в в

Перед вами {Rock. Он сост оит из кода HTML LS!?' не взаи­ м одейст вует с п о льзо ­ ват елями.

Virtual t>et «оск О

.

При щелчке пользоват еля на элем ент е iRock ничего не происходит.

Разгневанные ‘п ользоват ели дет а-версии обрывают т елеф он тех. ‘поддержки.

Ш ТУРМ Что должен делать iRock, взаимо­ действуя с пользователями? Ты чувствуешь, как я щелкаю мышью?

дальше >

49


стратегия взаимодействия

Сделайте ^Rock интерактивным Вы не просто сделаете объект 1Яоск интерактивны м , но попутно познакомитесь с JavaScript. Вы бы стро научите вашего домаш него лю бимца здороваться. П еречислим список ваших задач.

О

© О

Создайте для 1Роск НТМи-страницу. Заставьте объект !Роск приветствовать пользователей при загрузке страницы.

Напишите код, запрашивающий имя пользователя для личного приветствия и заставляющий объект улыбаться. Добавьте обработчик события, запуска­ ющий написанный на шаге З^од в ответ на щелчок на объекте.

0

50

Вы уже знает е, как эт о сделать.

Заслужите одобрение и благодарность начальства.

у..пава 1

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


интерактивная сеть

Веб-страница iRock Более простую НТМ Ь-страницу, чем 1Коск, найти невозможно. Введите указанный ниж е код в ваш лю бимы й редактор и сохра­ ните его под именем iRock.htm l. Нужные и зображ ения скачай­ те с наш его сайта http://www.headfirstlabs.com.

<html> <head> <title>iRock - Виртуальный любимец Rock</title> </head> <body> <div style="margin-top:lOOpx; text-align:center"> <img id="rockImg" src="rock.png" alt="iRock" /> </div> </body> </html>

He

"7 за б ц д от е ск а ч а т ь

irock.html Часзцо

Тестирование П еред тем как двигаться дальше, сохраните и про­ тестируйте страницу 1Коск в браузере. Убедитесь, что результат выглядит именно так, как показано на рисунке, так как все уже ф актически готово, чтобы сделать его и нтерактивны м при помощи JavaScript.

____ з а д а в а е м ы е

_____

B o IIP o C b l

Б:

Внутри тега < d i v > находится CSS? Да. Вы угадали.

3 * Я думал, что не стоит помещать CSS непосредственно на HTML-страницу. Зачем это сделано? • Да, обычно лучше поместить CSS в тег <style> в заголовке страницы или на отдельную таблицу стилей. Но ваш начальник не очень хорошо в этом разбирается, а такая запись упрощает пример. Но если вы хотите написать собственную таблицу стилей для файла iRock, обязательно сделайте это.

дальше ►

51


знакомство с событиями

События Ч тобы заставить объект п риветствовать пользователя после загрузки страницы , нужно реш ить две задачи: определить м омент окончания загрузки и придумать способ отображ ения приветствия. Реш ение первой задачи связано с реакцией на собы тие (загрузку страницы ), а во втором случае вам потребуется встроенная функция «alert». Событиями {Events) в JavaScript назы ваю тся уведомления о про­ исходящем, наприм ер о загрузке страницы (onload) или о щ елчке на кнопке (onclick). В качестве ответа на подобные действия можно написать ваш собственны й код JavaScript.

.Rock-TheVinuaS

Событие onload срабат ы ва­ е т после окончания загрузки ст раницы iRock в браузере.

o n l o ‘a d !

Код для события onload задан в а т рибут е onload т ега <body>.

События являются уве­ домлениями, в ответ на которые защгскаетея код JavaScript.

М етод alertQ вызывает окно диалога с привет ст вием .

НеНо, Iam your petrock.

€E K 3 52

глава 1


интерактивная сеть

Оповещение пользователей JavaScript позволяет вы звать отдельное окно с инф орм ац ией для пользователей. Д ля этого вам потребуется написать код, вы зы ­ ваю щий метод alert {) и передаю щ ий ему отображ аемы й текст. Методами назы ваю тся ф рагм енты кода м ногократного использо­ вания, предназначенны е для реш ения общ их задач.

alert О

^ Е с л и сразу после ключевого слова Ja va5cript вы видите скобки,, скорее всего, эт о название /метода. ЦоДроёно Про

Мето°Ды

Указывает, чт о нужно щ елкнут ь на кнопке « К у п и т ь дом> a lert — эт о вст роен­ ный м ет од, от обра­ жающий всплывающее окно.

с х

Э т от т е кс т появит ся во всплывающелл окне. Не забудьте заклю чит ь его 6 кавычки.

Л. Текст

И нф орм ация, передаваемая . м ет одам J a v a S c n p t ■— в н а ^ илем случае эт о отображ ае­ мый т екст , — заклю чает ся в скобки.

А J

>нце п р ед лблче.ныя принят о ст авит ь т очку, т о каждую ст року кода ■^луаЗспрЬ заверш ает точка с запят ой.

С оединив все вместе, вы получите строку кода JavaScript. О на вы зы вает метод, отображ аю щ ий во всплывающем окне указанное вами приветствие: alert('Hello, I am your pet rock.');

Спокойно!

Методами называются фрагменты кода много­ кратного использования.

л Отображ аемый т екст заклю чает ся в кавычки.

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

дальше >

53


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

iRock приветствует вас Ч тобы поприветствовать пользователей после загрузки страницы iRock, вам потребую тся обработчик собы тия onload и метод alert ( ). Д обавьте следующую строчку на JavaScript в код irock.html:

<html> <head> ,ead> <title>iRock - The Virtual Pet Rock</title> </head> Хотя событие onload even t _ работ ает Зля всей ст р а н и ­ цы, вы задаете его в качестве ат рибут а т ега <body>, т ак как имен но эт а часть ст раницы вид­ на в браузере.

<body onload="alert('Hello, I am your pet rock. <div style="margin-top;lOOpx; text-align:center"> <img id="rockImg" src="rock.png" alt="iRock" </div> </body> </html>

П омнит е, чт о код на Ja va S crm t вст роен непосредственно в Ш уш ю т

’ _

irock.html

Проверка интерактивности Т еп ерь страница iRock стала более и нтерактивной благодаря окну с приветствием, появляющемуся в ответ на собы тие onload. Загрузи­ те в браузер страницу irock.html и посмотрите, что произойдет. iRocit - ТЬеViRual WRotli

_ Сразу же после за гр у з­ ки ст раницы появит ся дополнит ельное окно с <лриветствием.

Hello, i am your pet rock.

54

глава 1


интерактивная сеть Ч асто

'^адаБаеМые B o ilp o c jji

Существуют ли методы кроме

Откуда берутся события?

КЛЮ ЧЕВЫЕ МОМЕНТЫ

alert о ? а1<

О

! События, конечно, инициируются пользователем, но реализуются браузером. К примеру, при нажатии кнопки браузер должен распаковать информацию (какая именно кнопка была нажата) и передать ее методу, который отвечает

События отвечают на I Да, их множество. Метод alert () — это только верхушка айсберга. По мере вашего знакомства с JavaScript вы даже научитесь создавать свои собственные методы.

Событие onload про­ исходит в момент окон­ чания загрузки страницы.

Почему код события o n l o a d содержит кавычки и апострофы? соде

Вы отвечаете на со­ бытие onload, задав атрибут onload в теге

0:.

<body>.

за данное событие. А что будет, если не связать особ с событием никакого кода?

0:.

Если рядом с падающим деревом никого нет, производит ли оно шум? Вот также и с событиями. Если на событие нет ответа, браузер просто продолжает свою работу.

Б

Код JavaScript это то, что заключено между тегами <script>? ; Обычно да. Но этот код можно поместить и непосредственно в обработчик события, как вы видели на примере события onload. Именно так обычно и делают, когда требуется запустить всего одну строчку кода JavaScript как для объекта iRock.

происходящее на страни­ це кодом JavaScript.

! В HTML и JavaScript перед тем, как начать новое предложение, требуется закрыть предыдущее... если вы не используете другого разделителя. Поэтому, когда код JavaScript появляется внутри атрибута HTML (текст внутри другого текста), решить эту проблему можно совместным употреблением кавычек и апострофов. При этом не важно, что именно вы используете для атрибута или текста JavaScript, главное — быть последовательным. Приведем пример из обычного языка: «При щелчке iRock говорит „Hello there“». Именно по такому принципу должны располагаться кавычки

Методы связывают код JavaScript в модули многократного использо­ вания. Некоторым методам нужно передавать ин­ формацию. Метод alert О ото­ бражает окно с тексто­ вым сообщением.

и апострофы.

КТО и У кажите, что делает каждый ф рагм ент кoдaJavaScript.

o n lo a d 0 a le rt

П оказы вает текст во всплывающем окне. Заверш ает строчку кoдaJavaScript. У казы вает на окончание загрузки стра­ ницы. Включает информ ацию , передаваемую методу.

дальше >

55


добавим личного участия

КТ9 Вот, что делает каждый из указанных слева ф рагм ентов кода JavaScript.

П оказы вает текст во всплывающем окне. Заверш ает строчку кода JavaScript. У казы вает на окончание загрузки стра­ ницы. Включает информ ацию , передаваемую методу.

Сделаем объект ^Rock действительно интерактивным Вы уже сделали п ервы е шаги в сторону увеличения и нтерак­ тивности объекта 1Коск, но до момента, когда виртуального домаш него лю бимца можно будет представить пользователям, ещ е далеко... П ом ните наш список? Сделано!

©

- з а ™

О

Напишите код, запрашивающий имя пользователя для личного приветствия и заставляющий объект улыбаться. Добавьте обработчик события, запуска­ ющий написанный на шаге 3 код в ответ на щелчок на объекте. Заслужите одобрение и благодарность начальства.

56

глава 1

-- - И эту задачу мы


интерактивная сеть

ВзаимодейстВие доА}кно бы ть двусторонним в настоящ ий момент камеш ек говорит «Привет», но не позволяет поучаствовать в диалоге. А хочется, чтобы он отвечал пользователям. С небольш ой помощью JavaScript 1Коск можно п реврати ть в очарова­ тельного зверька, меняю щ его вы раж ение лица и приветствую щ его по­ сетителя страницы по имени...

После .щелчка объект должен спрашиват(у имя пользователя.

What is your name? Paul

(câncd

имеет привет ст воват ь пользователя по имени.

Теперь iRock

(Rock должен дем он­ ст рироват ь 3M0U,UUj улыбаясь Полтавателям.

il Is good to meet you, Pau*.

Пользователи

довольны.

JavaScript п озволяет пользователям взаимодействовать с объектом 1Коск, превращ ая наж атия клавиш и щ елчки мыши (дополнительны е собы тия) в удовольствие от общ ения хозяи н а с домаш ним любимцем. Так благодаря JavaScript рож дается дружба!

п ^ о з ь м и В руку карандаш Напишите, как, по вашему мнению, должно называться собы­ тие JavaScript, отвечающее на щелчок мыши.

дальше *

57


решение

^ В о з ь м и в руку карандаш Решение

Вот как должно называться событие JavaScript, отвечающее на щелчок мыши.

onclick Событие onclick возникает , когда п олт оват ель щ елкает на элемен т е ст раницы - при эт о м каждому элем ент у можно сопост авит ь сбои собственный уникальный код отое т а на эт о событие.

Как узнать имя пользователя Вот готовы й к работе метод JavaScrip. И м енно такие куски кода вы будете находить под данным значком. Со временем вы изучите все его детали и сможете писать свой собственны й код.

]"о щ о Б ь 1й К од JaV a^cT ^t

В данном случае перед нами пользовательский метод touchR ock; (), которы й сначала предлагает пользователю указать свое имя, а затем вы зы вает отдельное окно с п ерсониф ицированны м приветствием. О дноврем енно стандартное изображ ение объекта 1Коск зам еняется улыбающимся. М ет од p ro m p t() вызывает Все методы исмаЗспрЬ всплывающ ее окно, в к о т о и м ею т свои имена. Э т от рое пользоват елю предлага мет од называется touchRock. ет ся ввест и некую инфор ^ мацию. С function touchRockO { var userName = prompt("Как вас зовут?", "Введите ваше имя.");

— Теперь, когда мы знаем if (userName) { ^ можно попривет ст воват ь alert("Рад вас видеть, " + userName + ". ) f пользователя... document.getElementByld("rocklmg") .src = " r o ck_happy.png"; }

' t i __ м зам енит ь обьш ое изображение камеш ка улы баю щ им ся.

Ш ТУРМ в какое место кода страницы irock.html нужно поместить этот метод?

58

глава 1


интерактивная сеть

Магниты с кодом JavaScript Код 1Воск лишился некоторых фрагментов. Можете ли вы его восстановить?

Подсказка: проверит ь п р а ­ вильност ь своих от вет ов можно м ет одом их ввода в код ст раницы 1госкМт1.

/ <html> <head> <title>iRock - The Virtual Pet Rock</title> <

type="text/javascript"> function touchRockO { var userName = promptC'KaK вас зовут?", "Введите ваше имя."); if (userName) { alert ("Рад вас видеть, " + userName + "."); document.getElementByld("rocklmg").src = "rock_happy.png";

} } </script> </head> <body ....... =" .........( ................................ ) ;"> <div style="margin-top:lOOpx; text-align:center"> <img id="rockImg" src="rock.png" alt="iRock" style="cursor:pointer"

............... = " .............................; " /> </div> </body> </html>

touchRock 0

alert

script onclick 'Hello. I am your pet rock. '

дальше *

59


решение задачи с магнитами

Решение задачи с магнитами Вот как выглядит целый код.

Методы иауаЗспрЬ р а с ­ полагаю т ся внут ри т ега <scnpt>, накодяш,егося в з а ­ головке ст раница.

А т р и б у т ty p e т ега <script> задает язык, на кот ором будет написан сценарий. В на ш ем случае эт о JavaScript.

J _________________ <html> <head> <title^Rock - The V i s u a l Pet Rock</title> script I type="text/javascript"> ■TEmumTjn touchRockO { var userName = prompt("Как вас зовут?", "Введите ваше имя.");

if (userName) { alert("Рад вас видеть, " + userName + "."); document.getElementByld("rocklmg").src = "rock happy.png";

} } </script> </hpsd>

^ А т р и б у т события onload ^ <hody> привязы вает к ст ранице всплывающ ее окно ^ привет ст вием .

' З а грузит е изображение улыбающегося камеилка.

<body onload к=" alert |( < d i7 * f¥ f!ie * « fc a rg fie re p fl <img id="ropkIma" src="rock.pna" alt="iRock" style="cursor:pointer" onclick^"

" />

</body> </html> А т р и б у т onclick изображе ния объект а вызывает м ет од touchRockO при ще'лчке на объекте.

60

глава 1

Наведенный на камеш ек курсор должен приним ат ь ф орм у руки.


интерактивная сеть

Полученный результат Н ебольш ой код JavaScript вы звал м нож ество изм енений, сделав наш объект 1Коск нам ного более интересн ы м . Д авай те посм отрим , как теп ерь вы глядит наш а страни ц а.

Щ елчок на изображении iRock вы зы ваем заданный пользоват елем метод.

id="rockImg" src="rock.png" alt-"iRock" ______ onclick="touchRook(); S t y l e = " cursor-.pointer

/>

mm

function touchRockO { var userName = promptC'KaK в а с з о в у т ? " , "Введите ваше имя."); if (userName) { alert("Рад вас видеть, " + userName + "."); document.getElementById("rockImg").src = "rock happy.png";

} ^т т ^щ т ш т ш т т т ш я т К ам еш ек (i начинает улыбаться..

М ет од спраш ивает , как зобут пользоват еля, а зат ем п р и ве т ст вуе т его по имени. What is your name? It is good to meet you, Paul Paul

( C a n c ^ ) f~ O K дальше

61


IRock заработал!

Проверка прило)кения iRock 1.0 Убедитесь, в том что ваша версия страницы i r o c k . h t m l со­ впадает с показанной на странице 62 и что вы загрузили с сайта H ead First Labs {http://www.headfirstlabs.com/books/hfjs/) оба необ­ ходимых вам изображ ения. Теперь открой те вашу веб-страницу, и пусть камеш ек вертится: :

Сделано!

О

-€оздайте-для4Явек44ТШ г«=1=раницуг-

©

•■3 a c T a B t ï R ^ -

е

О

(Rock - The Virtual Pet Rode

вО 0

0

é b Æ

ia

4

R < №

lt

4

i f w

e

^

------------

пользователей при зарруэке-етрс№тцы.

~14атт1ш тгетю 0дгзапрж ш т^^

-пользователя для личного приветствия и заставляющий i 3-

ющий написанный на

в ответ

выполнена.

■ Здесь мы вое 'пользовались М ет одом io u c h R o c k ().

реш ения эт ой задат нам т ия onclick.

Заслужите одобрение и благодарность начальства. 62

глава 1

Начальник доволен... Может быть, он вы ­ делит нам большой м онит ор?

JavaScript по зволяет веб­ страницам действовать, а не просто отображать содержимое.


интерактивная сеть

В к л а д к а Согните страницу по вертикали, чтобы совместить два мозга и решить задачу. ^

Что добавляет JavaScript? ■-------- \ и xojJoiiio, а ДБа лучше!

^ ----

ЭТО х о л о д н ы й

камешек...

.а это теплый.

Теперь объект (■Rock м м е е т коечт о общее с ЭИЛМ" MU н е ви р т у а ль­ ными животными. Что именно?

Поиск ответов в Интернете, скорее всего, не принесет вам особой пользы. Лучше вместо этого провести время с пользователями.


■анение Данных

Все на своем месте ^

в реальном мире люди часто не придают значения местам для хранения своего имущества, в иауаЗспр! такое поведение не­ возможно. Ведь там не существует роскоши в виде огромных шкафов и га­ ражей на три машины. В иауаЗспр1 все имеет свое место, и ваша задача в этом убедиться. Мы поговорим о данных — как их представить, как хра­ нить их и как их найти после сохранения. Вы научитесь превращать за­ хламленые комнаты с данными в аккуратные помещения с ящиками, каждый из которых имеет пометку


сценарии сохранения данных

Сохранение данных П рактически каждый сценарий им еет дело с данны ми в той или иной ипостаси. О бы чно это подразумевает сохранение данны х в памяти. З а выбор места для хран ен и я отвечает и н тер ­ п ретатор JavaScript. Вам же нужно объяснить ему, что это за данные и как вы собираетесь их использовать. House f m«l«r _

в в в.

О

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

R eady to find a new h o u se ? Enter your annual income: jioooo Enter the num ber o f bedroom s; |3 Enter your Z ip code: p i o i 4 CaicuUte Price 1 Shop te r H ouses..

Н а основе сохраненны х данны х сценарии вы полняю т вы числения и помнят инф орм ацию о пользователе. Без возмож ности сохранения данны х вы никогда не наш ли бы новы й дом и не познакомились бы с объектом 1Коск.

Ш ТУРМ Подумайте о той информации, с которой при­ ходится иметь дело ежедневно. На что она похожа? Как различается? Каким образом вы бы ее систематизировали?

66

глава 2


хранение данных

Типы данных Д анны е из реального м ира мы категоризируем и систематизируем, даже не задумываясь над этим: имена, числа, звуки и т. п. JavaScript такж е разделяет данны е на типы. И м енно это является ключом п ри передаче инф орм ации из вашего мозга в JavaScript.

JavaScript

Мозг человека $19.95

^

number

Включить свет.

boolean

Отвези меня на стадион.

text

В JavaScript три основных типа данных: text, number и boolean. Number Ц и ф р ы используются для хран е­ н и я числовы х данных, наприм ер

массы или количества предметов. В T a v a S c rip t они могут бы ть как ц ^ ы м и (2 кг), так и десятичны м и (2.5 кг).

Текстовы е данны е используют­ ся для хран ен и я набора симво­ лов, наприм ер названия вашего лю бимого завтрака. М ожно не ограничиваться словами и пред­ лож ениями. Текст в ;ау а 8 с п р 1 всегда заклю чается в кавы чки (" ') или в ап остроф ы ('').

Boolean Л огические данны е имею т два значения true и false. П оэтому с их помош;ью представляю т­ ся п роцессы и объекты, имею щ ие два состояния, наприм ер; тостер мож ет быть вклю чен или выклю ­ чен. П одробно об этом типе данны х мы погово­ ри м в главе 4 .

Тип данны х определяет способ его обработки кодом JavaScript. Н априм ер, всплываю щ ие окна отображ аю т только текст. П оэтому числа перед отображ ением следует преобразовать в текстовы й формат. дальше >•

67


упражнение

Возьми в руку карандаш Найдите информацию, которая может быть представлена данными JavaScript, и укажите, к какому типу она должна относиться.

З с 1 п с а п 5 D G n lllts 1‘ж л , :

О 68

глава 2


хранение данных

дальше >

69


решение упражнения

Возьми В руку карандаш \

Решение

Вот к каким типам относились бы данные с картинки в сценарии JavaScript.

Text

Object (о них мы поговорим в главе 9). /

i

4

О опа B o o lean

1202 Ы итЬ Ш

-

г»

is-.

.й.

70

’ fi ^ ^

глава 2


хранение данных

дальше ^

71


постоянное и изменяемое

Константы и переменные С охраняя данны е в JavaScript, нужно помнить не только про их тип, но и про назначение. Будут ли данны е меняться в процессе вы полнения сценария? О т ответа на этот вопрос зависит, константами вы будете пользоваться или ж е п ере­ менными.

Константа Площадь ст раны с о ­ ст авляет ъ .5 миллиона квадрат ных м и л ь — это конст ант а, если, конечно, не сдвинут ся т ект о ни ч е­ ские плит ы .

В сут ках 2-4 часа. Это конст ант а, известная всем людям.

и я и веб-ст раницы w w w .duncansdonuts.com эт о конст ант а, по кр а й ­ ней м ере до т ех тор, пока бизнес не пр и дет в упадок.

Ш ТУРМ Какие еще типы информации работают как с переменными, так и с константами?

72

глава 2

Переменные ме­ няют свое значе­ ние, в то время как константы фиксированы. Переменная Население в 3 0 0 м иллионов человек — ' перем енная, т ак как население СШ А во з­ раст ает .

Восход солнца в 6 :4 3 — э т о переменная, т ак как врем я восхода солн­ ца м еняет ся каждый день.

32-4 посещения — п е ­ рем енная, т ак как пользоват ели п р о ­ должают заходит ь на ст раницу и м енят ь показания счетчика.


хранение данных

Возьми в руку карандаш Обведите все данные, связанные с кондитерской Дункана, и укажите, к переменным или к константам они относятся.

Э а п с а п з D o n (J ts 'ж л .

1202

дальше у

73


решение упражнения 11^ з ь м и

В

руку карандаш Решение

Вам нужно было определить, какие данные относятся к пере­ менным, а какие к константам.

-КонстантаПеремен ная

опсапз Константа

Переменная

^Переменная

74

глава 2


хранение данных

Беседа у камина Переменные и константы обсуждают аспекты хранения данных.

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

Разумеется, но твое упорное неж елание ме­ няться ставит в тупик в ситуациях с изм еня­ ющ имися данными. Н априм ер, при запуске ракеты нужно произвести отсчет от 10 до 1. И что ты будешь делать?

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

Константа:

А я называю это нереш ительностью ! Я гово­ рю, что значения нужно вы бирать раз и на­ всегда. И именно моя последовательность делает меня столь ценной... П рограм мисты ценят мою предсказуемость.

И вот поэтому ты считаеш ь себя един­ ственным вариантом хран ен и я данны х для важ ны х прилож ений? Угадай, почему ракета оказалась на стартовой площадке. Лиш ь потому, что парам етры запуска являю тся константами. Ты когда-нибудь видела п ере­ менны й срок окончания проекта?

Ч ем больше вещ и меняю тся, тем более неиз­ менны ми они остаются. Почему изм енения нужно ставить на первое место? П рисвой изначально нужное значение и не трогай его больше. Это ж е так удобно, когда парам етр не мож ет бы ть случайно изменен.

я думаю, тут можно только соглашаться. И ли не соглашаться. И м енно так. И я с тобой полностью несо­ гласна. дальше р

75


создание переменной

исходное состояние переменных П ерем енной назы вается место хранения и нф орм ац ии в памяти, имею щ ее уникальное имя. Это как метка на коробке для хранения вещей. Д ля создания п ерем енной прим еняется клю чевое слово v a r , после которого следует ее имя. Ключевыми назы ваю тся слова, заре­ зервированны е в JavaScript для вы полнения различны х операций. К лю чевое слово var указы вает на создание новой переменной.

Имя

Б конце каждой ст роки кода Ja va S crip t ст авит ся точка с запят ой.

переменной

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

С озданная при помощ и клю чевого слова v a r перем енная из­ начально пуста —она не им еет никакого значения. П оэтому не им еет смысла пользоваться перем енной до операции п ри ­ своения. Вы.же не вклю чаете М РЗ-проигрыватель, не вставив в него диск.

Д а , эт о новая <леременная.

^о н е ц v a r p a g e H its ;

^•^роки.

Ящмк п у с т — сюда можно полож ить информацию.

Ее им я радеИНв — к о ­ личест во посеш,ений страницы. Вновь созданная перем енная резервирует пространство для хран ен и я и нф орм ации и готова к присвоению ей значений. В ы бранное для нее имя играет немаловажную роль. О но долж­ но быть уникальным и значимым. К примеру, имя p a g e H i ts сразу дает понять, что за и нф орм ац ия содерж ится внутри. Если бы перем енной для подсчета количества посещ ений страни­ цы было присвоено имя X или д егк ± п , вы бы уже не смогли с п ервого взгляда определить, для чего она предназначена.

76

глава 2

■ч


хранение данных

Присвоение значений Н е следует создавать переменную , не имеющую значения. Бо­ лее того, имеет смысл присваивать зн ачение перем енной уже в момент создания. Эта процедура назы вается инициализаци­ ей. Д ля ее вы полнения достаточно добавить небольш ой кусо­ чек кода в уже знакомую вам строчку:

Имя

Заверш ает с т р о ч к у кода.

ш

Значение

перем енной

З н а к р а в е н с т в а соединяет и м я п е р е м е н н о й с ее н а ч а л ь ­ н ы м значением .

И м енно эт о значение б у ­ де т х р а н и т ь с я в пе р е м е н н о й .

В отли чи е от своего пустого дубликата, и ни циализирован­ ная п ерем енная немедленно готова к использованию ... П о­ скольку она уже им еет значение. Вы как будто купили МРЗпроигры ватель со вставленным внутрь диском —и сразу мож ете слушать музыку.

П р и сво й т е значение »переменной. Конец.

Теперь переменная с о д е р ж и т численны е

данные. va r

p o p u la t io n

=

300; ^

/К С оздайт е п е р е м е н н у ю .

П р и сво й т е ей и м я.

У каж ит е ее значение.

П ом ните о типах данных? П оказанная выше строчка кода автом атически н азначает перем енной ти п данных. В данном случае JavaScript создает переменную p o p u l a t i o n число­ вого типа, потому что вы присваиваете ей значение 300. П осле присвоени я другого зн ачен ия ти п перем енной может измениться. В больш инстве cлyчaeвJavaScript делает это автоматически, хотя бываю т случаи, когда переход от одно­ го ти п а к другому следует вы полнять вручную. Н о о них мы поговорим позже. дальше *

77


упрямые константы

Не все браузеры поддерживают Ьдыпе I ключевое слово 0СШ0|=0ЖНьі! const.

Константы в процессе инициализации перем енной присваивается начальное значение, но ничто не меш ает его п о з ж е поме­ нять. А вот для хран ен и я данных, которы е никогда не будут меняться, вам потребуется константа. К онстанты создаются аналогично инициализированны м перем енны м, но вместо клю чевого слова v a r используется клю чевое слово c o n s t . И «начальное» зн ачение становится постоянным! Э т о клю чевое слово

Присвоение

создает конст ант у.

значения к о н ­ ст ант е.

Ключевое слово c o n s t — новинка для JavaScript, и не все браузеры его понимают. Поэтому тщательно про­ веряйте те браузеры, для которых пишется код, содер­ жащий константы.

/ const 1 4- \

і

Имя константы

Значение

Значение к о н с т а н т ы никогда не и зм е н и т ся .

Имя константы.

П роцесс создания константы отличается только используемым клю чевым словом. О стальной синтаксис остается таким же, как при инициализации перем енной. Ч тобы выделить константы , им часто присваиваю т имена, написанны е больш ими буквами. Э т о значение

Эти данные не и з м е ­ н я т с я никогда! const

конст ант а будет и м е т ь вечно. TAXRATE

=

.9 2 5 ;

/

Т О Л Ь К О П Р О П И С Н Ы Е буквы о и м е н и к о н с т а н т ы о б ле гча ю т ее

от личие от переменных, в именах к о т о р ы х возможны буквы р а зн ы х регист ров. К онстанты позволяю т хранить информ ацию , кодируемую прямо в сценарии, скажем, ставку налога с продаж. Вместо числа 0 .9 2 5 им еет смысл вставить в код константу со значим ы м именем, на­ п рим ер ТАХКАТЕ. П ри таком подходе, если впоследствии вам потребуется пом енять зн ачение константы , достаточно будет сделать это один раз —в месте ее инициализации. Это намного прош,е, чем искать и зам енять числа по всему сценарию .

78

глава 2

О перация закончена.


хранение данных

А я думала, что константы не могут менять своих значений.

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

ненке

Как вы думаете, переменной или константой должно быть каждое из указанных ниже значений? При желании вы можете написать код для создания и инициализации каждо­ го из них.

Температура воздуха в данный момент. Начальное значение неизвестно. Коэффициент преобразования возраста собаки в возраст человека (1 год че­ ловека = 7 годам собаки). Обратный отсчет перед запуском ракеты (от 10 до 0).

Цена вкусного пирожка (50 центов).

дальше >

79


решение упражнения

^

ш нпг

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

решение Температура воздуха в данный момент. Начальное значение неизвестно. Коэффициент преобразования возраста собаки в возраст человека (1 год человека = 7 годам собаки). Обратный отсчет перед запуском ракеты (от 10 до 0).

Цена вкусного пирожка (50 центов).

var tem p; Т ем перат ура все врем я меняет ся, а ее исходное значение неизвест но, поэт ом у для нее мы резервируем п ус т ую переменную .

const HUMANTODOQ = 7;

1

К оэффс^циент преобразования м еняет ся, поэт ом у для него превосходно подойдет ко н ст ант а.

var countdow n - Ю ; Обратный от счет меняет ся от ХО до X, ' поэт ом у нам нужна переменная с начальным значением i-O. var donutPrice = О.SO; или const PONUTPRICE = О.SO;

цену на пирожки нужно предст авит ь п е р е ­ менной с указанны м в задаче начальным значением

80

глава 2

Если же цена фиксированная, .лучш е всего выбрать для ее предст авления конст ант у.


хранение данных

чааэдо

ЧадаБаеМые B o iij= » o c :b i

ляет тип данных, если я их не

ИЛожно ли оставить переменную неинициализированной,если я заранее

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

указываю?

не знаю ее значения?

вдруг потребуется поменять значение этих параметров.

Q ; в отличие от других языков про­ граммирования, JavaScript не позволяет в явном виде задавать тип констант

; Конечно. Инициализация призвана предотвратить проблемы, которые могут возникнуть при попытке доступа к пере­ менной, не имеющей значения. Но бы­ вают и случаи, когда в момент создания переменной ее значение еще неизвестно.

Каким образом JavaScript опреде­

и переменных. Тип выражается неявно в момент присвоения значения. Это дает переменным JavaScript ббльшую гибкость. К примеру, присвоив число 17 пере­ менной X , вы приведете ее к числовому типу. Но если затем присвоить ей же текст “seventeen”, тип изменится на строковый. Если JavaScript автоматически заботится о типах данных, зачем мне вообще о них задумываться?

I Во многих ситуациях нельзя целиком положиться на автоматическую обработку данных средствами JavaScript. К примеру, у вас есть число, сохраненное в виде текста, которое нужно использовать в вы­ числениях. Для этого его предварительно нужно преобразовать из строкового типа в числовой. Обратная ситуация возникает при необходимости отобразить число во всплывающем окне. JavaScript умеет автоматически преобразовывать числа в текст и обратно, но не всегда делает это так, как вам нужно.

Тогда следить за тем, чтобы обращение не происходило к пустым переменным, уже вам. Кстати, переменным можно присваивать и «пустые» значения, на­

Что происходит с данными сцена­ рия при перезагрузке страницы? ! Все данные принимают свои началь­ ные значения, как будто сценарий перед этим и не запускался. Другими словами, после перезагрузки страницы сценарий запускается сначала.

пример" " для текста, О для числа, или false логического типа. Это уменьшает риск обращения к неинициализированным данным.

Как определить, когда мне нужна переменная, а когда константа? 0 ; Часто пользователи начинают работать исключительно с переменными, а позже обнаруживают, что некоторые из них можно превратить в константы. Скорее всего, это будут повторяющиеся строки текста или число, которое встреча­ ется в нескольких местах кода, к примеру, повторяющееся приветствие или коэффи­ циент преобразования. Вместо того чтобы писать этот текст или число снова и снова.

Тип данных определяется после того, как переменной или константе было присвоено значение.

КЛЮЧЕВЫЕ МОМЕНТЫ Данные в сценариях обычно принадлежат к одному из трех типов: text, number или boolean.

Ключевое слова v a r создает переменные, в то время как c o n s t создает константы.

Переменной называется кусок данных, который меняется в процессе работы сценария.

Тип данных JavaScript определяется в момент при­ своения значения. У переменных тип данных может

Константа — это неизменяемый кусок информации.

меняться.

дальше

81


меня зовут

Ч то В имени тебе моем? П ерем енны е, константы и другие синтаксические конструкции JavaScript определяю тся по своим уникальным именам или, как их ещ е называют, идентиф икаторам . И н ден тиф и каторы JavaScript напоминаю т им ена лю­ дей из реального мира, хотя и с некоторы м и ограничениям и (люди могут носить одинаковы е имена, а вот перем енны е JavaScript —нет). К роме того, им еет смысл придерж иваться следующих правил именования;

Идентификатор должен быть длиной хотя бы в один символ. Первым символом идентификатора должна быть буква, знак подчеркивания ( J или знак доллара ($).

В символах после первого допускаются буквы, циф­ ры, знаки (_) и {$).

Пробелы и специальные символы, отличные от и $, в идентификаторах недопустимы. Когда вы создаете и дентиф икатор JavaScript для перем енной или константы , давайте им «говорящие» имена. То есть вам недостаточно просто вы полнить п еречисленны е выше требования. И мена должны быть такими, чтобы по их виду было понятно, для чего предназначена та или иная перем енная или константа. Разумеется, бываю т и случаи, когда можно обойтись просты м х —дале­ ко не каждый ф рагм ент и нф орм ации в сценарии можно легко описать. Ш ериф Правосудов, за с л у ж е н н ы й юрист .

Идентификаторам следует присваивать значимые имена. 82

глава 2

Я не потерплю на­ рушений закона, когда речь идет об иденти­ фикаторах.

О


хранение данных

Корректные u некорректные имена f ir s t N a m e

t o p i ОО

Н е ко р р е к т н о : и м я не м о ж е т начинат ься с циф ры . Коррект но: им я с о с т о и т т о л ь ко из букв.

ка chow

Коррект но: буквы с н и ж н и м п о д ч е р ки в а н и е м сост авляю т допуст им ую комбинацию .

topSecret

J Коррект но: циф ­ р ы р а с п о л о ж е н ы на п о зи ц и я х , о т л и ч н ы х о т первой.

Некорректно: и м я не м о ж е т начинаться со сп е ц и а л ьн о го с и м ­ вола, от личного от « » или «$»■

$total ?g u i l t y

К о р р е кт н о : начинат ь им я с н иж него по дче р ки ва н и я м о ж но — н е ко т о р ы е п о льзо ва т е ли даж е спец иал ьно п р и м е н я ю т т а к о е и м е но ва ни е , чт обы п о д ­ ч е р к н у т ь особое значение п е р е ­ м енной.

1^

К о рр е к т н о : х о т я т а к и е имена и вы глядят н е ­ с ко л ько с т р а н н о , но зн а к доллара на первой п о з и ­ ции вполне д о п у с т и м .

Вот примеры бейсболок для агентов, рекламирующих кондитерскую Дункана. К сожа­ лению, при их разработке не учитывались стандарты именования идентификаторов в иауа8сг1р1. Зачеркните неподходящие с точки зрения иауаЗсг1р1 варианты.

donut '

fflazel

дальше *

83


решение упражнения

,Н 2Н И б

ешение

Вам нужно было вычеркнуть бейсболки с именами, некорректными с точки зрения

иауаЗсг1р1.

?1агег

в именах идент иф икат оров недопуст имо использоват ь восклицат ельный знак.

И пробелы в них также запрещены..

Символ # вызовет ярост ь и шерифа Правосудова.

СтильВерблюда Законов, обязующих использовать определенны е стандарты именования в JavaScript, не существует, но есть неофициальные правила, которы х придерж ивается больш инство. Одно из таких правил —использовать СтильВерблюда в составны х именах и дентиф икаторов. Такое название появилось из-за того, что заглавны е буквы внутри слова напоминаю т горбы верблюда. В именах перем енны х первое слово обы чно пиш ется буквами ниж него регистра, а все п рочие —смешанным регистром . n ш l_ c a ]c e _ d o n u ts Первая буква каждого слова прописная. Знак подчеркивания между от дельны ми словами вполне д опуст им , но сущ ест вует лучш ий способ.

НижнийСтильВерблюда используется для именования многословных переменных. 84

глава 2

N ш n C a k e D o n u ts

Именно т ак выглядит ст и ль верблюда, но и он не совсем подходит для переменных. Вот т акой ст иль п р е ­ восходно подходит для именования переменных.

Прописной является первая буква каждого слова, кроме саМ_ого


хранение данных

Магниты JavaScript От магнитов с описаниями отвалились имена переменных и кон­ стант. Поместите на каждый магнит нужное имя, особо проследив за их корректностью. В качестве дополнительного задания в каждом случае укажите тип данных.

данных с Ш д -

Количество муки (Поиг) для п р и - ^ гоилоол€-ныя одной порции (hatch) пирожков.

ця Чйш ек , ( n u m b e r of cups).

І^мя ра5отни ~ ка месяца (the е-тріодее o f the

т опЩ .

(^e,cord holder\

Cocm om ae (status) аварийной сигна лизаи,ии (йійгил).

мЛ

Н йлого^й номер number) для Фиксации налога ^ продаж.

(eclaits).

emDlovee*of*the*Month

дальше >

85


решение задачи с магнитами

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

К-Оличейилбс) дат ьт с и о д ня ч й ш е к к о ф е ( n w w b e f or CMpS)-

Количество муки (flour) Зля п р и - ^ готовлеиий одной порции (batch) пирожков.

^ м я работ ни­ ка месяца (рке пшпСирз

enployeeOfMonth

Text

Number

(ИХ number) для с налога

Состояние (status) аварийной сигнаАизации (alarm).

alarmstatus

V Boolean

T ext

cups-o-cjoffee Eir^loyee of the Month alarm s

Оставш иеся ,— имена являю т ся некоррект ны ми с точки зрения JavaScript■

86

глава 2

f

Tax#

f ~ flour quantity

|

e c la ir W in n e r I

Tfc


хранение данных

Следующий этап Вы уже читали о заведении Дункана, но пока ничего не знаете о планах его хозяина. Дункан хочет перевести свой бизнес на новы й уровень... П родавать пончики ч ерез И н ­ тернет! Только представьте, пользователь вводит в форму количество товара и время доставки и точно в указанное время получает горячи е пончики. Вам нужно убедиться, что пользователь ввел все требуемые данны е, и вы числить на­ лог и итоговую сумму заказа.

Ouncan's Just-irvTime Donuts

Mdonuts^c

^

Minutes « pidiup.

То«р6^ Привет, я Дункан. Система заказа моих пончиков через Интернет — это нечто!

хО На основе введенмых пользоват елем данных иауйЗсп'рг вычисляет налог и ит оговую с т о и ­ м о ст ь заказа.

О

D onut Blaster 3 0 0 0 .

Горячие и вовремя!

«oPFtr

V>x>№ifTB

дальше >

87


форум для заказа пончиков

Планируем Веб-страницу О бработка заказов вклю чает в себя как проверку введенны х в ф о р ­ му данных, так и вы числение на их основе суммы заказа. Промежу­ точная и полная суммы долж ны отображ аться сразу же после ввода инф орм ации пользователем. К нопка Сделать заказ просто отправ­ ляет сведения. Ее работа не им еет отнош ения к JavaScript, поэтому здесь она рассматриваться не будет.

.О л Э т а инф ормация т ребует ся для выполнения заказа и п о э­ т о м у ее следует проверит ь средст вами JavaScript.

D u n c a n ^ J u s t-ln ^ tn e O o n m s

в о о D u n c a n 's J u 8 t - J n - T i m e D o n u t e

All donuts 50 cents each, cake or ^azed. " N a m e T jp a u l^

#

of cake do n u ts: ^

# o f g la zed do n uts; pL2 j^ u te s & jb to lS iir |$ 6 .0 0

Tax: j$0 .5 S Total: fse .is

Done

Э т у инф ормацию JavaScript вычисляет, чт о называется, на

88

глава 2

Д ля ф инальной о т ­ правки введенных в ф орм у данных на сервер JavaScript не т ребует ся.


хранение данных

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

( кол-во пончиков + кол-о глазированных ) х цена пончика

Налог вычисляется умножением промежуточной суммы на ставку:

сумма X налоговая ставка

Общая стоимость заказа вычисляется сложением промежуточной суммы и налога:

сумма + налог

Кажется, у Дункана достаточно данных, чтобы отслеж ивать их при помощ и ф ормы . Ему нужно быть не только в курсе введен­ ной пользователем инф орм ации, но и вы числить при помощ и кодаЗауа8сг1р1 ряд параметров.

При помощи JavaScгipt каждый заказ будет доставлен во­ время! О

Ш ТУРМ Какие переменные и константы пона­ добятся для этих вычислений? Какие имена вы бы им присвоили?

дальше ¥

89


не считается

Начнем с Вычислений Дункан попы тался самостоятельно написать код JavaScript, вы полняю щ ий подсчеты, но столкнулся с проблемой. П осле ввода пользователем количе­ ства требуемых пончиков в полях с результатами вы числений стало появ­ ляться не имею щее никакого смысла зн ачение $NaN. Б олее того, заказ не заполнялся. И клиенты были соверш енно не в восторге от технологическо­ го «усоверш енствования» Дункана. о 10ОО

Duncan's

D u n c a n 's

Just-In-Time Donuts

AHdonuts 50 cents each, cake or ^ z e d l Name: jPauT

$ЫаЫ — эт о код для чего-т о п л о ­ хого?

# of caKe donuts: jO # of glazed donuts: Minutes'til pickup: j45

Subtotal; p N a iT ^ Ой, как н е ­ хорошо!

П риш ло время взглянуть на код нашего сценария и понять, что же происходит. П ерейдите на следуюшую страницу (или загрузите п рим ер кода с сайта http://www.headfirstlabs.com/books/hfjs/) и попы тай­ тесь п опять, где именно скры вается источник проблем.

W

/

Нет пончиков = ест ь проблема.

90

глава 2


хранение данных

Э т о т код о бно в л яет за к а з, м гновенн о \ вычисляя п р о м е ж у ­ т очную и полную сум мы . Т а к к а к введенные по л ь зо ва т е л е м дан ные в п о р яд ке , для п о и ска п р о б л е м ы о б ­ р а т и м в н и м а н и е на конст ант ы .

Э т о т код о т ­ п р а в л я е т зака з на сервер и п о д ­ т в е р ж д а е т его принят ие.

<html> <head> <title>noH4MKM Дункана к указанному BpeMeHM</title> <link rel="stylesheet" type="text/css" href="donuts.css" /> <script type="text/javascript"> function updateOrder() ( const TAXRATE; const DONUTPRICE; var var var var var

numCakeDonuts = document.getElementByld("cakedonuts").value■ numGlazedDonuts = document.getElementByld("glazeddonuts").value; subTotal - {numCakeDonuts + numGlazedDonuts) * DONUTPRICEtax = subTotal * TAXRATE; total = subTotal + tax;

document.getElementByld("subtotal") .value = . sum'otai t< + subTotal.toFixed(2) document.getElementByld("tax").value = + tax.toFixed(2)■ ^ document.getElementByld("total").value = + total.toFixed(2); function placeOrderO { // Передать заказ на сервер... form, submit () ;

) </script> </head> <body> <div id="frame"> <form name="orderfo^' action="donuts .php" method="POST">

З а ка з обновляет ся п р и и зм енени и к о ­ л и че ст в а пончиков.

З а ка з п р и н и м а ­ ет ся после ш,елчка на к н о п к е С делат ь заказ.

<div class="field"> ^ Число пончиков: <inpu4,type="text" id="cakedonuts" name="cakedonuts" value=’" onchange="updateOrder0 ;" /> </div> <div class="field"> Глазированных: <input type="text" id="glazeddonuts" name="glazeddonuts" value=" onchange="updateOrder();" /> <div class="field"> <input type="button" value="Cдeлaть за к а з" onclick="placeOrder(this.form);" /> </div> <7form5

-— ----- -----------------

</div> </body> </html>

Возьми в руку карандаш Запишите, что, по вашему мнению, не так с кодом данного сценария.

дальше *

91


решение упражнения

Возьми в руку карондаш Решение

Итак, вот в чем была проблема с кодом сценария для заказа пончиков через Интернет.

М . и н и ц и а л и з и р о в а н ы , и вычисления, в которые они входят, ст али невозможны.

Я знаю, что константы сохраняют свое значение, но не понимаю, зачем их ини­ циализировать?

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

Всегда инициализируйте созданные константы.

92

глава 2


хранение данных

инициализируйте данные... или... Н еин и ци али зи рованы е данны е считаю тся неопределенны ми. Другими словами, они не имею т никакого значения. Это не значит, что они соверш енно бесполезны . О ни просто не со­ держ ат инф орм ации... пока. П роблемы начинаю тся, когда вы собираетесь использовать подобны е перем енны е или констан­ ты , наприм ер, для вычислений.

const

DONUTPRICE;7

в JavaScript операт ор умнож ения a не X.

" ^Инициализировано

v a r n u m C ak eD o n u ts = 0; v a r nu m G laze d D o n u ts = 12;

3-Я ( n u m C a k ^ C f o n u t s + n u m G l a ^ d D o n u t s ) * D0NIJ7?RICE; О

var

subT otal =

subtotal = (0 + 12)

0 Это большая проблема.

К онстанта D O N U T P R IC E неинициализирована. В JavaScript такие данны е обозначаю т специальны м состоянием; u n d e f in e d . Это все равно что оставить на автоответчике сообщ ение «сообщений нет», если вам нечего сказать —вы оставляете сообщ ение, обозначаю щ ее его отсутствие. Так же и с состоянием u n d e f i n e d —оно обозначает отсутствие данных.

Данные не определены, если им не было присвоено значение.

Т ут нет данных.

D O N U TP R IC E

дальше *

93


NaN — не то, что вы подумали

NaN — это НЕ число П одобно значению u n d e f i n e d , которое представляет особое состояние данных, существу­ ет ещ е одно значение пepeм eнны xJavaScrip: NaN. Эта аббревиатура расш иф ровы вается как N ot а N u m b er —не число. И м енно такое значение п рисваивается перем енной s u b T o t a l из-за того, что нам не хватает инф орм ац ии для расчетов. Другими словами, вы восприни­ мали отстутствующее зн ачение как число... а получили NaN. Число

Не ч и с л о ! "Л

subtotal = (О + 12) * ? = NaN Так как эт и данные неопределены , произвест и вычисление невозможно. Так, для реш ения возникш ей проблем ы инициализируйте константу DONUTPRICE в момент ее создания:

NaN — это значение, не являющееся числом.

const DONUTPRICE = 0.50; _

Часто

;^ а Д а Б а е М ы е B o iIp o C b i Что означает «идентификаторы должны быть уникальны в пределах сценария»? 0 1 Идентификатор выступает как уникальное имя для фрагмента информации в сценарии. В реальном мире люди часто имеют одинаковые имена... но при этом они вполне в состоянии разобраться «кто есть кто». иауаЗспр! не умеет решать подобные неопределенности, поэтому различные фрагменты информации различают, присваивая им разны е имена. И вы должны следить за уникальностью всех идентификаторов в ваших сценариях. Идентификаторы должны быть уникальными вообще или только в пределах сценария?

94

глава 2

I Уникальность идентификатора важна присвоим имя Donut, методу — имя именно в пределах сценария, а иногда g e t D o n u t ( ) , а переменной — имя и в пределах части сценария. Но следует numDonuts. Для констант подобный помнить, что для больших приложений подход не применяется. Имена констант иногда требуются очень большие пишутся полностью заглавными буквами. сценарии,распределенные по файлам. В этом случае имеет смысл делать Существует ли значение NaN для идентификаторы полностью уникальными. текстовых и логических данных? Но для этого достаточно давать им значимые имена в контексте выполняемой ; Теоретически да, так как параметры задачи. этих типов не являются числами. В реальности же это не так. Значение Я так и не понял, зачем нужен NaN указывает, что число — это не то, стиль верблюда? что вы думаете. Другими словами, NaN — это не описание данных JavaScript, Q ; Стиль верблюда с заглавной а индикатор ошибки для численных буквой первого слова используется типов. Это значение обычно появляется для именования объектов JavaScript, в результате вычислений, в которые о которых мы поговорим в главе 9. Для в качестве параметра по какой-то причине переменных и методов используется попали нечисловые данные. стиль верблюда, в котором первое слово пишется с прописной буквы. Соответственно, объекту мы


хранение данных

А те м временем у Дункана... у Дункана дела идут все хуже и хуже. Вместо пустых коробок теп ерь везде пончики —в каждый заказ добав­ ляю тся лиш ние. Дункан утонул в жалобах на избы ток пончиков и другой выпечки...

...... Duncan's Just-In-Time Donuts Altdonuis 50 cents each, cake or glazed! Name: jcrS

I ■ I

‘GO 'FFEfE

J

Bom чт о было получено вм ест о й заказанных пончиков.

-....

„ t €50F*;iaE ^

-0'0im£9e ^

*>©;MSUT5 SSSSSSSSSS?

iiSwmwS^^

Ш ТУРМ Что может быть не так с обработкой данных о количестве пончиков?

дальше >

95


различные типы сложения

СкладыВать мо)кно не только числа в JavaScript многое значит контекст. О собенно важен тип данных, с которы м и осущ ествляется манипуляция в каждом конкретном куске кода. Ведь даже такая простая операция, как слож ение, дает разны е результаты для данны х разны х типов.

1 + 2 = 3

"с1о" + "nuts" = "donuts"

I

У

Сло)кение чисел

^р а си во е название -ОЛЯ «склеивания слов друг с другом>.

^

Соединение строк

Это прекрасно вам знако­ мая из начальной школы ариф м етическая операция.

П р и этой операции на­ чало второго слова «приклеивается»к концу первого.

И так, вооруживш ись знанием о том, что строки складываются не так, как числа, ответьте, что произойдет при слож ении двух чисел в текстовом формате? ?

Сложение, соединение, чт о именно?

Язык5ауа8сг1р1 не разби рает смысл текста —с его точки зрен и я, это всего лиш ь набор символов. П оэтому тот факт, что строка содерж ит численны е символы, не им еет никако­ го значения, будет вы полнено соединение строк. Если вы предполагали математическую операцию слож ения, дан­ ны й результат окаж ется неожиданным.

Так как эт о ст роки, а не числа, они « склады ваю т ­ ся» п у т е м соединения ст рок.

96

глава 2

Вы получит е ст року, кот орая никак не напо­ м инает резуль>тат м а ­ т ем ат ической операции.

Б йА ьте о с т о |э о ж н ь 1 !

Всегда следите, что именно вы складываете.

Соединение строк вместо сложения чисел — не самая редкая ошибка в JavaScript. Если требуется сложить два чис­ ла, убедитесь, что они нахо­ дятся в нужном формате.


хранение данных

Методы раг$е1п1(] и раг$еР1оа1() П ериодически возникаю т ситуации, когда требуется сложить числа, сохраненны е в текстовом форм ате. В этом случае вам сле­ дует сначала преобразовать строку в число. Для подобных преоб­ разований вJavaScript предусмотрены два метода:

p a r s e F lo a t П ереданная данному методу строка преобразуется в целое

А этот метод преобразует строку в число с десятичной (плавающей) точкой.

число.

О ба метода берут в качестве п арам етра строку и преобразую т ее в число: рдг5е1пед п р е о б р а зу е т " 1 " в г .

Я

рагз^1п1:("1") + p a r ^ n t ( " 2 " ) = 3 / "

\

Следует помнить, что методы p a r s e I n t () и p a r s e F l o a t () могут и не сработать. Все зависит от парам етров, которы е вы им передадите. О ни превосходно преобразую т строки в ц и ф ры , но важно дать им в качестве п арам етра строку, со­ держащую только численны е символы.

p a r s e F lo a t( " $ 3 1 .5 0 " )

= ЫаК

/ Э т о т код не б уд е т работ ат о, т а к как т т о д не п о н и м а е т си м во л а

На э т о т р а з м ы п о . лучи м резул ьт ат м ат ем ат ического слож ения.

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

С ю рприз! В результ ат е п о л у ч и т е все т о т ж е

дальше >

97


когда вещи не складываются

Откуда берутся лишние пончики? В згляните внимательно на форму заказа пончиков. П опы таемся понять, почему возрастает количество заказанного...

#00

CD

Duncar»*s Just-ln-Time Donuts

Duncan's Just-ln-Tlfn© Donuts All donuts 50 cents each, cake or glazed!

Name: Greg

# of cake donuts: 6 # of glazed donuts: Minutes 'til piclcup: W JS 3 1 .5 0 ^ О п л а т а берет ся за ко л и ч е ст во пончиков, ч е м было злказано... но

ах: Ш ж Total: $34.41

н а с к о л ^ о их больше?

Иасе Order

Done

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

$31.50 / $0.50 = 63 пончик

Ц енй одного п о н ч и ка .

К аж ется, мы столкнулись с проблем ой объединения строк. Ведь данны е, введенны е в форму, всегда сохраняю тся в стро­ ковом ф ормате. Даже введенны е вами ц иф ры с точки зрения JavaScript являю тся текстом. П оэтому мы избавимся от ош иб­ ки, просто преобразовав строки в числовой ф ормат.

98

глава 2

^ о т с ко л ь ко п о н ч и ко в было за ка за н о на с а м о м оеле... ст ранно...

Вы п о м н и т е , ч т о "3 -" + "Я К а ж е т с я ,, здесь м ы с т о л к н у л и с ь с а н а л о ги ч н ы м случа е м .


хранение данных

Возьми в руку карандаш Показанные ниже строчки кода забирают введенную в поля инфор­ мацию о количестве заказанных пончиков. Воспользуйтесь ими для заполнения недостающих строк метода u p d a t e O r d e r () таким образом, чтобы информация о размере заказа была преобразована в числовой формат.

docum ent. g e tE le m e n tB y ld (" c a k e d o n u ts " ) . v a lu e

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

А эт а ст рочка получает из ф орм ы данные о количест ве заказанных глазированных пончиков. •

d o c u m e n t. g e tE le m e n tB y ld (" g l a z e d d o n u t s " ) . v a lu e

function updateO rder0 { c o n s t TAXRATE = 0 . 0 9 2 5 ; c o n s t DONUTPRICE = 0 . 5 0 ; v a r n u mC ak eDon ut s =

v a r numGlazedDonuts =

if

(isNaN(numCakeDonuts)) n u mC ak eDo nu ts = 0; i f (isNaN(numGlazedDonuts)) n u m G l a z e d D o n u t s = 0; v a r s u b T o t a l = ( nu mCakeDonuts + n u m G l a z e d D o n u t s ) * DONUTPRICE; v a r t a x = s u b T o t a l * TAXRATE; v ar t o t a l = subTotal + tax ; d o c u m e n t . g e t E l e m e n t B y l d ( " s u b t o t a l " ) . v a l u e = "$" + s u b T o t a l . t o F i x e d (2); document. g etE lem entB yld (" ta x " ) . v a l u e = + t a x . t o F i x e d (2) ; d o cum ent.getE lem entB yld("total").value = + t o t a l . t o F i x e d (2);

дальше у

99


решение упражнения

Возьми Вруку карандаш. 'ешение

Итак, вот каким образом нужно было вставить данные в строч­ ки кода, чтобы завершить метод u p d a t e O r d e r {).

docum ent. g e tE le m e n tB y ld (" c a k e d o n u ts" ) . v a lu e

Так как в обоих случаях мы им еем дело е целыми числам и, используем для преобразования м ет од раг5е1пЬ().

docum ent. g e tE le m e n tB y ld (" g la z e d d o n u ts " ) . v a lu e

function updateO rder0 { c o n s t TAXRATE = 0 . 0 9 2 5 ; c o n s t DONUTPRICE = 0 . 5 0 ; v a r n umC akeDo nu ts =

A V

w

parselnt(docum ent.getElem entByld("cakedonuts").va(ue):, \

v a r numGlazedDonuts = parselifxt(docum ent.getElem ent8yld("glazeddonuts'').value); if

(isNaN(numCakeDonuts)) n u mC ak eDo nu ts = 0; i f (isNaN(numGlazedDonuts)) n u m G l a z e d D o n u t s = 0; v a r s u b T o t a l = ( numCakeDonuts + n u m G l a z e d D o n u t s ) * DONUTPRICE; v a r t a x = s u b T o t a l * TAXRATE; var t o t a l = subTotal + tax; docum ent.g etE lem en tB y ld C 'su b to tal").v alu e = + s u b T o t a l . t o F i x e d (2); docum ent.getE lem entB yld("tax").value = + t a x . t o F i x e d (2); d o c u m e n t . g e t E l e m e n t B y I d ( " t o t a l " ) . v a l u e = "$" t o t a l . t o F i x e d (2);

М етод ЬоР1хЫ () округляет __ су м м у в долларах, ост авляя после запят ой всего два знака.

100

глава 2


хранение данных

КЛЮЧЕВЫЕ МОМЕНТЫ Имена констант имеет смысл писать ПРОПИСНЫ­ МИ БУКВАМИ, а имена переменных — с использо­ ванием стиляВерблюда.

Всегда инициализируйте константы в момент

NaN означает не число и используется для указа­ ния на отсутствие численных данных там, где они должны быть.

создания, а переменные по мере возможности.

Соединение строк отличается от математического сложения, хотя и выполняется одним оператором (+).

Неинициализированная переменная имеет статус

Встроенные методы p a r s e i n t ()

undefined, пока ей не будет присвоено значение.

и p a r s e F l o a t {) преобразуют строки в числа.

Вы решили проблему... Дункан восхищ ен исправлениями, которы е вы внесли в код JavaScript. Т еп ерь с получаемыми им заказами все в порядке и бизнес пошел в гору. 6

_____________

« j.a>№ Мида»

Duncan's JusMn-Time Donuts

-

rls »irmoPu»« Грего. atpt 70 «< a*'»

Nam:jc^ « of oake donuts: j6~~

^ of gtazarS donuts: Minutes 1«p)cfcup:|Ja S u W o la tjiliJ Tax: [so'ff Total: IsT gT Oone

Система заказов через ) Интернет работает пре- "S ___ ) восходно!

Разумеется, не стоит полагать, что несколько бы стры х исправ­ л ен и й реш ат проблему навсегда. Самые надоедливы е проблемы обы чно возникаю т из-за сторонних ф акторов... дальше *

101


г неприятности нарастают

Дункан обнару}киваеіп шпиона у Дункана новая проблема: проны рливы й конкурент Ф ренки. Ф ренки торгует хот-догами на той же самой улице. Ч тобы на­ вредить Дункану, он отп равляет ч ерез И н терн ет фальш ивые безы м янны е заказы. В итоге Дункану приходится работать впустую.

0 0 «

Duncan’s Just-ln-Tim e Donuts

Duncan'S Just-In-Time Donuts All donute 50 certs each, cake or glazod! Name: # of cake dofiyts: p i # of glazed donute; jio Minutes 4it pickup: p5

Дункан впустую трати т драгоценное время, энергию и пончики, вы полняя фальш ивы е заказы. Нужно сделать так, чтобы ф орм а отправлялась только после ввода всех данных.

102

глава 2


хранение данных

Метод getElementByldO Для проверки корректности вводимых в форму данны х требуется способ получения этих данны х со страницы . Ключом, дающим JavaScript доступ к элементам страницы , является атрибут i d в теге HTML: <input

type= "text"

id= "cakedonuts"

nam e= "cakedonuts"

/> < -

Вводимый в ф орм у элем ент предст авляет количество обычных пончиков (саке donuts).

г А т р и б у т 1(1 использует ся для дост упа к полям ф ормы о коде иауаЗсп'рЬ.

# of cake donuts: 118

JavaScript п озволяет восстанавливать элементы веб-страницы по их номеру ID п ри помощ и метода g e t E l e m e n t B y l d (). Э тот метод не забирает данны е напрямую, а представляет поле HTM L в виде объекта JavaScript. Д ля доступа к данны м доста­ точно воспользоваться свойством v a l u e этого поля.

ф ормально getE iem entB ylP Q не функция, а м ет од объ ­ ект а документа.

О

document.getElementByldO

Не волнуйтесь по поводу объектов, методов и свойств!

|

■einjiu.i , pu.umimJiiJm-Liw*«» iJiJiiiu» Взяв в качестве парам етра Ш элемента страницы , метод возвращ ает вам сам элемент, которы й затем можно исполь­ зовать для доступа к данным. М етоЭ getE lem entB yldO принадлеж ит об-ьекту документа.

в JavaScript поддерж ива­ ется усоверш енствованны й тип данных, назы вае­ мый объектом, позволяю щ ий делать потрясаю щ ие вещи. Д а и сам язы к JavaScript по сути является набором объектов. Н о об этом мы поговорим позднее. П ока же вам достаточно помнить, что метод подобен м атематической функции, а свой­ ство —это своего рода перем енная.

docum ent. g e tE le m e n tB y ld (" c a k e d o n u ts " )

Ю — эт о ключ дост упа к элем ент ам .

docum ent. g e tE le m e n tB y ld (" c a k e d o n u ts" ) .v a lu e Свойство value дает дост уп к данным.

# of cake donuts: p i

Вооружившись этим кодом, п роверим форму Дункана на кор­ ректность вводимых в нее данных.

дальше *

103


всё ли вы заполнили ?

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

Заказ понт ков.

В данном случае мы долж ны проверить, не равен ли парам етр value (соответствующих полей) пустой строке ("").

docum ent. g e tE le m e n tB y ld ("name") . v a lu e

Если значением поля nam e является пустая строка, процедуру за­ каза следует приостановить и попросить клиента ввести его имя. Аналогично следует поступить с полем ввода времени. К роме того, следует проверить, к числовому ли типу относятся введенны е в это поле данные. Д ля этого вам потребуется метод IsNaN () . О н возвращ ает значение ( t r u e ) , если переданны й ему парам етр не является числом, и зн ачение ( f a l s e ) в противном случае.

Пустая строка указывает на отсутствие в форме данных.

Н еверны й 'о о р м а т

оанных. Minutes 'Ш pickup: jfifteen

г

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

: \

isN aN (docum ent. g e tE le m e n tB y ld (" p ic k u p m in u te s " ) . valu e)

isNaNQ п р о ­ веряет т и п вводимых данных.

104

глава 2

Если возвраи^ается значет е tru e, значит , данные введены в неверном ф о р ­ м а т е , и заказ не мож ет быть обработан.

-^true


хранение данных

Магниты JavaScript Метод р1ас еОг (1е г () выполняет проверку корректности введенных в ПОЛЯ данных. Воспользуйтесь магнитами, чтобы получить код, проверяю­ щий ввод имени клиента и времени в минутах, а также то, что во второе поле введено именно число. Вам потребуются все магниты, а некоторые из них будут использоваться больше одного раза.

О перат ор ”(Т" проверяет со олюдение условия и в зависи м ост ц от р езу льт а т а о с у ­ щ ест вляет некое действие.

fu4ction placeOrder0 V if (.......... alert(

Это означает , чт о к дей­ ст виям приводит одно из двух условий — если т ак ИЛИ т ак, т о следует н е ­ кое действие.

Это проверка равенства.

{

y o '„ 'm ;; t 'p r o r i W e ', o «

an o r d e r . " ) ;

J II

else if ....................................... ................. U'V'''oirmnsV’Drovide''the'number of minutes until pick-up" alert("I'm sorry but you must proviae " before submitting an order."); else //

О т п р а в к а заказа на сервер form.submit О ;

Ц}

docioment

Ш '

getElementByld isNaljJl

value 1

дальше *

105


решение задачи с магнитами

Решение задачи с магнитами Вот как выглядит код метода p la c e O r d e r ( ) , проверяющего корректность ввода данных о пользователе и времени до до­ ставки заказа, после заполнения пустых мест.

Здесь п т б ер яет ся, не м е н я е т с я ли значение S nam e п у с т о й ст ро

Если им я не введеноJ т о появляет ся окно с сообщением.

f ui c t i o n p l a c e O r d e r о

V

if

Кб " "•

{

getElementByld

docmaent

J(

......... „ (Ь a le rt( " I'm sorry

e R n b m ittin g an o r d e r . " ) ;

^ getElementByld else

if

a l e r t ("" before

getElementByld

s u b m i t t i n g an o r d e r . '

else / / Отправка з а к а з а на сервер f o r m . s u b m i t {);

глава 2

| ( "pickupminutes"

' У value

(

is N a N j

106

Э т у ф разу с ко м п ью т ер но ­ го языка на обычный можно перевест и так: «если значе­ нием являет ся пуст ая с т р о ­ ка ИЛИ значение не являет ся числом».

^

^ pickupminutes"

)

1 T

.1 value


хранение данных

и сноВа Вы спасли Дункана! Н овая, улучшенная ф орм а прием а заказов полож ила конец вредоносной деятельности Ф ренки и сделала страницу более устойчивой. П рим енение 5ауаЗспр1 для защ иты целостности вводимых клиентами данны х —беспроигры ш ны й вариант, особенно в ж естоком ресторанном бизнесе!

Duncan'»

0 0© „

о Т

ОопиЦ^

CD

Duncan’S aust4n-T5ni0 Donuts М donuts 50 cents each, cake or glazed! Name: Г # of cake donuts: pL8 # of giazed donuts; j5o Minutes 4it ptekup; jwwen ^

1$24ЛСГ

Tax:[S2.22~ Total; |$26.гГ P lace O rd er

j

.O '

Tenept>j если поле пат е ост ает ся н е ­ заполненны м, вм ест о от правки заказа п о ­ являет ся окно с со ­ общением.

Ctone

П е р еста л быть проблемой и ввод данных неподходяще­ го ф о рм ат а в полв^ предназначенное для времени доставки.

I’m sorry but you must provide your name submitting an order.

before

i'm sorry but you must provide the number of minutes ur>ti! pick-up before subm ittmg an order.

C ~ oT J

дальше >

107


спросите... в а м

же хочет ся

чаопо зад аваем ы е В опросы Как оператор (+) распознает, складывать ему или соединять? Q ; Как это часто бывает в JavaScript, функциональность определяется контекстом. То есть оператор смотрит, что он «складывает», и определяет, осуществлять ему арифметическое сложение или соединение строк. Проблемы возникают, когда вы путаете тип данных. Это дополнительная причина, по которой стоит перепроверять данные перед операцией сложения.

страницу, а браузер. На самом деле код JavaScript изолирован от кода НТМ1 и получает доступ к нему при помощи специальных механизмов. Один из таких механизмов включает в себя атрибут

усовершенствованный тип данных JavaScript, объединяющий в себе

i d , позволяющий языку JavaScript воспользоваться элементом НТМ1. Пометив элемент страницы атрибутом Ю, вы даете JavaScript возможность работать с ним.

как свойство является его переменной или константой. С практической точки зрения JavaScript использует объекты для

А как именно код иауаЗспр1 осуществляет доступ к элементам НТМ1-кода?

Что произойдет при попытке сложить строку и число?

parseint p a r s e F l o a t ().

— ---

{) или

Что будет, если методу p a r s e i n t о дать в качестве параметра строку с десятичной точкой? Q ; Ничего страшного. JavaScript решит, что вам просто не интересна дробная часть, и вернет только целую.

Каким образом атрибут i d связывает элементы с кодом JavaScript?

g e t E l e m e n t B y l d () d o c u m e n t является ключом,

Q ; Метод

объекта дающим доступ к элементу HTML из JavaScript. Этот метод использует атрибут i d для поиска элемента на странице. Идентификаторы HTML, как и идентификаторы JavaScript,

должны быть уникальны в пределах страницы. В противном случае метод

g e t E l e m e n t B y l d O не сможет определить, какой из элементов следует вернуть.

я помню, что мы будем рассматривать эту тему в главе 9,

! Представим атрибут i d в виде портала, через который код JavaScript получает доступ к коду HTIVIL. Говоря, что код JavaScript запускается на веб­ странице, обычно имеют в виду не саму

108

глава 2

представления всего на свете — и окно браузера, и веб-страница являются объектами. Именно поэтому вызов метода g e t E l e m e n t B y l d () осуществляется посредством объекта

d o cu m en t .

А теперь вернемся к материалу главы 2 ...

Я так и не понял, в чем разница между элементом веб-страницы и его значением.

Q ; Так как в JavaScript преобразование чисел в строки происходит автоматически, такая операция приведет к объединению строк. Поэтому сначала число преобразуется в строку, а потом две строки соединяются. Чтобы сложить два числа, сначала преобразуйте строку методом

методы, константы и переменные. Метод — это всего лишь функция, являющаяся частью объекта, в то время

но объекты уже неоднократно упоминались. Что же это такое? Q ; Мы в данном случае слегка забегаем вперед. Объектами называется

; Элементы веб-страницы с точки зрения JavaScript являются объектами. Это означает, что у них есть свойства и они могут управляться методами. Одним из таких свойств является v a l u e , содержащее хранящееся в элементе значение. Например, значением поля формы являются введенные в него данные. Зачем мне знать, что значение не является числом? Может быть, лучше проверять, я в л я е т с я ли оно числом? ; в большинстве случаев предполагается, что вы имеете дело с числами, поэтому имеет смысл проверять исключения. Этим вы делаете код более устойчивым и избегаете странных вычислений, в которые могут быть включены данные неподходящих типов.


хранение банных

интуитивный ВВод данных Т еперь, когда Дункан реш ил основны е проблемы, он хочет улучшить форму заказа пончиков. Н а вывеске его заведения красуется «горячий пончик», и всем проходящ им мимо сразу понятно, что находится внутри. Такой ж е интуитивно п онятной Дункан м ечтает сделать форму заказа. О н знает, что пончики обы чно берут дюжинами. Редко кто просит 12 или 24 штуки —спраш иваю т 1 или 2 дю­ жины. Так почему бы не дать клиентам возмож ность вводить данны е в привы ч­ ном им виде. П роблем а в том, что наш сценарий не восприним ает слово «дюжина» как руко­ водство к действию и п ерестает понимать, сколько ж е пончиков требуется. Duncan's Just-In-Time Oojnuts

# 0 0

Duncan's Just-In-Time Donuts A ll c k m u ts 5» c e n ts e a c h , c a k e o r g la z e d ! Name # o f cake donuts: |3 dozen

М е т о д p a rs e ln tO

'Преобразует с у оку «3 d o z e n .

# o f glazed donuts

о число 3.

M inutes 'til pickup: jso Subtotal; |$1 50 Tax; [$0.14 Total; j$1.64

parseint("3 dozen")

Done

С ценарий не прекращ ает работы , когда пользователи вводят слово «dozen» вслед за числом. М етод p a r s e i n t () просто иг­ норирует данны й текст. П оэтому в сухом остатке мы получаем число, а слово «дюжин» отбрасы вается.

Это ‘^ucAOj а не ст рока.

Ш ТУРМ Можно ли сделать так, чтобы пользователь вводил или количество пончиков одним чис­ лом, или же число дюжин и слово «dozen» следом? Как этого добиться?

дальше V

109


дюжинами дешевле .. или нет

Можно ли воспользоваться поис­ ком по введенному тексту и найти слово «dozen»? — V

Если клиент хочет считать дюжинами, умножим на 12! Ч тобы добавить в сценарий возмож ность заказы вать пон­ чики дю жинами, нужно п ровери ть введенную клиентом и нф орм ацию на наличие слова «dozen» до вы числения промеж уточной суммы. Если такое слово присутствует, вве денное число умножается на 12. В противном случае число используется для вы числений без редактирования.

# of cake donuts; j3 dozen # of саке donuts; p J

parseint("3 dozen") parselnt("18")

Введено точное количество з а ­ казанных п о н ­ [ чиков.

Так как в данных ^присут ст вует слово « d o ze n » , умнож им чис­ ло на 1 2 ..

©

3 * 12 =

0

SSSSSSSSSSSS '

I COTTER

110

глава 2

' sssssssss


хранение данных

ощ оБ ьШ К °Д

JaVa^cfipt

П ользовательский метод p a r s e D o n u t s () обрабаты вает инф орм а­ цию о количестве заказанны х пончиков. Сначала он преобразует введенны е данны е в численны й ф орм ат, затем п роверяет наличие там слова «dozen». П р и обнаруж ении этого слова введенное число уножается на 12. П олучите р ец еп т по адресу http://www.headfirstlabs. сот/books/hfjs/.

fu n c tio n parseDonuts (donutString) { numDonut s = p a r s e i n t ( d o n u t S t r i n g ) ; i f ( d o n u t S t r i n g . i n d e x O f ( " d o z e n " ) != - 1 ) numDonut s *= 12; r e t u r n n u mDo nu t s; }

ест ь слово «dny^Mi,^

Умножаем число пончиков на i-2..

Анализируя дю)кины пончиков... М етод p a r s e D o n u t s () вы зы вает метод u p d a t e O r d e r () , вы ­ числяю щ ий на основе введенны х клиентом данны х промежу­ точную и конечную суммы. Получаем число за казанных пончиков из поля формы.

И нициализация двух конст ант . function updateOrderо { const TAXRATE = 0.0925; ^ const DONUTPRICE = 0.50;

7

Л j

var numCakeDonuts = ParseDonuts(document.getElementByld("cakedonnh<,-M

ir

i

^

<

(^IsStL'Ske^D^nu^sn^"^^""'' "glazeddonuts")":aiue numCakeDonuts = 0; .if-— -- Если 6 поля Эля Шода данный о количест в. If (isNaN (numGlazedDonuts) ) введены не числа, присвоим эт им numGlazedDonuts = 0; значение G

var to ta l

.

s u b lo ta l + t a , ;

j

f« Z “

document.getElementByldC'subtotal").value = a o o ™ e „ t . g e t E l e m e „ t B y I d ( " t a x - , . v a lu e

-

+ subTotal

"5 " * ta x . t o F lx S ^ )

document.getElementByld("total").value = "$■' + total.toFixed(2);

Показываем на ст ранице су м м у в долларах.

сум м ц l lo M ^ p a x до двух Гкпл запят ой (количест во центов) дальше >

111


горячее не бывает!

Полный успех предприятия! И дея Дункана о доставке горячих пончиков к указанному клиентом времени заработала благодаря JavaScript, которы й п озволяет тщ ательно п роверить вводимы е в форму данные.

Теперь люби­ тели пончиков могут за­ казывать их через Интернет к указанному времени.

і е д а їе р @ 0 0

Duncan's lust-lt»“Tim< Don s

О

Duncan's Just-In-Time Donuts All donulB 50 cents each, cake or giszedi Name; {Alan # of сяке donuts; fl5

Пончики

# of glazed donuts: |4 t o e n Minutes -to pickup: |Ї0 Subtotal: j$31.50

Вовремя!

Tax: jS 2 jT Total: р м Г

Place Order

Done

112

глава 2


хранение данных

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

Чего мы все хотим для данных нашего сценария? у.у хороШо, а ДВа -ііу'Шіе!

Вводимым пользователями данным доверять нельзя. Предполагать, что пользователи при вводе данных будут их проверять, неразумно. В этом деле следует положиться на Ла¥а8епр1.


исследование кл и е н т а

Иногда иауаЗспр! хочет знать, что происходит в окружающем мире. Ваши сценарии могут существовать в качестве кода на веб-страницах, но по большей части они живут в мире, создаваемом браузером или клиентом.

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


любовный треугольник JavaScript, клиент и сервер

Клиент, сервер и JavaScript П осле щ елчка на ссылке или ввода и К Ь в адресную строку браузер требует указанную страницу с сервера и доставляет ее клиенту. JavaScript не начинает работу, пока страница не будет доставлена. Его код встроен в страницу и работает вместе с браузером, отвечая на действия пользователя. Ч асть браузера, запускающая код JavaScript, назы вается интерпретатором.

©

Браузер требует страницу с сервера.

Клиент

©СО

Duncan's Jost-in-Time Donuts

Duncan's Just-ln-TIm® Donuts

CD ( з ) Браузер отображает страницу.

All donuts 50 cents each, cake or glazed!

Name: jAlan

# of cake donuts; jlS # of glazed donuts: |4 dozen

©

^

Minutes ’til pickup:

иауаЗспр! проверяет поля формы в момент ^ ^ ввода данных. г

Subtotal: j$31.S0

T a x :|$ 2 jT " Total:

|$34.4Т

©

Код Ja vaScript выполняется полност ью на ст ороне клиент а.

О 116

глава 3

Запрос...

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


знакомство с браузером

З а п р о с с тр ан и ц ы

S i' Connection; close ^ Accept-Encoding: gzip

^ /„-1„вгт image/jpeg, image/p]peg, . ..

HTML описывает , с т р у к т у р у документа.

Ответ на запрос <html> <head> <title>Duncan's Just-In-Time Donut..</t ^м .s _

I

"

IP.- ri-ГГ--ГГ-p...........

g”""’

<sc ^ type "text/javascript"> unction u p d a t e O r d e r () {

parseDonuts(donutString)

function p l a c e O r d e r

0

{

__

------------------- --

{

JavaScript добавляет и н ­ терактивность). В дан ном случае он проверяет введенные пользоват е леМ данные. Сервер отправляет запрошенную страницу.

( 1) <body> <div id="frame">

л-

<div c l a s s = 4 u b h e a d i n g " > A i r d o n u t r s r ' ^ ^ ^ ^ Donuts</div> <drv i d = " l e f f > ® 50 cents each, cake or

glazed '</div>

</<xmg src="donuttime.png.. alt=-Just-In-Ti^e Donuts" /> <div id="right"> </div> </div> </body> </html>

U iT V P M Какие еще задачи разумнее выполнять на стороне клиента, а не на стороне сервера?

далее >

117


спроси не то, что т ы можешь сделат ь д ля браузера...

Ч то браузер мо)кет сделать для Вас? Ваш браузер отвечает за запуск кoдaJavaS cript, давая сценариям до­ пуск к клиентской среде. Н априм ер, сценарий мож ет узнать ш ирину и высоту окна браузера или историю посещ ений веб-страницы. Дру­ гими интересны м и функциями браузеров, откры ты м и для JavaScript, являю тся тайм еры и возмож ность сохранения куки. Так назы ваю тся создаваемые серверам и ф рагм енты данных, которы е хранятся на ком­ пью тере пользователя даже после того, как он ушел со страницы или вообщ е закры л окно браузера.

изме|>ения браузера Вы мож ете узнать не только разм ер окна браузера и видимой части веб-страницы, но и и н ф о р ­ мацию о производителе, и даже ном ер версии.

история браузера С п ом ощ ью ]ауа8спр1вы мож ете получить доступ к спи­ ску последних посещ енны х страниц и п ерей ти н а любую и з них, эф ф екти вн о с о з д а в ^ ваш и собственны е элементь управления браузером.

Таймеры Кука

Тайм еры позволяю т запускать код 5ауа8спр1 по истечении заданного времени.

Куки подобны перем ен­ ным, которы е сохраняю т­ ся браузером на жестком диске пользовательского ком пью тера после заверш е­ ния веб-сессии. То есть вы мож ете покинуть страницу, снова на нее вернуться, но они все равн о никуда не Это далеко не все функции, которы е клиент предоставляет сцена­ денутся. риям. Мы всего лиш ь попы тались дать вам представление о том, что JavaScript умеет намного больше, чем просто присутствовать на странице. Б олее того, часто возникаю т ситуации, когда им еет смысл выглянуть за пределы страницы и получить от браузера помощь.

118

глава 3


знакомство с браузером

Часто

____ <аДаВаеМые

-------

БоГЦроСЬ! Итак, иауаЗсг1р1 является частью клиента? О ; Да. Поддерживающие иауаЗспр! браузеры имеют встроенный интерпретатор, отвечающий за чтение и запуск кода на странице. 3 * Если код иауаЗспр! запускается на стороне клиента, как он связан с сервером?

Позволяет ли иауаЗспр! контролировать клиента?

Q ; Код JavaScript не имеет прямого доступа к серверу, так как он работает на стороне клиента. Обычно он используется для перехвата данных, транслируемых с сервера в браузер. Но можно написать и сценарий, который будет запрашивать информацию с сервера, а затем обрабатывать ее и отображать на странице. Эта техника называется Ajax. О ней мы поговорим

0 ; И да и нет. Браузеры дают иауаЗспр! доступ к определенным частям клиентской среды, но он весьма ограничен по причинам безопасности. Например, большинство браузеров не позволяет сценариям открывать и закрывать окна без согласия

в главе 12.

пользователя.

Объект iRocl( слишком счастлив П ом ните объект iRock? Ваш код JavaScript имел такой успех, что его выкупил молодой п редприним атель Ален. Н о он снова обратился к вам, так как появилась проблема... П ользователей раздраж ает вечное счастье объекта 1Коск. Разумеется, мы все хотим, чтобы наш и домаш ние лю бимцы были счастливы, но в данном случае диапазон эм оций уж слишком ограничен.

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

Один щелчок... и я буду улыбаться вечно.

д ден.

0« ^ ^ 8о »«лоМ ,ллитЬ, Hft

И так, вам следует подстроиться под ожидания пользователей. П остараем ся сделать вашего виртуального домаш него лю бимца как мож но более реальным. Вам следует понять, как нужно поменять по­ ведение объекта 1Коск. И кажется, в реш ен ии проблемы вам мож ет в н екоторой степени помочь браузер клиента. далее

119


эмоции объекта гйоск

^Rock дод}кен быть более отзыВчиВым Рассмотрим возможны е варианты поведения объекта 1Коск, которы е сделаю т его более реалистичным и привлекательны м для пользователя, не говоря уже о больш ей интерактивности. В идеале нам следует увели­ чить диапазон испы ты ваем ы х объектом эмоций.

Разгневанный

Последнюю версию кода /Ш ск г.О вы найдете по адресу nttp://w w w .keadfirstlab< ,.com /books/hfjS.

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

/^о д а В лен н ы й К а д раз, когда вы закры ваете страницу камеш ек начинает плакать, требуя, чтобы пользователь оставил окно браузе­ р а открытым.

Одинокий Если долго не обращ ать вним ания на 1Коск, он на­ чинает чувствовать себя одиноким. Щ елкайте на нем периодически, чтобы он чувствовал вашу заботу.

ШТУРМ Какие из этих эмоций имеет смысл приобрести объекту 1Коск? Каким об­ разом их можно реализовать при помощи иауаЗспр!?

120

глава 3


знакомство с браузером

Мне нравится идея, что камешек может почувствовать одиночество, так как именно такое по­ ведение свойственно реальным домашним животным Можно ли сделать так, чтобы поведение объекта iRock менялось с течением времени?

J a v a S c rip t п о зв о л я ет у зн а ть , ко гд а пол ьзовател ь вы полняет н е к и е д ей ств и я ... И ко гд а он это го н е д ел а ет. Бы ло бы и нтересн о заставить камеш ек испы ты вать одиночество, так как это подтолкнет пользователя к взаимодействию и вознаградит позитивны м от­ ветом объекта 1Коск. В опрос в том, как п ри помош;и JavaScript заставить объект 1Коск со временем менять свое эм оциональное состояние. Нужно сделать так, чтобы 1Коск начинал грустить, если в теч ен и е опреде­ ленного врем ени пользователь ни разу не ш;елкнул на нем.

...5 секунд

спуст я.

далее

121


время работает на меня

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

П родолж ит елш ост ь Задерж ка

Сейчас

Л й м е р а определяет именно задержка. П озднее

Таймер начинает работ ат ь сразу же после его настройки.

а І е г Ь («Просьшайся!)

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

122

глава 3

После т ого как указанное время кончит ся, т а й ­ м ер заверш ит работ у.

Таймеры позволя­ ют запускать код 1ауа8спр1 через нужное вам время.


знакомство с браузером

Как работает таймер Ч тобы запустить таймер, вам нужно 1) указать время задержки; 2) ука­ зать код, которы й следует запустить после указанного времени. Таймер начинает работу сразу ж е после его настройки.

В ремя задерж ки отсчиты вается в миллисекундах, то есть в ты сяч­ ны х долях секунды, к примеру, 2 секунды это 2000 миллисекунд.

О т образит ь

сообщение.

Код, которы й запускается по истечен и и срока действия тайм ера, зависит только от вашего ж елания. Это мож ет быть один оператор, набор операторов (каждый из которы х 1 заверш ается точкой с запятой), refreshO; setTimeout(refresh. и даже вызов встроенного или пользовательского метода. Обновить ст раницу. alert («П росьш ай ся !»)

П осле заверш ения отсчета тайм ер запускает код JavaScript и исчезает. М ожно создать таймер, которы й будет запу­ скать код ч ерез определенны е промеж утки времени, пока вы его не остановите. Н о в данном случае нам потребуется одноразовы й таймер. ~ \

ш нгнт

Совместите одинаковые показатели.

500 мс

5 минут

300 ООО мс

5 секунд

5000 мс

1/2 секунды

далее >

123


времени мало, дейст вуй сейчас

Вот как соотносятся различные записи.

п^ражнение решение

500 мс

5 минут

300 ООО мс

5 секунд

5000 мс

1/2 секунды

Метод setTimeoutO в Jav aS crip t о д н о р а зо в ы е т а й м е р ы запускаю тся п р и пом ощ и в с т р о е н н о г о м ето д а s e t T i m e o u t {). Д л я его р а б о т ы вам нуж но указать в р ем я зад ер ж ки и код, к о т о р ы й следует зап усти ть (до­ ступен п о адресу http://www.headfirstlabs.com/books/hfsd/). Р ассм о­ т р и м н е б о л ьш о й п р и м ер :

М етод setTimeoLit( ) уст анавливает одно­ крат ны й т аймер.

равняет ся <ьоо с е к З ^ ^ ' м и н ут а м 6 0 0 0 0 0 );

s e t T i m e o u t (" a l e r t ('Wake

НикогЭд не от деляйт е разряды даже при н а -

КоЭ JavaScript, к о т о ­ рый следует вы п о лн и т ь. по т а й м ер у, передает ­ ся м ет оду setTim eoutQ в виде т екст овой ст роки. Вот почему он помеш,ен в кавычки.

После завершения от счет а появляет ся окно с сообщением.

Ч и С ^ Т '^

В д ан н о м случае м етод s e t T i m e o u t () со зд ает т ай м е р , к о т о р ы й ч е р е з 10 м инут в ы зы в а е т о кн о с сообп 1;ением. 6С>С> ООО

миллисекунд! за д е р ж к а 10 м и н у . Wake up!

І 124

глава 3


знакомство с браузером

Анализ метода setTimeout() В от си н так си с м ето д а setTimeout ():

Заклю чает в себя ода аргум ент а

setTimeout

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

Разделяет аргум ент ы . Задержка в м иллисекундах-

Заверш ает операт ор.

З ад а н и е та й м е р а , ср аб аты в аю щ его ч е р е з о п р е д е л ен н ы е пром еж утки вр е м ен и , осу щ ествл яется с пом ощ ью м ето д а set Interval {). Его си н ­ такси с ан а л о ги ч е н преды дущ ему. В р езу л ьтате о д и н и т о т ж е код будет запускаться м н о го раз:

var timerlD = setlnterval :" a l e r t ('Wake u p !') Т У ст анавливает Хранимый о т повт оряющ ийся делш о и д ен т и ф икат ор т а й т аймер. XO м инут .

I Wake up!

n o м инут . 1 - г

~~^iO м инут .

Wake up!

t-O м и н у т

Wake up! М ногократный ' т а йм ер запускает код через указанный вами промеж ут ок _ времени.

Wake up!

р с . 9,1.3

бООООО)

р а д ь те о с т о р 'о ж н

М инут ы в м и лл и се к у н ­ дах.

ы1

Задержка таймера указывается в миллисе­ кундах.

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

Возьми 8 руку карандаш Создайте свою версию файла irock.htm l и п р о ­ т ест и р уй т е свой вариант — кода перед т ем , как перевернут ь ст раницу.

Напишите код, меняющий после 5 минут изображение объекта iRock со счастливого на одинокое. Подсказка: идентификатор изображения элемента iRock называется rocklmg, а файл с изображением одино­ чества — rock.png.*

* Э т от ф айл находится по адресу k t t p : / / w w w .kea d firstla b s.co m /b o o ks/kfjs/

далее >>

125


решение упражнения

возьми в руку карандаш

Решение

Вот как выглядит код, меняющий через 5 минут изображение камешка со счастливого на одинокое.

Кавычки и а п о ст р о ф ы ^

позволяют о с у щ е с т в и т ь к о р р е к т н о е влож ение м ет одов.

Л

^^^Т'!^УУ?:9}^Ж!!^Р^!^'^^пЬ.^еЬЕ{етен±Ву1с1^госк1тд‘).5гс = 'г о с к .р п д ';",

.. .5.*. . Ш м и л л и L-CKyИJ^, с е к у н д ^ /' гД ,л я 'перевода ив /V^iЛ/\/Ш оы п я т и м и н у т н о й' за д’ е р ж ки ....... сначала н у ж н о п р е о б р а зо в а т ь все в м и н у т ы (х& О ), з а т е м о м и л л и с е к у н д ы ( х ± 0 0 0 ).

ХРР.а);............ . Л ...................................................... ^

Л

(

Замена изображения (Я оск о сущ е ст в л я е т ся п о д с т а н о вко й нового граф ического ф айла в а т р и б у т $гс.

Идентификатор •изображения.

Изображе­ ние кйМешка., кот ором у одиноко.

Теперь îRock чуВстВуеш одиночестВо! Н е забудьте в н е с т и вы ш еу казан н ы е и зм е н ен и я в ф ай л i r o c k . h tm l и п р о в е р ь т е , как все р а б о т а е т . О б ъ е к т iR ock д о л ж ен д ем о н с т р и р о в ат ь о д и н о ч е с тв о , есл и в т е ч е н и е п я т и м инут н а н ем н и разу н е ш;елкнул п о л ьзо в ател ь. Н еб о л ьш ая в р е м е н н а я за д ер ж к а м о ж ет п р и в е с т и к тому, ч т о кам еш ек п о к а ж е тся вам ч ер есч у р т р е б о в а т ел ь н ы м , н о ведь мы и х о ­ т е л и все в р е м я д ер ж а ть п о л ь зо в а т е л я зан яты м . К ак будто рядом с ни м д ей с тв и те л ь н о ж и в о е суш;ество со св о и м и нуж дами. Т а й м е р ведет о б р а т н ы й о т счет «счаст ливого о р е м е н и » о б ъ е кт а ÎRock.

п оДсказка

М имолетность сча ст ливого с о ­ ст о я н и я сделала объект iRock более живым.

126

глава 3

Ускорить смену эмоциональных состояний объекта можно, умень­ шив задержку вызова метода s e t T i m e o u t () . Это позволит протестировать сценарий без долгих ожиданий.


знакомство с браузером

П ользователи бы ли правы . С б о л ь ш и м к о ­ л и ч е с т в о м э м о ц и й 1Роск бо л е е п р и в л е ка те л е н .

Таймер заверш ил работ а и счаст ье сменилось на одиночество.

_

Ч асто

<аДаБаеМые Б о г1|= »ос:ь1 Если объект іРоск должен пере­ ходить в одинокое состояние через каждые 5 минут, почему не задать для него временной интервал? ! Дело в том, что периодическое ощущение одиночества нашего объекта

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

Можно ли создать таймер, кото­ рый будет запускать код в определен­ ное время? ! Таймеры не пользуются абсолютным временем, поэтому для выполнения по­ добной задачи нужно вычислить задерж­ ку, вычтя текущее время из желаемого времени срабатывания. Эти подсчеты выполняются при помощи объекта D a te , с которым вы познакомитесь в главе 9. Данные на моей странице часто редактируются, поэтому я хотел бы обновлять ее каждые 15 минут. Как это сделать?

Как остановить таймер, срабаты­ вающий через заданные промежутки времени? ! Для прекращения работы таймера, запущенного методом s e t l n t e r v a l ( ) , используется метод

Что произойдет, если закрыть браузер до завершения обратного отсчета?

! С помощью метода s e t l n t e r v a l О установите таймер на 15 минут, то есть на 900 ООО миллисе­ кунд (15 X 60 X 1000). Обновление стра­

0 ; Ничего. Интерпретатор иауаЗспр! при этом прекращает свою работу, и все сценарии иауаЗспр!, в том числе и таймер, завершаются.

ницы реализуется методом r e l o a d {) объекта l o c a t i o n вот таким образом: lo c a t io n . r e lo a d ( ) ; Можно также воспользоваться техноло­

c l e a r I n t e r v a l ( ) . Ему следует передать идентификатор останавливае­ мого таймера, который возвращает метод s e t l n t e r v a l ( ) . Сохранив возвра­ щенное значение, например, под именем t i m e r ID , передайте его методу c l e a r l n t e r v a l ( ) вот таким обра­ зом: c l e a r l n t e r v a l ( t i m e r l D ) .

гией Ajax, с которой вы познакомитесь в главе 12, для динамической загрузки данных.

далее ►

127


браузер в открытом доступе

В Р А У З Ё Р

О' c B B te

Интервью недели: П р и з н а н и я в е б -к л и е н т а

Head First: С паси бо , ч то , н е с м о т р я н а за н я т о сть, наш л и в р е м я и заш ли к нам в гости .

Head First: Д а, вы п р авы . Т ак ч т о ж е эт о т ак о е — б ы ть веб-клиентом ?

Браузер: Д а, я к р а й н е зан ят. К ак будто м ало м н е б ы ло H T M L и CSS и св я за н н ы х с н и м и о с о б е н н о с т е й ви зу ал и зац и и с т р ан и ц , т е п е р ь м не п р и х о д и тс я и м е т ь д ел о еш;е и с Jav aS crip t. Э то совсем другой зв ер ь.

Браузер: Э то зн а ч и т б ы ть принимаю ш ;им ко н ц о м кан ала до ставки веб-стран и ц , зап р о ш ен н ы х с сер в ер а.

Head First: Ч т о вы и м е е т е в виду? Jav aS crip t д и к и н еп р и р у чен ?

Браузер: К о н е ч н о , н ет. Я у п о тр е б и л сл ово «зверь» в п е р е н о с н о м см ы сле. Я всего л и ш ь им ел в виду н о в ы е п р о б л ем ы , к о т о р ы е п о я в и л и сь вм есте с Jav aS crip t. Я д о л ж ен ч и т а т ь эт о т код, м олясь, ч то б ы о н бы л н а п и с а н к о р р е к т н о , а п о то м запускать его, н е заб ы в ая п р и это м п р о H T M L и CSS.

Head First: И как вы справл яетесь? Браузер: К счастью , эт и т р и суш,ности п р е к р а сн о р аб о т а ю т вм есте, х о т я и н о гд а Jav aS crip t ш алит и и ск аж ает H T M L -код. П р о б л е м а в то м , ч то я н и как н е могу н а эт о п о в л и я ть . В едь я всего л и ш ь делаю то , ч т о м не п р и к а зы в а ю т делать. Head First: Т о е с ть вы скл о н н ы к п о д чи н ен и ю ? Браузер: М ож н о сказать и так, н о б о л ее т о ч н ы м будет п р и зн а т ь , ч т о б ольш е всего я цен ю взаи м о д ей ств и е. М оя зад ач а б р ат ь код, к о т о р ы й о т д а е т м не с е р в е р , и п оступ ать с ни м так, как м не п р и казы в аю т. Head First: Д аж е если код я в л я е т с я ош иб о чн ы м ? Браузер: Я стар аю сь р е ш а т ь п р о б л ем ы , когда виж у их, н о эт о т я ж е л ая р аб о та. К р о м е то го , это те м а для другого обсуж ден ия (из гл авы 11). А п о к а д ав ай те п о го в о р и м о м о ей р а б о т е в ка ч е с тв е веб ­ к л и ен та.

128

глава 3

Head First: А как эт о св я зан о с JavaScript? Браузер: О ч е н ь тесн о . Я вы п о л н я ю всю работу по о т о б р аж ен и ю ст р а н и ц и о б р аб о т к е ввод и м ы х п о л ьзо в ат ел ям и д ан ны х. A Jav aS crip t в эт о вр ем я во все сует свой н о с и в н о си т и зм е н ен и я . Х о тя все н е т ак плохо. М н о ги е вещ и я н и ко гд а н е см ог бы сдел ать сам о сто я тел ь н о . Head First: Н а п р и м ер ? Браузер: Ну, я бы н е сделал н и ч его о со б е н н о го в ситуации , когда п о л ьзо в ат ел ь н аво д и т указатель м ы ш и н а и зо б р а ж е н и е и л и м е н я е т м ой р азм ер. A Jav aS crip t п о зв о л я е т легко п о м ен я т ь вид с т р ан и ц ы в о т в е т н а д ей ств и я п о л ьзо в ател я. Я не возр аж аю , т а к как код Jav aS crip t запускается на с т р а н и ц е и н а о с н о в е ст р ан и ц ы и в л и я е т то л ь к о н а саму стран ицу. Head First: Вы г о в о р и т е п р о Jav aS crip t как п р о чуж еродную сущ ность. Н о р а зв е это н е ч ас т ь вас? Браузер: Д а, Jav a S crip t о п р ед ел ен н о я в л я е т с я частью м ен я, н о его м ож н о во сп р и н и м а т ь и как с т о р о н н ю ю сущ ность, т а к как доступ к кл и ен ту (ко м не) о н осущ ествл яет п о ср ед ств о м о г р а н и ч е н н о г о и н т е р ф е й с а . Т о есть я н е даю Jav aS crip t н е о г р а н и ч е н н о г о д оступа ко всему. Э то б ы л о бы н е о с т о р о ж н о , ведь я н е знаю , кто н ап и сал с ц е н а р и й и п о п р о с и л м ен я зап усти ть его. Head First: П о н я т н о . С паси бо, ч т о п о д ел и л и сь с н ам и п о д р о б н о с тя м и ж и зн и к л и ен та. Browser: Рад, ч т о см ог вам пом очь.


знакомство с браузером

Зависимость о т размера экрана Т о л ьк о А лен успел о б р ад о в аться новом у д и ап азо н у эм о ц и й о б ъ е к т а 1Коск, как к о м п ан и ю зах лестн ула н о в а я в о л н а п о л ь зо в а тел ьс к и х ж алоб. О казы ва­ ется, р а зм е р о б ъ е к т а н е о ч е н ь стаб и л ен . Н е к о т о р ы е п о л ь зо в а т ел и ж алую т­ ся н а «син дром сх л о п ы в ан и я» , в т о в р е м я как другие и сп ы т ал и стр ах п ер ед «гигантски м кам нем ». А лен д о в е р я е т т о л ь к о вам , т ак ч т о п р и ш л о вр ем я ' с н о в а п р и в е с т и 1Коск в п о р я д о к.

Н е ко т о р ы е п о льзо ва т е ли го в о р я т , ч т о не м о г у т X т о л к о м р а згл я д е т ь о б ъ ­ е к т /Rock. /\р у г и е видят т о л ь ко ч а с т ь г и га н т ско го ка м н я .

ГШ ТУРМ Почему в разных браузерах камешек имеет разный размер?

далее >

129


размер имеет значение

Ширина окна браузера В о зн и кш ая п р о б л ем а св я за н а с тем , ч т о р а зм е р о б ъ е к та 1Коск н е м ен я е тс я вм есте с р а зм е р о м о к н а б раузера. М о­ ж е т п о к азаться, ч то это х о р о ш о , есл и н е у ч и ты вать, ч то п о л ьзо в а т е л ь м о ж ет зах о д и ть в И н т е р н е т как с м о б и л ьн о го у стр о й ств а, т а к и с н а с т о л ьн о го к о м п ью т е р а с ги ган тски м м о н и то р о м . З н а ч и т , вам следует за р а н е е о п р е д е л и т ь ш и р и ­ ну о к н а и с о о т в ет с т в е н н о о т р е д а к т и р о в а т ь р а зм е р наш его кам еш ка. И зо б р а ж е н и е к а м е ш к а п оявляет ся в к л и е н т с к о й ч а с т и о кн а б р а узе р а , и, следоват ельно, и м е н н о его п а р а м е ­ т р ы н у ж н о и с п о л ь зо в а т ь для и з м е н е ­ ний р а з м е р о в о б ъ е кт а 1Коск. ,Носк - ТЬе

Клиентской называется та часть окна браузера, в которой отображается веб-страница.

Ре1 йрск ...

в о а

Г

. docшnent. Ьос1у.с11еп'ЬНе1дЬЬ В ы со т а .к л и е н т с к о г о окна.

Не о т н о с и т с я к вы сот е к л и ­ ент ской т е т и окна.

<1осшпвпЪ.Ьо<1у ■с 1 1 епЪ» 1 (1ЪЬ

................... .

Ш ирина окна кл и е н т а .

130

глава 3

В аж н о о т л и ч а т ь ш и р и н у и вы соту к л и ен тс к о й ч асти о т обш;ей ш и р и н ы и вы с о ты о к н а б раузера. О кн ом к л и ен та сч и тае тся т о л ь к о т а ч асть, в к о т о р о й о т о б р аж ает ся веб-страни ца. С тр о к а заго л о вка, п а н ел и и н стр у м ен то в и с т р о к а с о с то я н и я сю да уже не входят. Р а зм е р о б ъ е к т а 1Коск вы ч и с л яе т ся , и сход я и з р а зм ер о в к л и ен тск о й части.


знакомство с браузером docioment

Задание ширины окна

О б ъ е к т d o c ijrn e p i п р е д с т а в л я е т собой в е б -с т р а н и ц у .

Р азм ер к л и ен тск о го о к н а п л о т н о связан с веб -стр ан и ц ей , доступ к к о т о р о й в Jav aS crip t осущ ествл яется п р и п ом о щ и о б ъ е к т а document. И м е н н о эт о т о б ъ е к т давал вам доступ к эл ем ен там ст р а н и ц ы в м ето д е

<html> <head> < t i t l e > i R o c k - The V i r t u a l P e t R o c k < / t i t l e > < s c r i p t t y p e = " t e x t / j a v a s c r i p t "> v a r userName; function greetUserO { a l e r t ( ' H e l l o , I am y o u r p e t r o c k . ' ) ; 1

f u n c t i o n touchRockO { i f (userName) { a l e r t ( " I lik e the a tte n tio n ,

getElementByld().

else { userName = p r o mp t ( " Wh a t i s y o u r name? ", " E n t e r y o u r name h e r e . " ) , i f (userName) a l e r t C ' I t i s good t o me e t you, " + userName + " . " ) ;

С вой ства

body.clientWidth и body.clientHeight д окум ента со д ер ж ат инф орм ацию о ш ирине и в ы с о те кл и ен тск о го окн а.

Тело документа у\р& 3см й8ля&т с о ­ бой б и З и м у ю мастер cm pam vp^> в кл ю ча я ш и р и н у ы вы сот у кл и е н т ско го окна.

" + userName + ". Thank y o u . " ) ;

}

}

document.getElementByld("rocklm g").src = "rock_happy.png"; s e t T i m e o u t (" d o c u m e n t . g e t E l e m e n t B y l d ( ' r o c k l m g ' ) . s r c = ' r o c k . p n g ' ; " , 5 * 60 * 1 0 0 0 ) ; }

</script> </ he a d > <body o n l o a d = " g r e e t U s e r 0 ; " > <div styl e= "m ar gi n- top :l OO px; t e x t - a l i g n : ce n te r"> <img i d = " r o c k I m g " s r c = " r o c k . p n g " a l t = " i R o c k " s t y l e = " c u r s o r : p o i n t e r " o n c l i c k = " t o u c h R o c k ( ) ; " /> J </div> </ body> </html>

4aca»o З ад авае м ы е

^

^ o "Hf j= o >eo C b l' B

^ !И |все-таки, чем различаются веб-клиент, браузер, окно клие клиента и окно браузера?

Почему мы собираемся менять размер объекта 1Коск именно в зависимости от размера окна клиента?

! Да, запутаться тут легко. С глобальной точки зрения браузер является веб-клиентом, так как при обслуживании веб-страниц он находится на стороне клиента. Если же рассмотреть браузер, слово «клиент» уже будет относиться к области, в которой появ­ ляется веб-страница. Так что окном клиента называется область

0:,

; Именно от размеров окна клиента зависит, какую часть пространства будет занимать отображаемый объект. Осталь­ ные элементы браузера, например дополнительные панели инструментов, крайне сложно учесть из-за их разнообразия при переходе от одной платформы к другой. К примеру, при одина­

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

ковом размере окна клиента размер браузера Safari в Мае будет отличаться от размера браузера Firefox в Windows.

О

далее >

131


насколько велико большое?

Высота и ширина объекта iRock З н а н и е р а зм е р о в кл и ен тс к о го о к н а н е п о м о ж ет вам б ез в о зм о ж н о с ти м ен я ть р а зм е р и зо б р а ж е н и я о б ъ е к т а iRock. К счастью , Jav aS crip t вм есте с CSS п о ­ зв о л я ю т это д елать. С в о й ств а w i d t h и h e i g h t и зо б р а ж е н и я даю т н е то л ь к о и н ф о р м а ц и ю о р а зм е р е о б ъ екта, н о и в о зм о ж н о с ть его д и н а м и ч е ск и м ен ять.

style, h e i g h t ^

Высота

изображ ения.

s ty le .w id th Ш и р и н а L-----

Д л я каж дого эл ем е н та с т р а н и ц ы сущ ествует о б ъ е к т s t y l e , п о зв о л я ­ ю щ и й узн ать ге о м е т р и ч е с к и е р а зм е р ы эт о го эл ем ен та. С н ач ал а вам п о тр еб у ется доступ к сам ом у элем енту, т о есть к к а р т и н к е с кам еш ­ ком . К ак вы уже зн а е те , для это го нуж ен м етод g e t E l e m e n t B y l d () о б ъ е к т а d o c u m e n t:

К о д Н ТМ и карт инки с к а м н е м дает ва м дост уп к свойст вам с т и л я изображ ения.

<img id="rockImg" s r c ="rock.png" alt="iRock"

/

d o c u m e n t .getEl e m e n t B y l d ("rocklmg").s t y l e .height

Д л я и зм е н ен и я р а зм е р о в о б ъ е к т а iR o ck д о с т а т о ч н о п о м е н я т ь зн а­ ч е н и я соответству ю щ и х сво й ств. Т о ч н е е , вы м о ж ете о гр ан и ч и т ь с я р е д а к ти р о в а н и е м т о л ь к о о д н о го сво й ств а. В т о р о е и зм е н и т с я авто ­ м ати ч еск и , ч то б ы с о х р а н и т ь п р о п о р ц и и и зо б р аж е н и я :

Э т о т ко З п о з в о л я е т „ з н а т е - в ы с о т у «зо

Ъражтия камешка.

С делайт е вы со т у и зо б р а ж е н и я р а вн о й 1 0 0 пикселам .

d o c u m e n t .getElementByld("rocklmg").s t y l e .height = "lOOpx";

132

глава 3

данный 6 coo

... />


знакомство с браузером

^Rock доА)кен соошбетсшВоВать странице П о к а ч т о р а зм е р и зо б р а ж е н и я кам еш ка н и к а к н е свя зан с р а зм е р о м о кн а к л и ен та , в то в р е м я как о н д о л ж ен м е н я т ь с я п р о п о р ц и о н а л ь н о ему. П усть его р а зм е р со с та в л я е т о п р е д е л е н н ы й п р о ц е н т о т р а зм е р а окна. К а к о е и з и зм е р е н и й следует в ы б р ат ь д ля п р и в язк и ? Т ак как п о в е р т и к а л и б раузер ы им ею т б о льш и е о г р а н и ч е н и я , и м е е т см ы сл в ы б и р а ть р азм е р кам ­ н я в за в и с и м о с т и о т в ы с о ты ви д и м о й области.

Высота окна кл и ен та.

(clientWindowHeight - 100) * 0.9 = госк1тадеНе±дЬй

% от. того, что остается по в е р т и ка л и .

М ы уч и ты ваем пустое п р о с т р а н с т в о сверху над кам еш ком (100 п и к се л о в ), а затем ум еньш аем и зо б р а ж е н и е н а 90 % от о став ш ей ся в ы со ты кл и ен тск о го окн а. Ф орм ула для п о д о б н ы х р а с ч е т о в о б ы ч н о п о д б и р ае тс я м етод ом п р о б и ош ибок. Вам следует п о см о т р е ть , как будет в р езу л ьтате вы гл яд еть 1Коск, но

далее ►

133


решение упражнения ^ В о з ь м и

В р у ку каранд аш

Решение

Вот как выглядит код метода resizeRock () и код обра­ ботчика события onload, вызывающего этот метод.

Р азм ер и зо бр а ж е н и я кам еш ка в ы числ я ем ­ ся на основе вы сот ы кл и е н т с ко г о окна.

IP к а р т и н к и с к а м е ш к о м и с п о л м у е т с й для д о с т у п а к элем ент у.

function resizeRock О {

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

В ы ч т и т е 1 -0 0 п и ксе л о в для от ст упа от верхней границы о кн а кл и е н т а .

КЛЮЧЕВЫЕ МОМЕНТЫ

ш

Метод setTimeout () создает однократный таймер, который после завершения отсчета запуска­ ет код JavaScript.

Таймер, срабатывающий через заданные промежутки времени, создается методом setlnterval ().

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

134

глава 3

Объект style элементов веб-страницы задает их свойства, например, width и height. Окном клиента называется часть окна браузера, в котором отображается веб-страница. Информация о ширине и высоте окна клиента содер­ жится в свойствах body.clientWidth и body. clientHeight объекта document.


знакомство с браузером

îRock эволюционирует!I Т е п е р ь о б ъ ек т iR ock ад ап ти р у ется к браузеру п о л ьзо в ател я. Н е забудьте о б н о в и т ь ф а й л iRock.html (его м о ж н о с к а ч а ть по адресу http://www.headfirstlabs.com/books/hfjs/) и п р о ­ т е с т и р о в а т ь его в н еск о л ьк и х б р ау зер ах п р и р а зн ы х р а зр е ш е н и я х эк р ан а. Вы м о ж ете п о ­ п р о б о в а ть зап у сти ть его даж е н а iP h o n e! Т еп е р ь р а з м е р кам еш ка м е н я е т ­ ся в з а в и с и м о с т и о т р а з м е р о в о кн а браузера.

П о л ь зо в а т ел и б ольш е н е п р и с ы л а ю т ж ал об , и А лен го то в дать вам п р ем и ю . В се счастл и вы ... п о к а счастл и вы . часзв°

ЛаДаБаеМые

-

БоЦ роСЬ!

• Я так И не понял, зачем нужно было вычитать 100 пикселов. : Код HTML/CSS для объекта iRock по­ мещает его изображение на 100 пикселов ниже верхней границы страницы, чтобы

Свойства width и height CSS-стиля позволяют менять ширину и высоту любого объекта?

Почему не поменять размеры объ­ екта IRock в коде JavaScript в заголовке страницы, не прибегая к событию

onload?

он не прилипал к верху окна. В вычисле­ ниях это смещение на 100 пикселов учи­ тывается до момента нахождения (90 %) от высоты клиентского окна. Подобный отступ нужен только для того, чтобы по­

Q l Практически так. Теперь вы мо­ жете представить, насколько мощным инструментом управления содержимым веб-страницы является JavaScript. В рас­ смотренном случае с его помощью вы смогли узнать размеры окна и на основе этих данных рассчитать размер изображе­

местить камешек на более удачное место

ния объекта.

; Дело в том, что содержимое страницы не загружается до появления события onload. Поэтому если ваш код JavaScript имеет доступ к элементам страницы, как в случае с кодом объекта iRocl<, вы не сможете его запустить, пока не произойдет событие

onload.

в большинстве браузеров.

далее *

135


динамическое изменение размеров

А что происходит при изменении размеров окна браузера? Изображение сохраняет свой размер?

Нет, разм ер ка м е ш ка не является д инам ическим . Н е к о т о р ы е п о л ь зо в ат е л и м огут п о м е н я т ь р а зм е р о кн а б р ау зер а, а о б ъ е к т iR ock п р и этом о с т ан е тс я тем ж е са­ мы м. В едь его р а зм е р о п р ед ел я е т с я п р и п е р в о й загрузке, в м о м ен т с о б ы т и я o n l o a d . П о сл е это го н а вид о б ъ ек т а уже н и ч е г о н е вл и я ет. Т о есть мы верн ул и сь к н аш ей и с­ х о д н о й пр о б л ем е; «ее

1

136

глава 3


знакомство с браузером

Событие 0ПГе5|2е Д ля т о го ч то б ы и зо б р а ж е н и е кам еш ка м о гл о м е н я т ь свой р а зм е р п р и и зм е н е­ н и и р а зм е р о в бр ау зер а, с ц е н а р и ю нуж но д ать п о н я т ь , ч то п р о и зо ш л о т ак о е и зм ен ен и е . Д ля эт о й ц ел и служ ит с о б ы т и е опгез1ге.

Ч т о б ы о т в е т и т ь н а с о б ы т и е опгез1ге, и сп ользуй те код}ауа8спр1 для атр и б у та опгез 12е т ега <Ьо<1у>.


нужно знать, когда менять размер

Возьми в руку карандаш _ г

ч

^

Решение

Какое из этих событий отличается от двух других и почему?

(^ l o a d ^

onresize

onclick

С обы т ия onresize и o n c lic k и н и ц и и р у ю т с я п о л ь зо в а т е л е м , а o n lo a d — нет .

Событие onresize для камешка П р и ш л о в р е м я со зд ать м етод , меняю ш ;ий р а зм е р и зо б р а ж е н и я кам еш ка. Ч т о б ы эт о п р о и с х о д и л о в о т в е т н а и зм е н ен и е р азм е­ р о в бр ау зер а, м ето д resizeRock () д о л ж ен в ы зы в а ться с о б ы т и ­ ем onresize:

В о зн и к а е т п р и и зм е н е н и и р а з м е р о в окн а браузера.

^ В о зн и к а е т п р и пер во й V за г р у зке ст р а н и ц ы .

<body onload="resizeRockО ; g r e e t U s e r ();" onresize="resizeRock();"> ч.

М е т о д ге^1х е к о с к () вы зы вает ся п р и п ервой за г р у зке с т р а н и ц ы , заоаоая начальны е р а з м е р ы н а ­ ш его изображ ения.

\

О т вет о м на событие мож ет с т а т ь выполнение нескольких ф рагм ент ов кода.

Т е п е р ь р а зм е р и зо б р а ж е н и я о б ъ е к т а 1Коск ав т о м ат и ч ес к и ме­ н я е т с я п р и и зм е н е н и и п о л ь зо в ател ем р а зм е р о в о к н а браузера.

Событие опге81ге позволяет распознать изменение раз­ меров окна браузера и от­ реагировать на них. 138

глава 3

Т е п е р ь м е т о д гев1геЯоск() вы зы вает ся еще и п р и л ю д о м и зм е н е н и и р а з м е ­ р о в окн а браузера.


знакомство с браузером

1Воск- ТЬе

5адьш е о С Ш о |^ о Ж Н Ь 1

Будьте аккурат­ ны, меняя размер изобра­ жения при помощи и а у а З с п р !.

Особенно если вы увеличивае­ те маленькую картинку. Ведь при этом ее качество может ухудшиться.

опге81ге!

J a v a S c rip t за с е ка е т изм енение к л и е н т а и д и н а м и ч е с ки м е н я ­ е т с о д е р ж и м о е в е б -с т р а н и ц ы в соот вет ст вии с э т и м и зм е ­ нением .

опге81ге!

(^ ^ (

^ — Ч^ Пользователи будут в восторге от этого. А какие | еще будут идеи? у

А лен чувствует лю б о в ь со с т о р о н ы п о л ь зо в а т ел ей , ведь т е п е р ь о б ъ ек т 1Коск н е в о с п р и и м ч и в к и зм е н ен и я м р азм е­ р о в брау зер о в. 1Коск н е т о л ь к о п о д с тр а и в а ет с я под р азм ер к л и ен тск о го о к н а н а п ер в о м этап е, н о и д и н а м и ч е ск и р еаги р у ет н а лю б ы е его и зм е н ен и я .

далее *

139


временный склероз браузера

Мы у)ке Встречались? П р о б л е м ы с р а зм е р о м о б ъ е к т а 1Коск о то ш л и в п р ош л ое... т е п е р ь реш и м , как б ы ть в ситуациях, когда п о л ь зо в ат е л ь щ ел к ает н а ка­ м еш ке н еск о л ьк о р аз, ч то б ы т о т н е чувствовал себ я од и н о к и м , и ли в о зв р а щ ае т с я н а стр ан и ц у с кам еш ком п о сл е п ер езагр у зк и своего ком п ью тер а.

Почему ты меня не помнишь? Я не произвел на тебя впечатления?

15 уоиг п ате?

Л ю и л е р б о М ЗН йКО М С тбе Л йм еш кол л

вводит свое им я.

О о б ъ е к т !Я о ск о т в е ч а ­ е т п е р со н а л и зи р о в а н н ы м п р и в е т с т в и е м — дюцжба началась!

It is good to meet you, Paul. ■

Г ~ о к ~ Щ

What

15

уоиг п ате? -«£г

...ка м е ш е к у ж е не поаан и т п ользоват еля.

^

У

Х о тя 1Коск и в с т р еч ал с я со своим х о зя и н о м н е ­ к о т о р о е в р ем я назад, о н заб ы л его им я...

140

глава 3


знакомство с браузером

Время )кизни сценария П о т е р я п ам яти о б ъ е к т а 1Коск св я за н а с в р ем ен ем ж и зн и сц е н а р и я , о т к о т о р о г о за в и с и т, как и е и м е н н о д ан н ы е х р а н я т с я в и сп ользуем ы х п ер ем ен н ы х . В р а у зе р за г р у ж е н , а в о т с т р а н и ц а еще нет . П ользоват ели) н у ж н о у к а з а т ь ее

- ■--- •

U R L.

'fock.htm/ С т р а н и ц а за г р у ж е н а с сервера — H T M L , CSS, J a v a S c rip t и все ост альное. -» М ......... ........

При закрытии браузера или перезагрузке страницы onload! JavaScript ликвидирует ВСЕ переменные. После собы т ия o n lo a d п е р е м е н н ы м J a v a S c rip t присваиваю т ся н а ­ чальны е значения.

С иенарш прекращ ает свою работ у, Ja vaScrlpt очищ ает все переменные, и ст раница закрывается.

П ользователь закры вает браузер или перезагруж ает ст раницу,

Ш ТУРМ Как бы вы решили проблему с объектом 1Роск, за­ бывающим имя пользователя?

далее *

141


к — эт о куки

Продление Времени )кизни сценария П р о б л ем а, ко то р у ю м ы и м еем с о б ъ ек то м 1Коск, н азы в ае т ся п о ­ с т о я н с т в о . Т о ч н е е , его о тсутствие. И н о гд а нам треб ую тся д ан н ы е, к о т о р ы е никуда н е и сч езаю т. К с о ж ал ен и ю , п е р е м е н н ы е в Jav aS crip t ж ивут н ед о л го и ун и ч то ж аю тся п р и за к р ы т и и б р ау зер а и л и о б н о вл е­ н и и с тр ан и ц ы . В о зм о ж н о сть с о х р а н и т ь д ан н ы е д ля и сп о л ьзо в ан и я и х даж е п о сл е п р е к р а щ е н и я р а б о т ы с ц е н а р и я р еал и зу ется с п о м о ­ щ ью т е х н о л о г и и ку к и . Э ти м словом н а зы в а е т с я кусок дан н ы х , с о х р а н я е м ы й б раузером н а к о м п ью те р е п о л ьзо в ател я. К уки во м н о го м н ап о м и н а ю т п ер ем ен н ы е Jav aS crip t, н о в о т л и ч и е о т п о сл ед н и х никуда н е и сч езаю т даж е п осл е за к р ы т и я б раузера, п ер езагр у зк и с т р ан и ц ы , вы к л ю ч е н и я ком п ью ­ т е р а и т. п. И м е н н о о н и п ом огут нам с о х р а н и т ь и м я п о л ьзо в ат е л я в с ц е н а р и и iR ock. П ри з а к р ы т и и окн а б р а у з е ­ р а сцен арий за п и с ы в а е т и м я по л ьзо ва т е л я в к у к и .

^

,!.! М?

/.I

*

^ ___“ТНв

•>

П ри сле д ую щ е й з а куки „ именем пользо­ ва т е ля б уде т п р о -

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

Г Ж е с т к и й диск.

142

глава 3

Б р а у зе р с о хр а н яе т к у к и с им енем пользоват е­ ля н а ж е с т к и й ди ск его ^ом пь>ю & ^ера.


знакомство с браузером

Начало!

."EesBa® П ри п е р в о м зн а к о м с т в е п о л ьзо ва т е л я с о б ъ е к т о м 1К о с к и м я п о л ьзо ва т е л я со хр а н яе т ся в п е р е м е н н о й J a v a S c r ip t. .

В р е м е н н ы е п е р е м е н н ы е 5ауа8спр1 зам е ч а те л ь н о сп р а в л я ю тс я с зад ач ей в п р о ц е с с е р а б о т ы с ц е н а р и я , н о , есл и вы х о т и т е и с п о л ь зо в ат ь их зн а ч е н и е и п о сл е текущ ей сесси и , его нуж но с о х р а н и т ь в ви д е куки. в н а ч а л е с ц е н а р и я п р и с в о й т е п е р е м е н н о й зн а ч е н и е , к о т о р о е тр еб у ется с о х р а н и т ь , а затем в м о м ен т за в е р ш е н и я с ц е н а р и я п р и с в о й т е эт о зн а ч е н и е куки.

кймешек м о ж е т uM пользоват ься-

^

iPaul

Конец! «ее

mituii Ы Rocfc


переменная и куки: кт о кого

Беседа у камина Переменная и куки обсуждают важность дли­ тельного хранения данных.

Переменная:

Куки:

я во о б щ е н е п о н и м аю , о ч ем с т о б о й р а з­ го в а р и в а т ь — ты ж е н е и м ееш ь о т н о ш ен и я Т ы п о ч т и п рава. Я в ы п о л н я ю свою работу б ез п ом о щ и Jav aS crip t, н о п р и этом я пом огаю с о х р а н я т ь д ан н ы е с ц е н а р и ев надолго. А как ты , в е р о я т н о , зн аеш ь, Jav aS crip t н е п о зв о л я е т эт о го делать.

к J a v a S c rip t.

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

Я недоступно? Я всегда под рукой, в б раузере, и м огу б ы ть в ы зв ан о в л ю б о й м ом ент.

Д опустим . Н о р а зв е т ы н е ж и в еш ь в тесн о м со сед стве с м н о ж ество м д руги х куки? Д а... и что? Г о в о р я т , ч то о т ы ск а ть к о н к р е т н о е куки к р а й н е слож но... вы ж е х р а н и т е с ь в ви д е о гр о м н о го спи ска. В от ч т о я и м ел а в виду, г о в о р я о т в о е й недо сту п н о сти . Н у да, мы х р ан и м ся в ви д е спи ска, н о все куки и м ею т у н и кал ьн ы е и м ен а, поэтом у о ты ск ать нуж ное н е т а к уж слож но. Д о с та т о ч н о п о ­ н и м ать, как р а зб и т ь сп и со к н а ч асти и н ай ти в нем к о н к р е т н о е имя.

Возьми в руку карандаш, РбШ бН Иб

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

144

глава 3


знакомство с браузером

Переменная:

Куки:

А я в о т н е участвую н и в как и х списках. Д о ­ с т ат о ч н о н азв ать м о е им я... я и тут!

П р и всех св о и х д о ст о и н с тв а х п о с т о я н с т в о не р е ш а е т каж до д н евн ы х пр о б л ем . Если подум ать, то д ал ек о н е все д ан н ы е нуж но со х р а н я т ь надолго. Б о л е е э ф ф е к т и в н о х р а ­ н и ть и х н е к о т о р о е вр ем я, а п о то м , за в ер ш и в работу, удалять. В от тут н а сцену вы хож у я - в р е м е н н а я ср ед а х р а н е н и я для д ан н ы х сц е н а р и я.

В от т о л ь к о в сп о м н и , каким о б р азо м все эти т о в а р ы и зн а ч а л ь н о о к азал и сь в ко р зи н е? Ведь и м ен н о я х р а н ю врем енную и н ф о р м а ­ ци ю о п р ед л агаем ы х то в а р ах . Я в аж н а так ж е, как и ты ... а м о ж ет б ы ть даж е больш е. Д аж е н е с м о т р я н а с т р ем л е н и е б ы ст р о заб ы ­ вать д ан н ы е, с к о т о р ы м и рабо таю .

я п о н я л о ваш у точку зр е н и я . З а т о , когд а во м н е с о х р а н я ю т и н ф о р м а ц и ю , я ее д ей с тв и ­ т е л ь н о зап ом и н аю . Н е важ н о, бы л л и за к р ы т б р ау зер и л и о б н о в л е н а стр ан и ц а. Я вечн о... до т е х п о р , п о к а п о л ьзо в а т ел ь н е р е ш и т п о ­ ч и с т и т ь куки. Н о это уже д ругой во п р о с.

Я все р ав н о убеж ден о, ч т о т ы н ед о о ц ен и в а­ еш ь важ н о сть д о л го в р е м ен н о го х р а н е н и я дан ны х. Р азве н е в о с х и т и т ел ьн о , когд а п о ­ сле д олгого в р е м е н и п о л ьзо в ат ел ь зах о д и т в и н тер н ет-м агази н и ви д и т, ч то все в ы ­ б р ан н ы е им р а н е е т о в а р ы все еш;е н ах о д ятся в его ко р зи н е? И все эт о б л аго д ар я мне.

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

Д умаю , т ы право . М ы р еш аем р а зн ы е зад ач и и д ел и ть нам н еч его . Х о тя д о л ж н а зам ети ть , ч т о я п р е д п о ч и т а ю л е гк и й доступ ко м не в о з­ м о ж н о сти п е р м а н е н тн о го х р а н е н и я дан ны х. А я и сп ы ты в аю у д овольстви е о т м ы сли, что, как т о л ь к о с т р а н и ц а будет п ер евер н у та, вы забудете весь наш р а зго во р . К ак о й разго во р ? Ну, ч т о я говори л о?

далее ►

145


хранение куки на стороне клиента

А почему нельзя хра­ нить долговременные данные на сервере?

Для сохранения небольших ф рагментов инф ормации, например имени пользователя, сервер не нуж ен. Р азум еется, с е р в е р м о ж ет и сп о л ьзо в ат ьс я как д о л го в р е­ м ен н о е х р а н и л и щ е д ан н ы х, н о с к о р о о н о к аж ется п е р е п о л ­ н ен м ал ен ьки м и ф р а гм е н т а м и и н ф о р м а ц и и . С о х р а н ен и е д ан н ы х н а с е р в е р е т р еб у ет р а б о т ы п р о гр ам м и с т о в и сп е­ ц и а л ь н о й ср еды , н а п р и м е р б азы д ан н ы х. Вам н е каж ется, ч то эт о слиш ком б ольш ая р а б о т а для с о х р а н е н и я , н а п р и ­ м ер , и м е н и п о л ь зо в ат ел я в с ц е н а р и и 1Коск? Куки с о х р а н я ю т д ан н ы е н а с т о р о н е кл и ен та, н и к ак н е за т р а ги в а я се р в е р . П р и этом п о л ьзо в а тел ь всегда и м еет в о зм о ж н о с ть удали ть куки со сво его к о м п ью тер а, есл и он р еш и л , ч т о эт а и н ф о р м а ц и я ему больш е н е требуется. Т а­ ко е п р о с т о е уд ален и е д ан н ы х с с е р в е р а н ев о зм о ж н о .

Лауа8спр1

146

глава 3

Долговременное хранение данных на стороне оиента!


знакомство с браузером

CBoucmBa kyku Куки с о х р а н я ю т м ал ен ьк и е ф р а гм е н ­ т ы д ан н ы х под у н и кал ьн ы м и и м ен ам и , п о ч т и к ак п е р е м е н н ы е. Н о , в о т л и ч и е о т п ер ем ен н ы х , у куки есть с р о к х р а н е н и я . П о сл е его д о ст и ж е н и я куки у н и ч то ж аю т­ ся. Т а к ч то куки н е я в л яю тся веч н ы м и , о н и п р о с т о ж ивут н ам н о го дольше п е р е ­ м ен н ы х . М ож н о со зд ать куки, н е им ею ­ щ ие с р о к а х р а н е н и я , н о в это м случае о н и будут, как и п е р е м е н н ы е Jav aS crip t, с т и р а ть ся п о сл е за к р ы т и я браузера.

имя ( Уникальное имя куки.

Значение u s e rN a m e = P a u l

И стекает 3/9/2009

хранения После ист ечения срока х р а ­ нения куки удаляются.

Куки с о х р а н я ю т с я н а к о м п ь ю т е р е п о л ь ­ зо в а т е л я в виде д л и н н о й с т р о к и текста, с в я за н н о й с сай то м (и ли д о м ен о м ). Д руг о т друга о н и о тд ел я ю тся т о ч к о й с за п я ­ т о й (;). И м е н н о э т о т р а зд ел и те л ь д ает во зм о ж н о с ть н а й т и в сп и ск е к о н к р е т ­ н ы й куки.

Зуду

в а м и данные.

,od®

л"»-

С охраненное в к у к и значение

lang = fr_ca И стекает 6/25/2010

cartlD = 1103 И стекает 11/4/2008

ф

ite m i = F lat panel television И стекает 9/3/2008

Ж

'

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

readCookieO

eraseCookieO writeCookie О

далее ►

147


куки при помощи JavaScript

°щоБый к°Д

Если вы не поним ает е смысл написанного, ни­ чего страшного. По мере чтения книги все п о ст е­ пенно ст а нет ясно.

В от код т р е х в сп о м о гател ьн ы х м етод ов, п р е д н а зн ач е н н ы х для ч т е н и я , за п и си и уд ален и я куки. И н о гд а п р ав и л ь н ее — за­ с т ав и ть р а б о т а т ь других. П оэтом у во зьм и те э т о т р е ц е п т (его м о ж н о с к а ч а ть по адресу кир://гтт).кеа(1/гг5иаЬз.сот/ЬооЬ/Ь/]$/) и и сп о льзу й те его для р а б о т ы с куки. f f х р /я н е н и я _^аписы вает -

function writeCookie(name,

//

value,

days)

f e ju d e числа которые должны су щ есі^воват ь куки.

{

no умолчанию к у к и я в л я ю т с я временными,

не имея ср о к а хранени

var expires =

// if

Указав число дней,

вы с д е л а е т е к у к и п о с т о я н н ы м и

(days) { v a r d a t e = new D a t e O ; * cn d a t e . s e tT im e ( d a te .g e tT im e O + ( d a y s * 24 60 60 expires = expires=" + date.toG M TStringO ;

Срок хранения вычисляется '^ре.оёразовани ем числа дней о миллисекунды и добавлением п о ­ лученного чис­ ла к т екущ ем у оремени.

1000));

} // П р и с в о и м куки имя, d o c u m e n t .

значение и срок хранения

c o o k i e = n a me + " = " + v a l u e

+ expires

+

path= /";

}

f u n c t io n readCookie(name) { / / Н а йд е м к о н к р е т н ы й к у к и и в е р н е м v a r s e a r c h N a m e = n a me + v a r cookies = docum ent. c o o k ie . s p l i t ( ' ; ' ) ; f o r ( v a r i= 0 ; і < c o o k i e s . l e n g t h ; І++) { var с = cookies[і]; w h i l e ( c . c h a r A t ( O ) == ' ' ) с = с . s u b s t r i n g (1, с . l e n g t h ) ; i f ( c . i n d e x O f ( s e a r c h N a m e ) == 0) r e tu r n c . s u b s t r i n g (searchN am e.length,

Разделит ель точка с з а ­ пят ой делит список куки на отдельные э к ­ земпляры . c.length)

}

return null; }

fu n c tio n eraseCookie(nam e) { / / Удалим выбранный к у к и - 1) w riteCookie(nam e.

var x;

ЩГ yt

ШтісЬіоп doXOI

} eunctio« doYO

Дая удаления куки достаточно cookie.js

148

глава 3

Создайте пуст ой ф айл с им енем cookie.js и добавьте в него э т о т код.

]

Разрешение .js указы вает , что ф айл содержит т олько код JavaScript.


знакомство с браузером

Код JavaScript ВНЕ Веб-страницы С о х р а н е н н ы й в о т д е л ь н ы й ф а й л код Jav aS crip t тр еб у ется и м п о р т и ­ р о в а т ь н а стран и ц у, для к о т о р о й о н п р е д н а зн а ч е н . С о о т в е тс т в ен ­ но, ф а й л cookie.j s нуж но импортировать на стр ан и ц у iRock.html. Э то р еал и зу ется в теге <script>:

Не забудьт е закры т ь его т&гоАЛ </scn pt> .

<script type="text/javascript" src="cookie. js"X/script>

Для JavaScript знамение

^ м я файла с кодом сценария обычно з а ­ канчивается на

a m p u S y m a t y p e всегда равно text/ja va scrip t.

, д

Д л я и м п о р т а н а стр ан и ц у кода JavaScript и з ф а й л а и сп ользуйте <script>. М н о го к р атн о и сп ользуем ы е сц е н а р и и всегда и м е е т см ы сл п о м ещ ать в о т д ел ьн ы й ф ай л и п о то м п р о с т о им п о р т и р о в а т ь в веб-страницу,

I'Rock h tm l T y ^ e d u m e c t, ч т о ф а й л cookie.js на хо ди т ся в т о й ж е п а п ке . <htinl> ~ <head>

« itle > « o c k

------- — -— .... * " -

а ,

~

------ ---------------------— ....___ __

R o c k < / u t l. >

;< s c r ip t t № e = " S 7 ja v ^ 3 c r ip t : . - - s r c = " ^ ............................. ; .............................................................. ^ ° ° ^ ie o s - - X /s c r ip t> -

......................... f u n c t io n r e s i z e R o c k о i d o c u m e n t. g e tE le m e n f RvTw /(d o c u m e n t.b o d y c l i L f H J У- l e n t H e i g h t - 100)

function greetUserо

ИМпортировансценарий помещается на

. h e ig h t = * 0 .9 ; стрлнмцу загрузке.

ее

I

Как ВЫ считаете, почему многократно используемый код имеет смысл помещать в отдель­ ный файл?

далее ►

149


пользователь хочет к у ш ?

Почему код многократного использования имеет смысл поместить в отдельный файл?

пражнение г 2Ш2НУ12

к й к п р и н е о б хо ди м о ст и его м о ж н о б уд е т легко о т р е д а кт и р о в а т ь .

Приветствие пользователя

u se rN am e = Paul Истекает 3/9/2009

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

Переменная J a v a S c r^ p t.

userName =

Это имя пользователя?

Здесь б уд е т или и м я пользоват еля... или ничего!

П ерсональное привет ст вие

О бщ ая ф о р м а

У

( Hello, I am your p e t rock.

sir«"

150

глава 3


знакомство с браузером

Ц о Д |э о б Н о HJ>o К ° Д -

К ц к и , хранящ ее и н ф о р м а ц и ю и м е н и п о л ьзо ва т е л я, долж но и м е т ь зн а ч и м о е им я. Э т о и з о ^о и т вас о т п у т а н и ц ы , если в б уд ущ е м вы р е ш и т е добавит ь оругие к у к и в данный сценарий.

00

М е т о д g re e tU s e rO о т в е ч а е т за п р и в е т с т в и е пользо ва т е ля п р и перво й за гр узке ст р а н и ц ы .

Э т о не слож ение.

function greetUser ■э т о соединение userName = readCookie ("irock_username" ) ;^ ст рок. if (userName) ^ alert("Hello " + userName + ", I missed you."); else a l e r t ('Hello, I am your pet rock.');

И м я п о льзова т е ля <^итается из кц ки ‘^ ^ Р л н и т с я в п е р е ­ м ен н о й u se rN a m e

Т1ри наличии к у к и с и м е ­ н е м п о л ьзо ва т е л я п о к а ж е м ет. п о т о м у

д

а

Х

1

что

Х

е

«" S

не

а

»

“ ' ’ “'®“ " “

" f '“ -

ф орме.

Memog greetUserl) иа осиоВе kyku Т е п е р ь в м ето д е greetUser {) р а б о т а ю т дуэтом и п е р е м е н н ая , и куки. И м я п о л ьзо в а т е л я ч и т а е т с я и з куки и с о х р а н я е тс я в п е р е ­ м ен н о й . Н о н а т о т ф акт, ч т о и м я с о х р а н е н о в куки, п о л агаться н ел ьзя , в к о н ц е ко н ц о в, с ц е н а р и й м о ж ет запускаться в п е р в ы й раз, зн а ч и т , п о л ь зо в а те л ь ещ е н е указы вал св о и х л и ч н ы х дан н ы х. И м е н н о по это м у в коде п р о в е р я е т с я в о зм о ж н о сть для п е р е м е н ­ н о й по л у ч и ть и м я и з куки, и н а о сн о в е э т о й п р о в е р к и в ы б и р а е тс я нуж ны й т и п п р и в е тс т в и я .

далее ►

151


Ну-ка посмотрим

Создание куки И с п о л ь зо в а т ь куки для н аш его о б ъ е к т а 1Коск —о т л и ч н а я и д ея, н о сн ач а­ л а и х тр еб у ется создать. З а п и с ь куки осущ ествим в м етод е 1 о и с Ь К о с к () , к о т о р ы й в ы зы в а е тс я п р и щ ел ч ке п о л ь зо в а т е л я н а кам еш ке. К ак вы п о м н и т е, эт о т м ето д п р ед л агает п о л ьзо в ател ю вв ес ти его и м я —т е п е р ь о н будет ещ е и за п и с ы в а т ь куки п о сл е вво д а э т о й и н ф о р м а ц и и .

Но

Если и м я не у к а за н о , его

нужно узнать. ли

Если и м я у к а з а н о , п о б л а го д а р и м ш л ь з о в а т е л я за в ним ание.

function touchRockO { ^ if (userName) { ^ alertC'I like the attention, " + userName + ". Thank you."); }

else { userName = prompt("What is your name?", "Enter your name here."); if (userName) { У бедит есь, alert ("It is good to meet you, " + userName + "."); чт о им я writeCookie("irock_username", userName, 5 * 365); введено.

}

K~

^

к

}

document.getfelementByldV"rocklmg") .src\ = "rock_happy.png"; setTimeout ("nocument.getElementByld ('roNcklmg') .src = 'rock, png 5 *

60

*

/OOO)

}

И м я имеет ся, п о ­ эт ому попривет ­ ст вуйт е пользова­ т ел я и за п и ш и т е его данные в к у ки .

И менно эт о им я использует ся при чт ении куки. К у к и не и с п о л ь з у ю т С т и льВ е р блю д а , они больш е н а п о м и н а ю т идент иф икат оры Н ТМ Ь.

И м я пользоват е­ ля за пи сы ва е т ся из пер е м е нно й .

/Г < im g

152

глава 3

id = " r o c k Im g "

s rc = " ro c k .p n g "

С охраним куки с именем п о л ь­ зо ва т е ля на ^ лет . Э т о т м е т о д в ы зы ­ вает ся п р и щ елчке на ка м е ш ке .

o n c lic k = " t o u c h R o c k ( ) ; "

/>


знакомство с браузером

onclick!

П ользоват ель щ & лкает на объ ект е iR o ck

В б о л ьш и н ств е случаев м етод to u c h R o c k () и г р а е т р о л ь, п р о ти во п о л о ж н у ю р о л и м етод а g r e e t U s e r ( ) , по к р а й н е й м ер е, с т о ч к и зр е н и я куки. И м я ввод и тся п о л ьзо вател ем , со­ х р а н я е т с я в п е р е м е н н о й и затем зап и с ы в а ет ся в куки. пользователя известно?

'

Ч

What is your name? Paul

С охраняем и м я п о л ь з о ­ ват еля в пе р е м е н н о й .

userName =

"Paul" З а п и сы ва е м перем енную в к у ки .

М е н я е м изображ ение ч у ё ы п р и в е с т и iR o ck о счаст ливое сост ояние.

It is good to meet you, Paul.

f

далее >

153


руки прочь от куки

Влияние на безопасность

^уд ьш е

Б о л ь ш и н ств о п о л ь зо в а т е л е й о б ъ е к т а 1Коск в в о с т о р ге от та к о го л е к а р с т в а п р о т и в скл ер о за, как куки, н о н е к о т о р ы е и з н и х о за б о ч е н ы в о п р о с о м б езо п асн о сти . Э то п р ав и л ь н ы й во п р о с, так как в куки ч ас т о со х р а н я ю т п е р с о н а л ь н ы е д ан н ы е, х о т я и не ставят под угрозу б езо п асн о сть... по м ен ьш ей м ер е в п л ан е д оступа к х р ан я щ и м ся н а ваш ем к о м п ью тер е уязви ­ мы м д ан ны м . Н о сам и п о себ е куки н е я в л яю тся б езоп асн ы м сп осо б о м х р а н е н и я и н ф о р м а ц и и , п о это м у с о х р а н я т ь с и х п о ­ м ощ ью уязвимые д ан н ы е н е сто и т.

оС Ш ороЖ Н Ь!

То, ЧТО ВЫ можете, не означает, что вы должны.

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

Куки — это всего лишь ф раг­ менты текстовой инф ормации, сохраняемой к вам на ком­ пьютер.

■ Л **

Не являясь исполняемы ми Хотя куки и хранят­ ся на ж естко м диске, они не имею т доступа

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

к остальной хранящ ейся там инф ормации.

; Черви... ф у !

154

глава 3

Куки могут сохранять персональны е данны е, но только после того, ка к пользователь сознательно у ка за л их на веб-странице.


знакомство с браузером Часщо "^ а Д а Б а е М ы е БоП роС ь! То есть куки всегда сохраняются на жесткий диск компьютера? ! Нет. Просто большинство браузеров сохраняет куки именно на жесткий диск, Но при этом есть и браузеры, которые не имеют туда доступа. К примеру, некоторые мобильные устройства используют для этого специальную память. При этом с точки зрения браузера (и сценария) куки помнят присвоенные им значения вне зависимости от того, куда они были сохранены. Как понять, что куки имеют уникальные имена? 0 » Уникальность имени нужна для куки только в пределах рассматриваемой страницы, ведь они сохраняются со ссылкой на нее. Таким образом, эффективной частью имени куки является название страницы, что гарантирует его уникальность.

J'

Куки сохраняются для всех

браузеров? Q * Нет. Каждый браузер имеет свою, уникальную базу куки. То есть куки, созданные в Internet Explorer, не будут видимы в Firefox или Opera. Имея куки, зачем вообще сохранять данные на сервер? Q * Ну, во-первых, куки позволяют сохранять только относительно небольшие (менее 4 Кбайт) фрагменты текста. Это одно из их самых больших ограничений. Кроме того, куки недостаточно эффективны, и вряд ли вы захотите постоянно записывать и читать оттуда данные. Для подобных целей обычно используются базы данных, которые находятся именно на серверах. Несмотря на то что куки прекрасно подходят для сохранения небольших фрагментов информации, которые необязательно помещать в базу на сервере, они не помогут вам в случаях с другими видами данных. Также их не стоит применять для сохранения уязвимых данных, так как это небезопасно.

Можно ли создавать действительно вечные куки? 0 » Нет. Нравится вам это или нет, все куки имеют срок действия. Они предназначены для достаточно длительного хранения данных, но никто не предполагал использовать их в качестве вечного хранилища. Куки хранят данные дни, недели, месяцы. Для более длительного хранения данные стоит поместить на сервер. Нет, куки тоже потенциально могут хранить данные годами, но пользователи обновляют компьютеры, переустанавливают браузеры и т. п. Какие недостатки есть у хранения кода иауаЗспр! во внешнем файле? 0 » Недостатков нет. Просто следует помнить, что целью сохранения сценария во внешний файл является доступ к нему из нескольких источников. Если ваш сценарий появляется всего на одной странице, нет никакого смысла сохранять его во внешний файл. Ну разве что только в случаях, когда код выглядит запутанным и вы хотите упростить его, распределив сценарии по отдельным файлам.

КЛЮ ЧЕВЫЕ МОМЕНТЫ Куки — это фрагменты текстовых данных, которые браузер сохраняет на компьютер пользователя.

Поместив сценарий во внешний файл, вы сделаете его доступным для других страниц.

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

Куки не имеют доступа к жесткому диску пользо­ вателя и не распространяют вирусы, они просто сохраняют введенные пользователем на страницу персональные данные.

Все куки имеют срок хранения, после истечения которого они уничтожаются браузером.

далее *

155


вам куки не положены

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

Уменьшение количе­ ства пользователей — это недопустимо.

Проблема!

+

Неработающи( К счастью , б р ау зер ы могут п р о в е р я т ь д о сту п н ость куки. С во й ств о cookieEnabled п р и н а д л е ж и т об ъекту navigator, п ред о ставл яю щ ем у Jav aS crip t и н ф о р м а ц и ю о б раузере.

navigator.cookieEnabled Если к у к и дост упны J ж изнь п р е ­ красна.

156

глава 3

tru e

false

Вы не м о ж е т е чит ат ь и за­ писы ват ь к у к и , если к ним н е т дост у>лл.


знакомство с браузером

возьми в руку карандаш Напишите недостающий код для проверки доступности куки в методах greetUser {) и touchRock {). В метод touchRock () также добавьте код, сообщающий пользовате­ лю о недоступности куки.

function greetUserо

{

userName - readCookie{"irock_username"); if (userName) alert ("Hello " + userName -i- ", I missed you ")• else alert ('Hello,

I am your pet rock.');

)

function touchRockO if (userName) {

{

^ alert ("I like the attention,

" + userName + ". Thank you.");

else {

alert ("It IS good to meet you, " + userName + ".");

writeCookie ("irock_username", userName, 5 * Зб'ь')"-" else

d o c u m e n t . g e t E l e m e n t B y l d ( " r o c k l m g " ) . s r c = " r o c k h a p p y .p n g " s e t T i m e o u t ( - 'd o c u m e n t . g e t E l e m e n t B y l d ( 'r o c k l m g ') . s r c = ' r o c k , p n g ' ;

далее >

157


решение упражнения

возьми в руку карандаш_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ^бШ бНИб

должен выглядеть код, проверяющий поддержку куки для методов greetUser () и touchRock (), а также код для второго метода, дающий пользователю понять, что куки недоступны.

Если куки поддерж иваю т сяпрочит айт е имя пользоват еля из куки iRock. function greetUserО

{

if (navigator.cookieEnableo userName = readCookie("irock_username"); if (userName) alert("Hello " + userName + ", I missed you."); else alert('Hello, I am your pet rock.'); }

function touchRockO { if (userName) { alert("I like the attention, " + userName + ". Thank you ")• }

else { userName = prompt("What is your name?", "Enter your name here."); if (userName) { r-,, 1 4- /МТ4- ■ , Если куки поддерalert( It is good to meet you, " + userName + "."); ж иваются, за п и ...— — ---------— -----uAume куки с uMi if (n a vig a to r.co o kieE n a b lec^:;--''''''^ кем пользоват е/ writeCookie("irock_username", userName, 5 * 365); else alertC 'Sorry. Cookies a ren ’t sup p o rted /en a b led in uour brow ser I w on’t

}

■f'em-ember -y o u -in te r. ............................................... ■•■ .................. . ............................. . \

J

/\a u m e пользоват елю знат ь, чт о от сут ст ви е куки ограни-

d o c u m e n t . g e t E l e m e n t B y l d l - r o c k l m g " ) .src - ~

setTimeout("document.getElementByld('rocklmg').src = 'r o c k . p n g , 5 * 60 * 1000); }

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

158

глава 3


знакомство с браузером

ЧэсЗЦо Задаваем ы е БоЦ роС ы Зависит ли поддержка куки от типа или версии браузера?

Q ; Распознавание типа и версии браузера в данном случае ведет к непредска­ зуемым результатам. К сожалению, верить тому, что сообщают о себе браузеры, нельзя. Поэтому, чтобы проверить, поддерживаются ли куки, используйте свойство

navigator.cookieEnabled.

Разговор с пользователями... это лучше, чем ничего Е сли куки н едоступ ны , и с п р а в и ть ситуацию н ел ьзя. Н о по к р а й ­ н е й м е р е и м е е т см ы сл со о б щ и ть п о л ьзо в ател ям о и м ею щ ей ся п р о б л ем е.

е в 0

iRock - The Virtual Pet Rock

О

Cookies aren't supported/enabied tn your browser, which means I won't remember you later. I'm sorry. Гч"

f

Ален сноба доволен... м п о л у ч м л к е,1Ме,

оЭин чек-

далее *■

159


играем с îRock 2.0

iRock — король иауаЗспр! Вы п р и л о ж и л и м н о ж еств о у силий , со в ер ш ен ству я код сц е­ н а р и я и вн о ся в н его все н ео б х о д и м ы е для успеха о б ъ ек т а 1Яоск и зм е н ен и я . Б л аго д ар я о тзы в ам п о л ь зо в ат ел е й 1Коск п р и о б р е л больш ую эм о ц и о н а л ьн о с ть , в о зм о ж н о с ть м ен я ть сво й р а зм е р и даж е улучш ил пам ять!

Параметры бра­ узера и свой­ ства CSS даю т объекту ÎRock возможность подстраиваться под среду.

Тайм еры расш ирили эм оциональны й д и а­ п а з о н о б ъ е к т а ÎR o c k .

Жмк - Ths Vimalfet «оск

Спасибо за вашу тяжелую работу, !Коск теперь твердокаменный домашний любимец.

u serName = "Paul

160

глава 3

Куки позволяют объекту iRock помнить данны е д аж е после заверш ения сценария.

О


знакомство с браузером

Г

7 ';1

С огни те стран ицу по верти кали , ч тоб ы с о в м е с т и т ь д в а м о зг а и р е ш и т ь задачу. ^

Вкладка Почему JavaScript должен заботиться о клиенте? Ь-- -хо|>оШо, а ДВа ЯуЧШе!

------------------------- -

Клиент — это место запуска кода 1ауа8спр1, то есть Дауа8спр1 связан с браузером. Это хорошая новость, потому что в результате серверу не приходится сохранять 1Ц1«и!


]=ч»няп1ие решений %

^

Если на дороге развилка...

Жизнь неотделима от принятия решений. Стоять или

идти, пойти на сделку с негодяем или пойти в суд... Результата невозможно добиться без выбора. То же самое происходит в иауаЗспр1 — вам приходится выбирать между различными вариантами сценария. Приходится то и дело при­ нимать р е ш е н и я - Стоит ли поверить данным, введенным пользователем, и отправить его охотиться на львов? Или же проверить еще раз, может быть, он всего лишь пытался заказать билет до Львова? Выбор за вами!


выбери меня

Счастливчик, спускайся ко мне! в сего дн яш н ем эп и зо д е зах ваты ваю щ его шоу «Заклю чи м сделку?» мы в ы б ер ем у ч астн и ка, ко то р о м у ул ы б н ется удача.

Удачливый участник Эрмк

В е дущ и й игрового ш оу.

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

164

глава 4


принятие решении

Выбор — это принятие решения Все п р о с то . И м я Э р и к а б ы ло н а п и с а н о н а кар то ч ке! О б р а т и т е вн и м ан и е на то , ч т о ф а к т п р и н я т и я ведущ им р е ш е н и я н а о сн о в е зап и сан н ы х н а ка р т о ч к а х и м ен вы п р и н я л и как д о лж н о е. Ведь о н ч ел о век , а л ю ди ум ею т о б р аб а т ы в ат ь и н ф о р м а ц и ю и п р и н и м а т ь р е ш ен и я . А во т есл и б ы о н бы л сц ен ар и ем ...

В от ведь как о й во п р о с: каки м о б р азо м с ц е н а р и й м о ж е т ис­ п о л ь зо в а ть ф р а гм е н т ы и н ф о р м а ц и и в кач е с тв е о сн о в ы для д ей стви й ? У знать, ч ье и м я п о я в и т с я н а в ы б р а н н о й к ар т о ч к е , — то л ь к о п о л о в и н а дела. А ведь нуж но ещ е и о ц е н и т ь п р о ч и т а н ­ н о е и в ы б р ат ь у ч астн и ка с ан ал о ги ч н ы м им енем .

далее ►

165


если нужно решение

«если» так, то сделай что-нибудь Н а сам ом дел е Jav aS crip t у м еет о б р аб а т ы в ат ь и н ф о р м а ц и ю и п р и н и м а т ь р е ш е н и я и д ел ает это , н а п р и м ер , п р и п ом ощ и оператора . Э то т о п е р а т о р запускает к o д Jav aS crip t по резуль­ татам п р о в е р к и какого-либо условия.

11 (п р о в е р к а

Д е л а е м что-то;

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

П роверим , совпадаю т ли два э л е м е н т а .

Совпадение!

Brie

if (chosenContestant == "Eric") alert("Eric, come on down!"); а „ П р о ве р ка условия бсегт за к л ю ч а е т с я о скобки.

1 I I

/ /

/

конец о п е р а т о р а . п о э т о м у т о ч к а с за п я т о й не ст а в и т с я .

А в о т э т о конец операт ора.

Оператор if запускает \ фрагмент кода по результатам проверки условия. 166

глава 4

_____

Eric, come on down!


принятие решений

Оператор if О п е р а т о р 1 £ всегда и м еет о д и н и т о т ж е си н так ­ сис. Вы уже п о зн а к о м и л и с ь с н и м , д о б ав и в куки к об ъ екту iR ock, н о н а в с я к и й случай сделаем его п о д р о б н ы й анализ:

Э т о т ко д Д О Л Ж Е Н о е р н у т ь значение ~~ triAe или false.

Проверка условия

if

У

а

Оператор

О т с т у п ы о блегча ю т чт ение кода. Н а пи са н н ы й с о т с т и п о м о п е р а т о р являет ся ч а с т ь ю операт ора

В о т ч то следует зн а т ь об о п е р а т о р е i f . В о-первы х, запустить м о ж н о т о л ь к о од и н ф р а гм е н т кода, к о т о р ы й п и ш ется с отсту­ пом сразу под п р о в е р к о й условия. О тступ н е я в л я е т с я о б я за ­ т ел ьн ы м т р е б о в а н и е м , н о о н п о зв о л я е т о п р е д ел и ть, ч т о в т о р а я с т р о ч к а т а к ж е о т н о с и т с я к о п е р а т о р у ± f. В от о сн о в н ы е п р и н ­ ц и п ы н а п и са н и я эт о го о п ер ат о р а :

П р о в е р я е м о е условие закл ю ч ается в скобки. О тступ н а пару п р о б е л о в во в т о р о й стр о ч к е. К од, запускаем ы й в случае со б л ю д ен и я условия.

У праж нение

Укажите, какие действия должны следовать за каждым из операторов ±±.

i f (hungry)

numDonuts *= 12;

i f (countDown == 0)

userName = r e a d C o o k i e ( " i r o c l i _ u s e r n a m e " ) ;

i f (donutString.indexOf("dozen")

!= -1)

a w a r d P r i z e () ;

i f ( t e s t S c o r e > 90)

g oE a t ( ) ;

i f (Iguilty)

a l e r t ( " H o u s t o n , we ha ve l i f t - o f f . " ) ;

i f (winner)

a le r t( " S h e 's innocent!");

i f ( n a v i g a t o r . cookieEnabled)

g r a d e = "A";

далее >

167


решение упражнения

Вот какие действия должны следовать за каждым из операторов

ажнение угш гш г

Равно tr u e , если с т р о к а с о д е р ж и т с л о ­ во " d o z e n " (д ю ж и н а ).

i f (hungry)

numDonuts *= 12;

i f (countDown == 0)

userName = r e a d C o o k i e ( " i r o c k _ u s e r n a m e " ) ,

i f ( d o n u t S t r i n g . i n d e x O f ( "dozen' ' )

!= - 1 ) -

a w a r d P r i z e ();

i f ( t e s t S c o r e > 90)

g o E a t ();

if

(Iguilty)

a l e r t ( " H o u s t o n , we ha ve l i f t - o f f . " ) ;

''i f

(winner )

a l e r t ("She's in n o c e n t!" );

( n a v i g a t o r . cookieEnabled)

g r a d e = "A";

if

Ig u ilty ознйЧйбт. H E g u ilt y , т о е ст ь п а р а м е т р g u ilt y и м е е т значение false.

И м е е т значение tr u e , если в бр а узе р е вкльочсил п о д д с р ж ка к у к и .

А что делать, ЕСЛИ вариантов несколько? О

Д елайте это... или вот то. С т о и т вам подум ать, ч то т е м а р ас к р ы т а , к ак п о я в л я е тс я н е ч т о вы х о д ящ ее и з р я д а вон. Х отя в ситуац и и , когда п р и х о д и тс я в ы б и р а ть и з н еск о л ьк и х в ар и а н т о в , н е т н и ­ ч его эк с тр а о р д и н ар н о го ... Ш о к о л ад н о е и л и в ан и л ьн о е, б ез к о ф е и н а и л и о б ы ч н ы й , к аж ется, ч т о м н о ж еств е н ­ н ы е в а р и а н т ы сво д ятся к п р ед л ож ен и ю : вам о д н о го или другого. И м е н н о п оэтом у о п е р а т о р 1 f ум еет н е то л ь ко п р и н и м а т ь р е ш е н и я , но и п р о д ел ы в ат ь одну и з двух во з­ м о ж н ы х о п ер а ц и й .

168

глава 4


принятие решении

Когда Вариантов дВа О п е р а т о р 1£ ум еет д ел ать в ы б о р и з двух п р е д л о ж ен ­ н ы х в а р и а н то в . В ер н ем ся к наш ем у шоу. Э р и к п ы т а ется п р и н я т ь р е ш е н и е , какую и з двух п р е д о с та в л е н н ы х ему во зм о ж н о с те й п р ед п о ч есть.

ш

П ервы й в а р и а н т че м о д а н А...

if (проверка условия)\ д е л ай что-то;

—а в т о р о й чем одан В.

e ls e д е л а й что-то ещ е;

<

В ж и зн и о б ы ч н о п р е д о с та в л я е тс я в ы б о р и з б олее чем о д н о го в ар и ан та. О п е р а т о р И д ае т нам (и Э рику) в о зм о ж н о сть в ы б р ат ь ч ем о д ан А и л и ч е­ м одан В. В от как эт о в ы гл яд и т в JavaS cript:

if (chosenCase =

"А")

openCaseC'A") ;

напислт ^у

» Г и ё > е

далее *■

169


если вариантов больше одного

сделать Вы мо}кете V мно)кестВенный Выбор в случае м н о ж ес тв е н н о го

в ы б о р а о п е р а т о р 1£ п р ев р а щ ает с я в о п е р а т о р 1 £ / е 1 з е , д аю щ и й в о зм о ж н о с ть в случае н есо б л ю д ен и я зад ан н о го усл о ви я зап у сти ть другой ф р а гм е н т кода. Ф ак ти ч ески вы го в о р и те: «если условие соблю ден о, запустим эт о т ф р агм е н т кода, а если н е т — в о т эт о т ф р агм ен т» .

if (chosenCase == "А") openCase("А"); ^ собы т ий. О дин ^ о л н е н и я у сл о в и я Г его

else openCase ("В") ;

Э р и к в ы б и р а е т чем о д ан В, т о есть п е р е м е н н ая c h o s e n C a s e будет и м еть зн а ч е н и е «В». Т ак как за д ан н о е усло ви е н е в ы п о л н я ет с я, у п р авл ен и е п е р е ­ х о д и т к коду, стоящ ем у п о сл е о п е р а т о р а e l s e . К н есч астью д ля Э ри ка, в ы б р ан н ы й им ч ем о д ан н а п о л н е н п о н ч и к ам и , а вовсе н е п ач кам и д ен ег, как о н надеялся. Чемодан 8.

Я могу поменять свое решение?

9

170

глава 4

^ развит ия


принятие решений

Ключевое слоВо else С и н так си с о п е р а т о р а i f / e l s e п р а к т и ч е с к и н е о т л и ч а е т с я о т си н так си са уже и зв е с тн о го вам о п е р а т о р а i f . П р о с т о д о б ав л я е т ­ ся кл ю ч ев о е сл о во e l s e с ещ е од ним ф р а гм е н т о м кода, к о т о р ы й запускается п р и н есо б л ю д ен и и условия: Условие

-I-

Оператор!

Всли э т о неверно, за ­ пускается эт от коа К л ю ч е в о е слово else н а п р а в л я е т дейст вие

----------------------------- 1

\-------- 1

В от каким о б р азо м м ож н о д о б а в и т ь в т о р о й в а р и а н т д ей ств и я к о п е р а т о р у i f : К л ю ч ев о е сл ово e l s e п о сл е п ер в о го о п ер ат о р а . ©

О тступ н а пару п р о б е л о в д ля следую щ ей стр о ч к и ,

е

К од, запускаем ы й п р и н есо б л ю д ен и и условия. чааюо

ЛаДаБаеМые

-

БоДроС ьі

Почему после скобок в операторе 1 £ отсутствует точка с запятой?

0 ; визуаЗспр! принято ставить точку с запятой после каждого оператора, и i f не исключение. Однако оператор i f — это не просто запись i f { п р о в е р к а у с л о в и я ) , это еще и код, который выполняется в случае положительного результата

S Ничего, в этом случае по результатам проверки условия не предпринимается никаких действий. Можно ли использовать несколько ключевых слов e l s e для выбора из большего числа вариантов?

проверки. И вот эт от код венчает точка с запятой. Так что

; Да. В структуру i f /е 1 s е можно добавить дополнительные варианты, но это вовсе не сводится к написанию еще одного

оператор i f заканчивается так, как нужнр, если учесть, из каких

ключевого слова

фрагментов он состоит.

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

Что происходит, если условие не выполняется, а ключевое слово е 1 з е отсутствует?

e l s e . Конструкцию i f / e l s e приходится

структура — оператор

s w i t c h / c a s e , с которым мы таюке

познакомимся в этой главе.

далее ►

171


приключения нарисованного человечка

Пишем приключения Э лли п и ш ет и н тер ак ти в н у ю и с т о р и ю « П р и к л ю ч ен и я н а р и с о ­ в а н н о го ч ел о веч ка» . Н а каж дом эт а п е п р и х о д и тс я п р и н и м а т ь р е ш е н и я , и о н а н ад еется со зд ать с ц е н а р и й н aJav a S c rip t, к о т о р ы й п о зв о л и т п о м е с т и т ь е е т в о р е н и е в И н т е р н е т д ля п о л ьзо вател ей .

Пользователю представлена ж т ориТ

Sttck f »S“«

инт еракт ивная

V J e lc o r A G - t o

STICK FIGURE adventu re Л ^

Click e'rtber buttoM ■to

I

S b r iPleasc choose; A J - i J

° Р ^^зличны х

не знает, как их вопло­

пока

т ит ь в реальность.

Э л ли х о ч ет , ч то б ы п о л ь зо в а т е л и н а каж дом этап е ее и с т о р и и вы нуж дены б ы ли д ел ать вы б о р . Вы м о ж ете сразу ск ач ать все н ео б х о д и м ы е ф а й л ы по адресу http://w w w. headfirstlabs. com/books/hfjs/ .

172

глава 4

Я надеюсь, что JavaScn■pt сделает мою историю понастоящему интерактивной.


принятие решений

Схема приключений « П р и к л ю ч ен и я н а р и со в а н н о го ч ел о веч ка» п р ед ставл я ю т со б о й н а б о р сц ен , каж дой и з к о т о р ы х с о о тв етству ет рисун ок и о п и с ан и е . И каж ды й р а з для п е р е х о д а к следую щ ей сц ен е вам п р и х о д и тс я в ы б и р а ть о д и н и з двух в а р и а н т о в р а зв и т и я со б ы ти й .

В сценах 2 и 5 вам также нужно при пят ь реш ение, чтобы двигаться дальше. Сцена 2

В каждой сцене п р и ­ с у т с т в у е т два в а ­ риант а дальнейшего развит ия событий. Хажмнй в лесу ^

С цена 1

■ ■

Развилка на дороге

L

Сцена 3

Каждая сцена и м еет свой уникальный номер.

М ост через реку «Текущ ая сцена» показы ва. ет положение пользоват еля в данный м ом ент времени.

Возьми в руку карандаш Напишите код принятия решений для первых трех сцен с оператором i f / e ls e . Подсказка: переменная d e c i s i o n хранит информацию о выборе пользователя, в то время как переменная c u r S c e n e содержит сцену, к которой происходит переход.

далее

173


решение упражнения

Возьми в руку карандаш _ Решение П е р е м е н н ая ie c is о

Вот как выглядит написанный на основе оператора i f / e l s e код для первых трех сцен «Приключений нарисованного человечка».

_____—

„ .л f ГЛеКУ^М*^*^ “

\

Г о 1 "о б й т е Д ^ ^ ^ ,Д о р о е М0ЛЛеК1АА

АЛО/кет рйЬнЯ 1А^

J. UA« я .

^

_

, f (d e c is io n == 1 ) C M rS cm e - Z } < г

else

-^ c u rS c e n e = 3 ; П ерем енная сигЗсепе х р а н и т инф орм ацию о т е к у щ е й сцене переход к к о т о р о й я в ы л с я ^ е Щ А ь т а т о м принят ого п о л ь ­ з о в а т е л е м решения.

П ереход к сцене Z .

Переход к сцене 3.

Переменные как двигатель истории П о с м о тр и м в н и м ате л ь н о н а п е р е м е н н ы е, к о т о р ы е ф и гури рую т в на­ ш ей и с т о р и и . И х зн а ч е н и е за в и с и т о т р е ш е н и я , п р и н я т о г о п о л ьзо в а ­ тел ем , и и м е н н о о н о я в л я е т с я д в и гател ем н аш ей и ст о р и и .

С«еиа■ Сцена 2

d e c is io n Н уж н о в ы б р ат ь между з н а ч е н и я м и 1 и 2. Э то о п р е д е л и т , в как о й с ц ен е п о л ьзо в а те л ь о к аж ется н а следую щ ем этапе.

Р ем

curScene С ц ен а, в к о т о р о й н а ­ х о д и т ся п ол ьзовател ь. Ее н о м е р о п р е д е л я е т с я п ерем ен н ой d e c is io n : сц ен а 1, сц ен а 2 и т. д.

П е р е м е н н ы е d e c i s i o n и c u rS c e n e р а б о т а ю т совм естн о , со х р ан я я в ар и а н т , в ы б р ан н ы й п о л ь зо в ател ем , и затем н а его о сн о в е осущ ест­ вл я я п ер ех о д к следую щ ей сц ен е. П р о ц е д у р а п о в т о р я е т с я о т сц ен ы к сц е н е до к о н ц а и с т о р и и . С п аси бо за эт о о п ер ат о р у i f / e l s e .

174

глава 4

Сце

И З е М >^01 м осту

по1


принятие решении

Недостающие части истории О п е р а т о р 1 £ / е 1 з е п р е к р а сн о р а б о т а е т в к ач еств е «двигателя» « П р и к л ю ч ен и й н а р и со в а н н о го ч ел о в е ч ­ ка», н о о н , к со ж ал ен и ю , н е п о зв о л я е т р а с с к а зат ь и с т о ­ р и ю цел и ко м . К аж д о й сц ен е с о о тв етств у ет не то л ь ко и зо б р а ж е н и е , н о и т е к с т о в о е о п и сан и е. И зм е н е н и е н о м е р а текущ ей с ц ен ы п о зв о л я е т п е р е й т и к другому и зо б р а ж е н и ю , о став и в за кадром и зм е н и в ш и й ся текст.

«Н овая» т екущ ая

сцена. Г

1

Сцена 2

Пользователь выбрал в а р и ­ ант « эт о п ривело его

Х и ж и н а в лесу

к сцене Я-

Сцена 1

J Р йзвилкй на дороге

с ч .« «

0ДрйЗним веЗі>М^і

«Вы прибьши в симпатичную маленькую хижину в чаще леса».

© Обойде

Для з а д М

д о ст а т о ч н о н о м е р а си,еиьь ка к э т о т ном ер содерж ит ся

iiio to e

в имени соот вет ст вую щ его

c o l Ofс

граф ического ф айла.

la ia n i

.—

ф о р м а т РЫО — новы й, ш и р о ко ^ распрост раненны й ^лtлл слтлалнI д а р т.

О п и са н и е сце~ н ь / о с т а е т с я за кадром ,, т а к к а к рР^ЗЦЛЬИА/]1 е з у л ь т а талл е 1п рI, и ­ н ят о го р е ш е н и я м о ж е т бы т ь в ы один

document.getElementByldC'sceneimg").src = "scene" + curScene + ".png

Т ак как п о сл е каж до й ч ас т и о п е р а т о р а i f / else м о ж н о зап у сти ть т о л ь к о о д и н ф р а гм е н т кода, к о л и ч е с т в о в а р и а н т о в р а зв и т и я с о б ы ти й о гр а н и ч е н о . Д р у ги м и сл овам и, вы н е м о ж ете о т о б р а зи т ь н о в ы й т е к с т и н о в о е и зо б р а ж е н и е о д н о в р ем ен н о .

Ш ТУРМ Как бы вы реализовали выполнение набора операций в ответ на принятие решения?

далее ►

175


больше одного

СоВмецение усилий Э л ли нуж но, ч то б ы н а каж д о й ветв и о п е р а т о р а i f / e l s e в ы п о л н я л о с ь н еск о л ьк о ф р а гм е н т о в кода. П р и п е р е х о д е к следую щ ей с ц ен е о н а хоч е т м е н я т ь н е т о л ь к о и зо б р а ж е н и е , н о и с о п р о в о д и т е л ь н ы й текст:

И зм енение к а р т и н к и б р а н н о с ^^^ ^^ ^

document.getElementByldC'sceneimg").src = "scene" + curScene + ".png"; alert(message);

О т ображ ение описания в ы ­ бранной п о л ш о в а т е л е м новой сцены. Вам нуж но п р о и зв е с т и н еск о л ьк о о п е р а ц и й , н е с м о т р я н а т о ч то Jav aS crip t в это м случае п о зв о л я е т запускать всего од и н ф р а гм е н т кода. Р еш ен и ем я в л я е т с я с о с та в н о й о п е р а т о р . Д л я его с о зд ан и я до­ ст ат о ч н о зак л ю ч и ть н а б о р о п е р а т о р о в в ф и гу р н ы е скоб ки ({ } ).

Ага! Составной оператор позволяет превратить набор фрагментов в один кусок кода.

О d o T h i s (); d o T h a t ();

З оператора

doSomethingElse (); >

Количество открывающих и закрывающих скобок должно совпадать.

{

doThisO; doThat();

1 оператор

doSomethingEise();

_____

С о ставн о й о п е р а т о р п о зв о л я е т со зд ать к о н струк ц и ю i f / e l s e , реализую щ ую в о д н о й в е т к е н еск о л ьк о о п е р а ц и й : if (chosenDoor == "А") { prize = "donuts"; alert{"Вы выиграли коробку с пончиками!"); }

else { prize = "pet rock"; С х ґ' alert("Вы выиграли камешек!"); }

176

глава 4

Выполняйте »абор действий о каждой ветке оператора if/else.


принятие решений

чааво

ЧаДаБаеМые Б оЛ рось! Каким образом переменные влияют на развитие сюжета

Зачем соединять несколько операторов в один?

3 * Почему в конце составного оператора нет точки с запятой?

в «Приключениях»? 0 ; в иауаЗсг1р1 часто требуется всего ; в каждый момент переменная c u r S c e n e содержит номер текущей сцены. При этом демонстрируются соответствующее изображение и описание, а пользователю предлагается указать, к какой из следующих сцен он предпочитает перейти. Выбор пользователя — 1 или 2 — сохраняется в переменной d e c i s i o n . Вместе с переменной c u r S c e n e она определяет следующую сцену. На основе значения этой переменной выбирается новая картинка, и во всплывающем окне появляется новое описание.

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

0 ; Точка с запятой обозначает конец обычного, одиночного оператора. Соответственно, она завершает каждый составной оператор из формирующих операторов. 3 * Относится ли метод к составным операторам? ! Разумеется. Вы уже могли заметить, что код методов заключен в фигурные скобки. Поэтому на данном этапе методы можно воспринимать как большие составные операторы, которым вы передаете данные и от которых получаете результат.


решение упражнения

Возьми в руку карандаш,

Решение Номер новой сцены определяет реш ение 'пользователя.

Вот как должен выглядеть новый вариант кода для первого оператора i f / e l s e , направляющего героя «Приключений» к следующей сцене.

if (decisioiA

1) (

curScene = 2: Описание Выбира­ ет ся в с о о т в е т - ...............message = ‘'You have arrived a t a cute little house in th e w oods ” • ст вии с ном ером Г

сцены.

...................................................................................................................................... .

-----^

}

Начните сост авной о п е р а т о р с ф игур ной

открывающ ей скобки.у<С‘'ИГ?сепе ~ з .

strea m .”; Все содержимое составного о п е ­ р а т о р а пиш ем с от ст упом .

8 конце составного о п ер а т о р а с т а ви м закры ваю щ ий} ф и гу р н у ю скооку.

КЛЮЧЕВЫЕ МОМЕНТЫ

178

<1

bridge overlooking а ^eaceful_ tv

Д л я сцены 3 задано другое описание.

------------------------------------------------

Оператор i f запускает фрагмент кода JavaScript при соблюдении заданного условия.

Составной оператор позволяет запустить набор фрагментов кода JavaScript вместо одного.

Результатом проверки условия в операторе i f является значение t r u e или f a l s e .

Для создания составного оператора достаточно за­ ключить набор операторов в фигурные скобки ( { } ) .

Оператор i f / e l s e позволяет по результатам проверки условия запустить два фрагмента кода JavaScript.

Составные операторы позволяют осуществлять на­ бор действий в конструкциях i f и i f / e l s e .

глава 4


принятие решений

Приключения начинаются Н а б о р со став н ы х о п е р а т о р о в вм есте с ко н стр у к ц и ей i f / e l s e п р е в р а т и л и « П р и к л ю ч ен и я н а р и со в а н н о го чел овеч ка» в и н тер ак ти в н у ю и сторию !

0 Дразним , 'веЭЬАЩ ,

К но п ка X п ер е во д и т п о ль зо вй т е ля к сцене Z-

f

Pleasechoosc:

YOU have

»

«

' «

*"

-Ч»

Pltecl»»: _ lj j J Y our jou rn e y b e g in s “ ®

wmmmniHiaH Т е к с т с о п и са ни ем сцены во в с п лы ва ю щ ем окне.

Сцена 3.

К н о п ка Я п ер ево д и т п о ль зо ва т еля к сцене 3.

Первые сцены истории выглядят замечательно!

jJ - iJ You are s ta n d in e o n th e brid g e overlo o k m g a peaceful Stream .

далее *

179


корни дерева решений

Остальные приключения Е д и н ств ен н о е р е ш е н и е п о л ь зо в а т е л я в р я д л и п о зв о л и т со зд ать и н тер есн у ю и сто р и ю . Н о Э лли п л ан и р у ет вк л ю ч и ть в п о в ест в о ­ в ан и е д о п о л н и т е л ь н ы е сц ен ы . В р езу л ьтате п ол уч и тся древо­ видная структура, по к о т о р о й вы будете п р о д в и га ться дальш е.

Сцена 2

Х и ж и н а в лесу. Д л я перехода о т начальной сцены к сцене 1 р е ш е н и я п о л ь ­ зоват елей не т р е б уе т ся. ИЯІ

Сцена 1

Сцена О

^

И д ем п о д о р о ге.

Н ач ал о и с т о р и и . Рйзбылка Нй аоВведение

роге

И д ем н а мост.

Сцена 3

Заглавная сцена с л у ж и т введением 6 « П р и к л ю ч е н и я нарисован ного человечка».

К р о м е н о вы х сц ен , обеспечиваю ш ;их д о п о л н и т е л ь н ы е п о в о р о т ы сю ­ ж ета, Э лли со зд ал а вводную сцену, к о т о р а я будет п о я в л я ть ся п ер ед с ц ен о й 1. О н а ун и кал ьн а тем , ч т о н е т р еб у ет п р и н я т и я р е ш е н и я для п ер ех о д а. Все м а те р и а л ы , н ео б х о д и м ы е д ля эт о го урока, м ож н о ск ач ать п о адресу http://xvw w .headfirstlabs.com /books/hfjs/.

180

глава 4

М о с т через р е к у


принятие решении

С цена 8

С цена 4

К рад ем ся

Продолжение следует...

^

ВедШ й в окне

С цена 5

Д р азн и м ведьму.

^

Д р азн и м ведьму.

Съеден ведомой КО НЕЦ

Э т о т уп и к о в ы е в е т ки .

С цена 6

Э т и в а р и а н т ы возвра^ щ а ю т нас к т у п и к о ­ в ы м сценам .

Съеден т р о ллем КОНЕЦ ^

^ П е р е х о д и м м ост.

Г о в о р и м трол«П ривет».

ЛЮ

С цена 9

С цена 7

С м о тр и м

Продолжение следует...

ТроллЕ? на м ост у П р ы гаем в реку.

Ш ТУРМ Как будет выглядеть это дерево решений, написанное при помощи операторов if / e ls e ?

далее >

181


я не знаю... это зависит от...

Запись при noMoui^u if/else If (cu rSce n e is 2)

Н е с м о т р я н а т о ч т о в ы б и р а ть каж ды й р а з п р ед л агается всего и з двух в а р и а н т о в , Э лли р е ш и л а сделать так, ч то б ы последую щ ие р е ­ ш ен и я зав и сел и о т преды дущ их. Н а п р и м е р , для п ер е х о д а к сц е н е 5 о т н а ч а л а и с т о р и и нуж но п р о д е л а ть следую щ ий путь:

If (d e cision is 1) К сц ен е 4 E lse

С цена 2

Сцена 1

Разбидкй I

Хижина в леей

ц й дороге I

Съеден ведьм ой.

С цена 2

Сцеиа 1

разбилка нй дороге

^

Хижина лесу If (cu rSce n e is 4) If (d ecision is 1)

Можно ли вкладывать операторы if/else друг в друга?

К сц ен е 8 E lse К сцене 5

З н а н и я , как о й в а р и а н т в ы б р ал п о л ьзо вател ь, н е д о с та т о ч н о для п е р е х о д а к следую щ ей сц ен е. Э то всего л и ш ь од и н и з ф а к то р о в . М о ж н о и сп о л ьзо вать н а б о р о п е р а т о р о в i f / e l s e , сн ач ал а п р о ­ в е р я я текущую сцену, а затем п р е д п р и н и м а я д ей с тв и е н а о сн ове п р и н я т о г о п о л ьзо в ател ем р еш ен и я . Н о в этом случае вы получите н а б о р в л о ж ен н ы х о п е р а т о р о в i f , ч т о к р а й н е неудобно. Н о ведь в р е ал ьн о м м и р е мы п р и н и м ае м р е ш е н и я п о этап н о . Вы ведь о т в е ч ал и н а воп рос: «Вы будете за к азы в ать к а р т о ф е л ь ф ри?» Его о б ы ч н о н е задаю т, есл и вы зак азал и салат. Д ругим и словам и, ч то б ы по л уч и ть т а к о й в о п р о с, нуж но п ер ед эти м д ать о п р ед е л ен ­ н ы й о тв е т, н ап р и м ер : «Я буду чи зб ургер». Т о есть б олее п о зд н и е в о п р о с ы (к а р т о ф ел ь ф р и ?) зав и ся т о т о т в е та н а во п р о с преды ду­ щ и й (ч и зб ургер и л и салат?).

182

глава 4


принятие решении

Вло)кенный оператор ^f Jav aS crip t п о зв о л я е т вклад ы вать операторы друг в друга. Д руги­ ми сл овам и, н и ч т о н е за п р е щ а е т вам зад ать н о в ы й во п р о с, полу­ ч и в о т в е т н а преды дущ ий. Т акая к о н стр у к ц и я н а зы в а е т с я в л о ж е н ­ ны м о п е р а т о р о м .

В ло ж е н н ы й о п е ­ рат ор if р а ссм а ­ т р и в а е т с я только в т о м случае, к о г ­ да внешний опера­

тор возвращает значение true.

if (order == "cheeseburger") if (wantFries) order += " fries"; else if (order == "salad") if (wantFruit) order += " fruit"; }

/ Ynpou^eHHi^iu вариант за п и с и order " order -r ... на 8t>! получите

{

{


реш ение упражнения

Возьми В руку карандаш Рр\\\рЦ\АО г СШ СпИС

В Ы Г Л Я Д И Т код п р и н я ти я р е ш е н и й для сцены о и сцены 1 « П р и к л ю ч е н и й н а р и с о в а н н о го чел овечка».

Сцена О всегда см ен я ет ся сценой 1 , п о э т о м у вам не т р е б у е т с я влож енный операт ор

Текстовое описание ОЛЯ сцены 1,

if (curScene == о) I В ели м ы находим ся не е сцене о , п р о б е -

curScene = 1;

щ т е ^ бы т ь,

message = "Your joum&y begins a t a fork /n the road-“;

^else if (curScene - - 1) { if (decision == i ) { Влож енный о п е р а т о р if/else обрабат ы вает реш ение п о л ь з о в а т е ЛЯ для сцены t .

. curScene = Z; message = "You have arrived a t a cute, little house in the woods.":

else.f ^ curScene = 3; >mesSAge ~ "You are sta n d in ^o n the bridge overlooking a peaceful stream.";

}

O m xm ym t помога­ ю т определить, какие операторы являются вложенными.

184

глава 4

\

Важно, чт обы количест во о т кр ы ва ю щ и х скобок с о ­ от вет ст вовало количе­ с т в у закры ваю щ их.


принятие решении

Управление при помои^и методов П о л ь зо в а т ел ь п е р е х о д и т о т о д н о й с ц ен ы к другой п р и пом ощ и п ар ы к н о п о к («1» и «2»). Щ ел ч о к н а л ю б о й и з к н о п о к вы зы в ае т м етод с Ь а п д е З с е п е ( ) , о тв е ч а ю щ и й за п ер ех о д к следую щ ей сцене.

function changeScene(option)

{

} </script> </head> <body>

<div style="margin-top:100px; text-align:center">

p " a ,;

\

- p n ,-

x

A C v X tu re .. / > < ь Л >

<input type="buttOn" id="decision1 "

^

<input type="button" id="decision2" v alue="?" (1] </div> ° ^ d i c k - " c h a n g e S c e n e (^ </body> </html>

М етод c h a n g e S c e n e () по л у ч ает р е ш е н и е п о л ьзо в ате л я («1» и л и «2») в к ач еств е аргум ента. Э то й и н ф о р м а ц и и д о ст а т о ч н о д ля п е р е х о д а к следую щ ей сц ен е. М етод c h a n g e S c e n e () д ел ает следую щ ее:

На ве б -с т р а н и ц е находит ся Ъве кнопки, о п р ед еля ю щ и е, к какой сцене п о л м о в а т е л ь п е р е й д е т на с лед ую щ ем эт апе.

Присваивает п е р е м е н н о й c u r S c e n e н о м е р н о в о й сцены.

©

О

П р и с в а и в а е т п е р е м е н н о й m e s s a g e н о в о е о п и сан и е. М е н я е т и зо б р а ж е н и е н а о сн о в е зн а ч е н и я п е р е м е н ­ н о й c u r S c e n e и в ы в о д и т н о в о е о п и сан и е.

далее ►

185


псевдо что?

Псевдокод Э лли п р и м е р н о п р ед став л я ет, как н а п и с а ть н а Jav aS crip t код м етод а c h a n g e S c e n e ( ) , реал и зу ю щ и й д е р е в о р е ш е н и й н аш ей и с т о р и и . Н о из-за б ольш ого к о л и ч ес т в а р е ш е ­ н и й в коде л е гк о запутаться. П о это м у и м е е т см ы сл сн ач ал а н а п и с ать п севдокод, к о т о ­ р ы й п р о щ е в о с п р и н и м а е т ся , а уже н а его о с н о в е м ы зай м ем ся п р о гр а м м и р о в а н и е м . Т а к о й подход п о зв о л я е т и зб е ж а ть путан и ц ы и ош ибок.

С цена

Г Каждый о п е р а т о р if/else верхнего уровня представляет свою сцену.

о

If (c u rSc e n e is 0) < г

введение

К сцен е 1 Т екст с ц е н ы 1

V ---- -------------- 3!» E ls e и (c u rSc e n e I s 1) - > If (d ecision is 1)

В н у т р е н н и е опера­ торы if/else вы­ полняют действия ы выбору п о л ь з о в а ­ т еля.

К сц ен е 2 Т екст сц ен ы 2 E lse С цена 2

К сцен е 3

Хижина в лесу

Т екст сц ен ы 3 E lse If (c u rSc e n e Is 2)

Часзпо

5

^аД аБаеМ ы е Боц|=»ос:ь1 =

Псевдокод похож на код JavaScript. Зачем он нужен?

; Он позволяет упростить процесс преобразования сложного логического дерева в код JavaScript и минимизирует риск ошибок. Псевдокод имеет меньший уровень детализации, поэтому вы можете сфокусировать внимание на логике происходящего и переходе от одной сцены к другой. Привыкнув работать с псевдокодом, вы сможете практически на автомате переводить его в обычный код ивуаЗспр!.

186

глава 4

5=

Требуются ли фигурные скобки для вложенных one операторов i f ?

0

!: Нет. Если вы вкладываете всего один оператор , фигурные скобки проще игнорировать, так как технически вам не нужен составной оператор. А вот при сложном вложении операторов 1 £ скобки могут пригодиться, так как они структурируют код и делают его более читабельным.


принятие решении

Магниты JavaScript в м ето д е c h a n g e S c e n e ( ) не хв атает н е с ко л ь ки х ф рагм ентов . В оспользуйтесь м агн и та м и , чтобы пол учи ть код, в о с п р о и зв о д я щ и й д и а гр а м м у на с тр а н и ц е 180. П о м н и те , что показаны д а л е ко не все варианты р а зв и ти я и с то р и и — не ко то р ы е сцены н а м е р е н н о были оставлены за ка д р о м .

лее >

187


решение задачи с магнитами

^ Решение задачи с магнитами Вот ка ки м о б р а зо м тр е б о в а л о с ь д о п о л н и ть м ето д c h a n g e S c e n e { ) , чтобы пол учи ть код, в о с п р о и зв о д я щ и й д и а гр а м м у со страниц ы 180.

188

глава 4


принятие решении

Приключения продол}ка1отся Т е п е р ь с ц е н а р и й « П р и к л ю ч ен и й н а р и со в а н н о го ч е­ л овечка» о т о б р а ж ае т все д е р е в о р е ш е н и й , п о зв о л я я н а п р ав л я т ь с о б ы т и я по р а зл и ч н ы м веткам . В от од и н и з вар и ан то в :

W e lc o n e t o

ADVENTUI^E Click either b u tto N f o

start...

далее >

189


потерпев неудачу

Проблемы нарисованного человечка к со ж ал ен и ю , Э лли уже столкнулась с п р о б л ем о й . П о п р о с и в св о и х друзей п р о т е с т и р о в а т ь с тр ан и ц у с « П р и к л ю ч ен и ям и » , о н а узнала о п о я в л е н и и пустого окна. « О кн о-призрак» в о зн и ­ к ае т п р и п е р е х о д е о т о д н о й с ц ен ы к другой. Т о есть п р о б л ем а каким -то о б р азо м св язан а с в о зв р а щ ен и е м к с ц ен е 0.

О к н о - п р и з р а к не содерж ит никакого сообщения? WelcOHG t o

STICK FIGURE A D V E M T i i Pc

CZ5HZ3 О РЬаж choose:

О казал о сь, ч т о две с ц ен ы д ей с тв и те л ь н о в о звр ащ аю т нас к с ц ен е 0. И х н о м е р а 5 и 6 , и о н и со о тветству ю т тупиковы м веткам и с т о р и и . В п р и н ­ ц и п е и м е е т см ы сл, п о сл е то го как и с т о р и я сто л ь б ессл авн о за в ер ш и ­ л ась, вер н у ться в нач ало. И м е н н о п о это м у Э лли н ап и сал а код м етод а c h a n g e S c e n e () таки м о б р азо м , ч то б ы п о сл е э т и х с ц ен п р о и сх о д и л п ер ех о д к с ц е н е 0: else if (curScene == 5 curScene = 0;

} else if (curScene == curScene = 0;

Сцены s и <ь м е н я ю т значение пер ем ен н о й cu rS cen e, но ничего не д е л а ю т с пер ем ен н о й m essage.

К аж ется, ч то т а к о й п р о с т о й код н е д о л ж ен бы л п р е п о д н е ст и н ам н и к ак и х с ю р п р и зо в , н о в згл ян ем н а посл ед н ю ю стр о ч к у м е­ т о д а c h a n g e S c e n e ( ) , о тв еч аю щ его за и зм е н ен и е и зо б р а ж е н и я и о п и с ан и я п р и п е р е х о д е к следую щ ей сцене. document.getElementByldC'sceneimg").src = "scene" + curScene + ". png" alert(message);

О т ображ ает т е к с т с описанием сцены , хр анящ ийся в п ер ем ен н о й m essage.

190

глава 4


принятие решении

! = m-c-c‘ c, мне нечего тебе сказать... П р о б л е м а в то м , ч то код « П р и к л ю ч ен и й » всегда в ы зы в ае т о кн о с о п и с ан и е м сц ен ы , даж е есл и о п и с ы в а т ь н е ч е го , как, н а п р и м е р , в сц е н е 0. К аки м ж е о б р азо м п р о в е р и т ь , со д е р ж и т л и п е р е м е н н ая m e s s a g e какой-нибудь текст?

(

.3

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

Условие соблюдаеился для всех сцен, кроме сцены 6.

if

П е р ед вы зо во м о к н а нуж но п р о в е р и т ь , н е со д е р ж и т л и п е р е м е н н а я m e s s a g e пустой с т р о к и (" ")• М ож н о п о ­ ст ав и ть и другое условие. В ы зы вать о к н о ди ал ога, если п е р е м е н н а я m e s s a g e н е р а в н а пустой стр о ке. Э то вы гл я­ д и т как р е ш е н и е п р о б л ем ы задом н ап ер ед , н о в д ан н ом случае м ы рассуж даем в т е р м и н а х п р о в е р к и условия. В то в р е м я к ак о п е р а т о р (==) п р о в е р я е т р ав ен с т в о двух эл ем ен то в , о п е р а т о р (! =) п р о в е р я е т и х н ер авен ств о .

{curScene != 6) a l e r t ("Thankfully, you haven't been eaten by the troll.");

далее ^

191


операции сравнения

Возьми в руку карандаш 'ешение Условие с о б л ю д а е т ­ ся, ссли п&р&менная m essage содерж ит н е п у с т у ю ст р о ку.

Вот к а к б удет вы глядеть код, вы зы ваю щ ий о к н о д и а л о га в слу­ чае, если п е р е м е н н а я m e s s a g e с о д е р ж и т текстов ы е данны е.

if (m essage !- "") alert(m essa g e)i

Операторы сравнения Д о эт о го м о м ен та м ы р а с с м ат р и в а л и п р о в ер к у условий, со зд ан н ы х т о л ь к о п р и п о м о щ и о п е р а т о р о в р а в е н с т в а и н ер а в ен с тв а. А ведь н аш и в о зм о ж н о с ти эти м н е о гр а н и ч и в а ю тс я . Р ассм о тр и м и другие о п е р а т о р ы с р ав н ен и я.

Равенство X == у

Неравенство X

Меньше чем

»= X

Значение tr u e , если X Р А В Е Н у.

Отрицание

Значение tr u e , если х НЕ РА В Е Н у.

< у Значение tr u e , если х М Е Н Ь Ш Е , ЧЕМ у.

Меньше UAU равно X

Значение false, если х и м е е т значение tr u e , и наоборот .

< =

З начение tr u e , если х З О А Ь Ш Е , ЧЕМ у.

у

Значение tr u e , если х М ЕН ЬШ Е И Л И Р А В Е Н у.

Больше иди равно X

>= у

Значение tr u e , если х 5 0 Л Ь Ш Е И Л И Р А В Е Н у.

= и == вовсе не одно и то же.

О п е р а т о р ы с р а в н е н и я Jav aS crip t исп ользую т­ б у д ,ыпе ьте ся д ля п о с т р о е н и я выраженийг, к о т о р ы е затем Для проверки равенства осторож ны ! ком б и н и р у ю тся в е д и н о е зн а ч е н и е . Э то зн а ч е н и е двух значений следует ис­ п р и н а д л е ж и т к ло ги ч еск о м у типу ( t r u e / f a l s e ) , пользовать оператор == ч то д ел а е т его н езам ен и м ы м в кач е с тв е п р о в е р я е ­ и ни в коем случае не оператор =. Послед­ м ого усл о ви я в о п е р а т о р а х i f / e l s e . ний осуществляет присвоение значения.

192

глава 4


чааюо

принятие решении

Задаваем ы е Б о п р о сгь! Почему оператор отрицания использует всего одно значение?

Q l Этот оператор реализует очень простую задачу. Он меняет значение операнда на противоположное. В результате t r u e превращается в f a l s e , и наоборот. Я видел оператор отрицания рядом со значением, которое не имеет отношения к сравнению. Как он работает?

• А что такое n u l l ?

; n u l l — это специальное значение, указывающее на отсутствие данных. Его смысл вы лучше поймете при рассмотрении объектов, которым будут посвящены главы 9 и 10.

! В таких случаях все зависит от того, каким образом JavaScript определяет «правдивость» значения. Используя не имеющие отношения к сравнению значения в ситуации,

ажнение

где сравнение ожидается, мы интерпретируем любое значение, отличное от n u l l , о или " " , как t r u e . Другими словами, как t r u e рассматривается само наличие данных. Поэтому, когда вы видите оператор отрицания с несравниваемым значением, n u l l , О и " " дают в результате t r u e , а все остальные значения — f a l s e .

Этот код выводит сообщение «I love stick Figure Adventure!» Какие значения должны иметь переменные а , Ь , с и d , чтобы получился именно такой результат?

v a r q u o te -

a if

(a != 1 0 ) q u o t e += "Som e g u y " ; e ls e q u o te += " I " ; i f (b = = (a * 3)) { i f (c < (b / 6 ) ) q u o te += " d o n 't c a re f o r " ; e l s e i f (c > = (b / 5 ) ) q u o t e += " c a n ' t r e m e m b e r " ;

b

с d

e ls e q u o t e += " l o v e " ;

} e ls e { q u o t e += " r e a l l y

h a te s";

} if.(!d ) { q u o t e += " S t i c k F i g u r e " ;

} e ls e { q u o t e += " R o c k ,

P aper,

S c isso rs

;

} a l e r t

(q u o te + " A d v e n tu re !" );

далее ►

193


решение упражнения

значения должны иметь переменные а , Ь, с и d, чтобы во всплывающем окне rto 2 ^ 1 6 H V l2

появилось сообщение «I love stick Figure Adventure!»

var quote if

Й должно р а вн я т ься Ш

(a != 10)

q u o te += "Some g u y "; e ls e quote += "I"; if (b == (a * 3)) { if (c < (b / 6) ) quote += " don't care else if (c >= (b / 5)) q u o t e += " c a n ' t r e m e m b e r

e ls e quote += " love";<i

}

П ерем енная d должна и м е т ь значение false, чт о5ы выраж ение !d и м ело значение tru e. В о т сообщ ение, ко т орое н а м м ребовалось.

else { quote += "

} if (!d) { quote += " I love Stick Figure Adventure!

} else { quote += "

} a le rt(q u o te

+ " A d v en tu re!

Комментарии «П р и к л ю ч ен и я» я в л яю тся х о р о ш и м п р и м ер о м с ц е н а р и я с н е за в е р ш е н н ы м и ф р а гм е н т а ­ м и кода, ведь и с т о р и я еш,е н е д о п и сан а. К пр и м еру, сц ен ы 8 и 9 п о м е ч е н ы сл о в о со ч ет а­ н и ем « П р о д о л ж ен и е следует». Н е за к о н ч е н н ы е о б л асти код а и м еет см ы сл п о м еч ать ком ­ м ен т а р и я м и , ч то б ы н е за б ы ть за п о л н и т ь и х п о зд н ее. К о м м ен т ар и и вJav aS cгip t н и к о и м о б р азо м н е в л и я ю т н а запуск и р або ту сц ен ар и я.

К о м м е н т а р и и на чинаю т ся п арой косых ч ерт .

194

глава 4

-ь ^ Комментарий

Т екст к о м м е н т а р и я м ож ет быть любым. Инт ерпрет ат ор J a v a S c rip t его все равно не видит.


принятие решении

КоАЛАленшарии начинаются с / / Н а ч и н а я с ь с / / , к о м м е н т а р и и п р о д о л ж аю тся до к о н ц а стр о ки . Д ля со зд ан и я м е с то за п о л н и т е л я п о с та в ьте две к о сы е ч е р т ы и о став ь те за н и м и п р и м е ч а н и е о том , ч т о код ещ е н е нап и сан .

Сцена 8

else if (curScene == 8) { 11 Продолжение следует

Э т и ст р о ч ки и гн ори р ую т ся-

С ц ен а 9

} else if (curScene == 9) { 11 Продолжение следует

ПроЭоАжгиие слеЗает-..

} К о м м е н т а р и и н е то л ь к о и гр а ю т р о л ь м е с то за п о л н и т ел ей . О н и исп ользую тся в ка ч е с тв е п р и м еч а н и й , д ел аю щ и х код б о л ее п о н ятн ы м . Т о , ч т о вы сей ч ас п о м н и т е п р е д н а зн а ч е н и е то го и л и и н о го ф р а гм е н т а кода, н е о зн а ч ае т, ч то вы будете п о м н и т ь эт о и ч е р е з год. К р о м е т о го , ваш код м о ж ет п о п асть в чуж ие руки, и и м е н н о п р и м е ч а н и я п о зв о л я т б ы ст р о п о н я т ь , ч т о для ч его п р ед н азн ач ен о .

К ом м ент а­ р и й объясняет ин и ц и ализацию >л&ременной.

// Выбираем в качестве текущей сцену О (Введение) var curScene = 0 ;

И н и ц и а л и за ц и я п е р е м е н н о й c u r S c e n e в « П р и к л ю ч ен и ях» стал а п о н я т н е й б лаго д ар я ко м м ен тар и ю . А н ал о ги ч н ы м ко м м ен тар и ем м ож н о сн аб д и ть и н и ц и а л и за ц и ю п е р е м е н н о й m e s s a g e . И сноЬа к о м м е н т а р и й по я сн я ет назначение ф р а гм е н т а кода.

// Удаляем описание сцены var message =

С ущ ествует в о зм о ж н о сть со зд ав ать к о м м е н т а р и и , за н и ­ м аю щ ие н еск о л ьк о строк. М ногост рочны е к о м м е н т а р и и Ha™ чи и а ю т ся с / * Еще комментарий

}

Однострочные комментарии начинаются с / / , в то время как многострочные комментарии заключены между / * и * / .

К он ец коммент ария

8 конце м н о г о ­ ст рочного к о м ­ м ент ария с т а б ы тс я */.

________ ;

К о м м е ш а р и й м о ж е т и м е т ь п р ои звол ьн ую длину и зан и м ать скол ьк о угодн о стр о к. Д о с та т о ч н о п о ста­ в и ть в н ач ал е / *, а в к о н ц е * / . /* Эти три строчки кода представляют собой один большой комментарий. Серьезно, я не шучу. Кроме шуток, это все еще один комментарий. */

далее ►

195


ну и куда мне деть эту переменную?

Комментарии несут смыс­ ловую нагрузку, но я не понимаю, почему переменные curScene и message создаются в различных местах. Что это означает?

П ерем енная cu rS cen e со зд а ем ся вне м ет о д а c k a n g e S c em Q .

<script type="text/javascript"> (В ведение) - ^ / / Выбираем в к а ч е с т в е тек у щ ей с ц е н у О var curScene = 0; function changeScene(decision) / / У даляем о п и сан и е сцены var message =

{

</script>

П ерем енная m essage создает ся в н у т р и changeSceneQ .

Место создания переменных К ак п р и покупке н ед в и ж и м о сти , в Jav aS crip t б ольш ое зн а ч е н и е и м еет м ес то п о л о ж е н и е . В « П р и к л ю ч ен и ях » у ч и ты в а ется м есто со зд ан и я п ер ем ен н ы х . Н е случайн о п е р е м е н н а я c u r S c e n e п о я в и л а сь вн е м етод а c h a n g e S c e n e ( ) , в т о в р е м я как п е р е м е н н а я m e s s a g e — в н утри него. Все д ел о в о б л а с т и в и д и м о с т и , управляю ш ;ей ж и зн е н н ы м ц и кл ом п е р е ­ м е н н о й и о п р ед ел яю щ ей , как о й код и м е е т к н е й доступ.

196

глава 4


принятие решении

Область Видимости в Jav aS crip t о б л асть в и д и м о сти о п р е д е л я е т сп особ д оступа к д ан ­ ны м. Н е к о т о р ы е д ан н ы е ви д и м ы для всего с ц е н а р и я , в т о в р е м я как в и д и м о сть других о г р а н и ч е н а ф р а гм е н т о м кода, н а п р и м е р м етодом . Р ассм о тр и м п е р е м е н н ы е, ж и вущ и е в р а зл и ч н ы х об ла­ стях: v a r х;

f u n c t i o n d o S o m e th in g (2 )

Глобальная п ер ем ен н а я , видим а для всего сценария.

{

var у;

Л о ка ль н а я п ер ем ен н а я , видим а т о ль к о вн у т р и м ет ода.

}

В д ан н о м коде х н а зы в а е т с я глобальной п е р е м е н н о й , т а к как о н а б ы ла со зд ан а в н е м ето д а и л и л ю б о го другого ф р а гм е н т а кода и, сл ед о в ател ьн о , ви д и м а для всего с ц е н а р и я . Б о л е е то го , х «жи­ вет», п о к а р а б о т а е т сц е н а р и й . А во т у — эт о локальная п е р е м е н ­ н ая, в и д и м о сть к о т о р о й о г р а н и ч е н а м ето д о м d o S o m e th in g () . О н а сущ ествует т о л ь к о во в р е м я р а б о т ы это го м ето д а — созд ается п р и его запуске и у н и ч то ж ается п о сл е зав е р ш е н и я .

Глобальные п ерем енны е с у щ е с т в у ю т все вр ем я жизни сценария.

А ч т о м о ж н о сказать п р о ар гу м ен т м ето д а d o S o m e th in g {) — г? А ргум енты м ето д о в а н а л о ги ч н ы уже и н и ц и а л и зи р о в а н н ы м ло кал ьн ы м п ер ем ен н ы м . Т ак ч т о г и м е е т ту ж е самую об ласть ви д и м о сти , ч то и у, и доступн а то л ь к о в н у тр и метода.

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

Ш ТУРМ Как использовать локальные и глобальные переменные в коде «Приклю­ чений нарисованного человечка»?

далее ►

197


приключения с местом переменных

ПроВерилл область Видимости Т е п е р ь , в о о р у ж ен н ы е сведен и ем об о б л асти в и д и м о сти , взгл ян ем ещ е р а з н а п е р е м е н н ы е н аш его с ц е н а р и я. Э то п о зв о л и т лучш е п о ­ н ять, почем у п е р е м е н н ы е следует со зд авать в р а зн ы х м естах.

Значение п ер ем енно й m essage каждый р аз сбрасы вает ся м е т о д о м changeSceneQ , п о э т о м у сд ела ем ее локальной.

<script type="text/javascript"> // Выбираем в качестве текущей cueHv П т var curScene = n ■_ сцену О (Введение|_ function ChangeScene(decision) // Удаляем описание сцены

{

var message =

Значение п е р е ­ м енной cu rS cen e задает ся между вы зовам и м ет о д а changeScene()., з н а ­ ч и т , э т о гл о б а л ь ­ ная перем енная.

if (curScene == 0) curScene = 1 ; ,

{

^ ° - n e y begins at a fork in the road.

\ ^ e l s e if (curScene == 1) { if (decision == 1) { curScene = 2 ,

-

-Y O U

^

l i t t l e . . , . . ;

else { curScene = 3 ;

on t h e b t i d , , . . . . . ,

, else if

(curScene == 2)

{

</script>

В оп р о с в то м , нуж но л и с о х р а н я т ь зн а ч е н и е п е р е м е н н о й вн е об ла­ сти в и д и м о сти м ето д а changeScene ( ) . Д л я п е р е м е н н о й message, зн а ч е н и е к о т о р о й с б р асы в ается каж ды й р аз п е р е д н ач ало м р аб о ты м етод а, это го н е тр ебу ется. А в о т п е р е м е н н ая curScene и сп ользует­ ся для п р о в е р к и усл о ви я в н еск о л ьк и х о п е р а т о р а х i f / e l s e , поэтом у е е зн а ч е н и е д о л ж н о с о х р а н я т ь с я в н е за в и с и м о с ти о т в ы зо в а м етода.

В итоге получаем, что переменную message имеет смысл сделать локальной, в то время как переменная curScene в нашем приме­ ре должна быть глобальной.

198

глава 4


принятие решении

Где )кивут мои данные? Е сли п о н я т и е о б л а с ти в и д и м о сти все ещ е о с т ает с я д ля вас н е­ я сн ы м , р а зл и ч н ы е ч ас ти с ц е н а р и я м о ж н о п р е д став и ть в виде к о н т е й н е р о в , в к о т о р ы х ж и вут н аш и д ан н ы е. К п р и м еру, сц е­ н а р и й « П р и к л ю ч ен и й » и м е е т н еск о л ьк о о б л астей ви д и м ости , к о т о р ы м м огут п р и н а д л е ж ат ь дан н ы е. А о к а л ш й Я об ласт ь ГАобал»наЯ^^ ^ереМ бН КйЯ .

^ ^

Глобальная о б ласт ь ви д им ост и или уровень сценария.

видимости или и р о б е н ь мгт ода < s c п p t t y p e = " te x t/jQ V a S C r lp t" > ' скапдеЗсепеО^ ^ ' function сИапдеЭсепеО { if (сигЗсепе == 0) {

■! е1зе if (сигЗсепе == 1) { |

Локальная ' врем енная, ''s

}

Сущ ествует то л ь к о о д н а гл о б ал ьн ая о б л асть в и ­ д и м о сти , все о ст ал ьн ы е я в л я ю т ся л о кал ьн ы м и . Все, со зд ан н о е н а гл о бал ьн о м ур о в н е, видим о и з л ю б о й ч ас ти с ц е н а р и я , в то в р ем я как ви д и ­ м о сть л о к а л ь н ы х д ан н ы х о гр а н и ч е н а .

</ЗСГІрП

част°

зад аваем ы е Б о І їр о с Г ь і

Локальная область видимости для каждого из составных оп ера"Шоров.

в переменной какого типа сохранить мои данные: локальной или глобаль­ ной?

0 ; Это зависит от способа, которым вы собираетесь использовать данные. Хотя есть и обобщенное правило. Все переменные нужно стараться делать локальными, превра­ щая в глобальные только те, которые иначе не работают.

далее >

199


локальная переменная против глобальной

Беседа у камина Локальная и глобальная переменные обсуждают важность рас­ положения данных.

Локальная переменная: Ф о к у си р о вать ся нуж но т о л ь к о н а то м , ч то п р о и с х о д и т вокруг теб я. Я п о н я т и я н е им ею , ч т о п р о и с х о д и т у со сед ей , и о ч ен ь эти м до­ вольна.

Глобальная переменная;

Д руж ищ е, т е б е следует р а с ш и р и т ь свой кру­ го зо р . В ы йди и з своего к о к о н а и исследуй о ст ал ьн ы е ч аст и н аш ей всел ен н о й .

З ву ч и т с о б л азн и тел ьн о , н о м н е н р а в и тс я б езо п а с н о с т ь м о его п о л о ж ен и я . В едь м ен я н е м о ж е т д о стать н и к т о и з в н еш н его м ира. М ож ет б ы ть и так, н о п о н и м аеш ь л и ты , ч т о т в о я м ал ен ькая ж и зн ь б ессм ы сл ен н а в о б щ ей схем е сц ен ар и я? Т ы рож д аеш ься и ум и раеш ь каж ды й раз, когд а в о зн и к ае т т в о й м ал ен ьк и й м и р о к , в т о вр ем я как я тут надолго. П о к а ж и в с ц е н а р и й , ж и в а и я. Ч е с т н о го в о р я , я н е вер ю в р е и н к а р н а ц и ю , а для х р а н е н и я д ан н ы х я т а к ж е важ н а, как и ты . Я п р о с т о н е даю с м о тр е т ь н а себ я всем и каждому.

З а т о , когда сц е н а р и ю нуж но, ч то б ы н е к о т о ­ р а я и н ф о р м а ц и я б ы ла нед о сту п н а вн е о п р е ­ д ел е н н о го ф р а гм е н т а кода, я н езам ен и м а.

Э то да. Н е могу н е п р и зн а т ь , ч то р а з и л и два м ен я и сп о л ьзо в ал и н е п р ав и л ь н о , н о м оим преи м ущ еством я в л я е т с я с п о со б н о сть со­ х р а н я т ь зн а ч е н и е п р и в сех о б стоятел ьствах. К ак то л ь к о сц е н ар и ю тр еб у ется ф р а гм е н т д ан н ы х, п о м н ящ и й свое зн а ч е н и е и доступ­ н ы й отовсю ду, зовут м еня.

Зву ч и т зам ан ч и во , н о я все-таки п р е д п о ­ ч и таю п р и в а тн о с т и д оступ н ость и п о с т о я н ­ ство. И м е н н о п оэтом у л ю ди с ч и таю т, ч т о о б е мы о д и н а к о в о п о л езн ы .

200

глава 4


принятие решении часагю

ЧаДаБаеМые Б оД роС Ь ! Что получится, если в коммента­ рий написать код JavaScript?

; Ничего! Комментарии игнорируются интерпретатором изуа8сг1р1, поэтому, что бы вы туда ни поместили, он этого просто не заметит. Именно поэтому комментарии порой используются в качестве временно­ го хранения кода при попытках отследить проблему или попробовать другой подход к решению задачи. Может ли строчка кода JavaScript заканчиваться комментарием?

0 ; Да. в этом случае код все равно за­ пускается, так как он не является частью комментария. Плюс комментарий вовсе не обязан занимать целую строчку — он на­ чинается с / / и заканчивается с концом строки. Поэтом если за / / находится фрагмент кода, он будет работать.

Почему в конце комментариев не ставится точка с запятой?

! Комментарии не являются операто­ рами JavaScгipt. Они всего лишь предо­ ставляют дополнительную информацию, как сноски в книге. Вам следует помнить, что интерпретатор иауаЗсг1р1 коммента­ рии игнорирует — они предназначены для людей, а не для программы. Что означает «уровень сценария» при создании глобальных перемен­ ных?

; Это самый верхний уровень, рас­ положенный сразу в теге < s c r i p t > . Уровень сценария располагается вне методов и других фрагментов кода, и все, на этом уровне созданное, считается глобальным. То есть оно существует все время жизни сценария и доступно из любой его части.

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

Переменная, созданная внутри со­ ставного оператора, является глобаль­ ной или локальной?

! Составной оператор создает новую область видимости, поэтому все пере­ менные, возникшие внутри него, являются локальными. Их можно рассматривать как временные, так как они возникают и исчезают при каждом вызове составного оператора. Материал, посвященный локаль­ ным и глобальным переменным, вы­ глядит крайне сложным. Это на самом деле так?

; Не совсем. Главное — запомнить, что локальные переменные идеальны для хранения временной информации, которую не нужно помнить вне метода или другого фрагмента кода. Если же данные требуются все время жизни сценария, нужно использовать глобальные пере­ менные. Вы удивитесь, но большинство данных в сценариях обычно является временным, поэтому локальные перемен­ ные используются чаще глобальных.

КЛЮ ЧЕВЫЕ МОМЕНТЫ Комментарии, в частности, напоминают о коде, который необходимо добавить позднее. Не бойтесь писать много комментариев, так как это делает код более понятным. Начало однострочного комментария отмечают двумя косыми чертами ( / / ) .

Глобальные переменные создаются на уровне сце­ нария и сохраняются до конца сценария. Локальные переменные создаются внутри фрагмен­ тов кода и не видны извне. Лучше использовать локальные переменные, так как доступ к ним больше контролируется.

Многострочные комментарии начинаются с / * и заканчиваются * / .

далее >

201


выбор из многих вариантов

Выбор из пяти П о м н и т е н аш его сч а с тл и в ч и к а Э рика? К аж ется, он п о к о н ч и л с п о н ч и к а м и и п ер еш ел н а следующ;ий тур шоу «Заклю чи м сделку?» И т е п е р ь п ер ед н и м с т о и т д ей с тв и те л ь н о сл о ж н ая зад ач а — нуж но в ы б р ат ь о д и н и з п я т и в ар и ан то в .

О боже... кажется, мне не обойтись без помощи.

Ш ТУРМ Каким образом вы написали бы на иауаЗспр! сценарий выбора из пяти вариантов?

202

глава 4


принятие решении

А нельзя ли для этой цели

воспользоваться набором вложенных операторов if/else?

Выбор из пяти З а м е ч а т е л ь н а я идея! Сам по себе о п е р а т о р i f / e l s e п о ­ зв о л я е т в ы б р ат ь о д и н в а р и а н т и з двух, н о н а б о р и з таки х о п е р а т о р о в , вл о ж ен н ы х друг в друга, п о зв о л я е т в ы б и р а ть и з какого угодн о к о л и ч е ст в а в ар и ан то в.

if

( c h o s e n C a s e = = "А ") o p en C ase("А ");

e ls e

if

( c h o s e n C a s e = = "В ")

o p en C ase(" В " ); e ls e

if

( c h o s e n C a s e = = "C ")

o p e n C a se ("C "); e ls e К од р а б о т а е т , но., чт обы добрат ься до последнего чем одана, нужно вы п о лн и т ь п р о ве р к у п я т и услойии, ч т о неэф ф ект ивно-

if

(c h o se n C a se =

"D ")

o p e n C a se ("D "); e ls e

if

(c h o se n C a se =

"E ")

o p e n C a se ("E ");

ПереусАО)кнение конструкции В л о ж ен н ы е о п е р а т о р ы i f / e l s e п р е к р а с н о р аботаю т... н о он и н е э ф ф е к т и в н ы в о сн о вн о м потом у, ч то н е п р е д н а зн а ч е н ы для в ы б о р а и з б о л е е чем двух в ар и ан т о в . Д о с та т о ч н о п о сч и тать, ско л ьк о р а з п р и д е т ся осущ естви ть п р о вер к у услови й , п реж д е ч ем м ы д о б е р ем с я до п о сл ед н его ч ем о д ан а Е. Ч т о б ы его о т ­ к р ы ть, н ам п о тр еб у ется п р е д в а р и т е л ь н а я п р о в е р к а ещ е ч е т ы ­ р е х условий. далее ►

203


желания, надежды и выбор

Разве не здорово было бы вы­ бирать из множества вариантов без набора эти х неэффективных опера­ торов if/e ls e ?

204

глава 4


принятие решений

Оператор switch / case позволяет эффективно выбирать из множества вариантов.

Оператор switch/case Д л я т е х случаев, когд а тр еб у ется сдел ать в ы б о р и з м н о ­ ж еств а в а р и а н т о в , в Jav aS crip t сущ ествует с п е ц и а л ь н ы й о п е р а т о р . О н н а зы в а е т с я s w i t c h / c a s e , по п робуем с еего пом ощ ью о б л е гч и т ь в ы б о р Э рика: В т о р а я ч а ст ь н а ­ звания о п е р а т о р а никак не связана с и м е н е м п ер ем енно й , s w i t c h

(c h o se n C a se )

{ Содерж имое чем одана, выбранного Э р и ко м , — э т о к о н т р о л и р у е м ы й кусок и н ф о р м а ц и и для о п ер а т о р а sw itch /ca se.

К од, определян)ш ,ий, какие дейст вия с ле д у е т п р е д п р и н я т ь , р а сп о ла га ет с я сразу п о сле о п ер а т о р а case. О п е р л т о ^ case п р е д с т а о ля е т в а м все возмож ные вариант ы .

openC ase("С "); b re a k ; ^ _ кЗ и т зл к а н и а б й е т S h возмож ных ве т о к выбора, нем едленно заверш ая р а б о т у о п ер а т о р а s w itc h / case. О п е р а т о р sw itc h /c a se по с т р у к т у р е н а п о м и н а ет больш ой сост авной опер а т о р .

:нени2

Правда или ложь? Оператор s w i t c h / c a s e обладает той же функциональ­ ностью, что и оператор i f / e l s e .

П

П равда

О

Ложь

далее >

205


выбираем

^.

— П рЗЖ Н бНИ б

Правда или ложь? Оператор s w i t c h / c a s e обладает той же функциональностью, что и оператор i f / e l s e .

решение

и

П равда

И

Ложь

У оператора i f / e l s e в качестве проверяемого условия может выступать выражение, в то время как у оператора s w i t c h / c a s e это должен быть просто фрагмент данных.

Анализ оператора switch Т еп е р ь , когда вы п о с м о т р е л и н а о п е р а т о р s w i t c h / c a s e в д ей ств и и , п о с м о тр и м б о л ее в н и м ате л ьн о н а его си н так си с и ф ун кц и о н ал ьн о сть.

switch

Выражение д л я с р а в н е н и я

С о вп а д е н и е 1

Каждый из ва р и а н т о в выбора начинает ся с клю чевого слова case, за к о т о р ы м с ле д у е т значение для сравнения.

Оператор

break

3 - а ' ^

з-а

J - Q - Ш В качест ве у с л о ­ вия и с п о ль зует ся ф р а г м е н т данных, а не выраж ение — с о о т ве т с т ве н н о , оам не нужно оцениват ь его и ст и н н о ст ь.

После ф р а гм е н т а данных, с к о т о р ы м о су щ ест в ля е т ся сравнение, с т а в и т с я двоет очие й не т очка с запят ой.

default

г Необязательный блок "d e fa u lt” ^содержит код, ко т о р ы й за п у с к а е т с я при отсутствии со­ впадений.

а Оператор

□ • а

О п е р а т о р break предот вращ ает з а ­ п у с к кода из д р уги х вет ок.

break Тело о п ер а т о р а заклю чено о ф игурны е скобки.

206

глава 4


принятие решении

Ваш собственный оператор Switch С о зд ать о п е р а т о р s w i t c h / c a s e с л о ж н ее, ч ем о п е р а т о р i f / e l s e , зато о н я в л я е т с я б о л ее эф ф е к т и в н ы м в случае м н о ж ест в ен н о го вы ­ бора. С ледуйте прави лам : У сл о ви е зак л ю ч и те в ско б ки и о т к р о й т е со став н о й оператор ({ ). ©

О

Н а п и ш и т е c a s e и у словие, а п о то м д в о е т о ч и е ( : ). Н а п и ш и т е код, запускаем ы й в случае с о в п а д е ­ н и я . О н м о ж ет б ы ть м н о го стр о ч н ы м . С о став­ н о й о п е р а т о р тут н е нуж ен.

Q

Д о б ав ь те о п е р а т о р b r e a k и то чку с за п я т о й ( ; ).

^

П о ж ел ан и ю со зд ай те б ло к d e f а и 1 1 для случая, когда с о в п ад ен и я отсутствую т. З а к р о й т е с о с та в н о й о п е р а т о р ( } ) .

_

часл1°

_^адаБаеМые БоЦ|=»ос;ьх То есть оператор s w i t c h / c a s e не принимает решений на основании выраже­ ний вида t r u e / f a l s e ?

Q ; Да, в отличие от операторов i f и i f / e l s e , s w i t c h / c a s e принимает ре­ шение на основе тестовых данных. Именно это позволяет выбирать из множества вариантов.

То есть нам всего лишь нужно совпаде­ ние с тестовыми данными?

Q ; Да. в качестве тестовых данных использу­ ется переменная, со значением которой и идет сравнение. Что произойдет при отсутствии ключе­ вого слова b r e a k ?

)удыпе осЗХ Ю роЖ Н ь!

1

Break для безопасно­ сти.

Этот оператор устраняет возможность случайного запуска ненуж­ ных фрагментов кода.

Q ; Оператор b r e a k является разделителем между блоками кода оператора s w i t c h / c a s e . Без них все фрагменты кода были бы за­ пущены просто в порядке очереди, что не имеет никакого смысла, так как выбор при этом не делается. В случае же совпадения запускается код после соответствующего оператора c a s e вплоть до оператора b r e a k . После этого s w i t c h / c a s e завершает свою работу.

далее >

207


операт ор switch о себе

О П Е Р А Т О Р

о

Й Ё Б Ё

Интервью недели: М астер н а все руки

Head First: С паси бо , ч то со гл аси л и сь п о б е ­ сед о в ать с нам и. П ож алуйста, о п и ш и те себя о д н и м словом . Switch: Р азб о р ч и в ы й . Head First: У то ч н и те , пож алуйста. Switch: Я п р ед о став л яю в о зм о ж н о с ть в ы ­ б и р а ть между м н о ж ество м веш:ей. И н о гд а до­ с т а т о ч н о в ы б р ат ь между ч ер н ы м и б елы м , но и н о гд а следует у ч и ты в ать ню ансы . В от тут-то и п о я в л я ю сь я.

Head First: Н о го в о р я т, ч т о о п е р а т о р I f ум еет д ел ать т о ж е сам ое, и н о гд а с м еньш им ко л и ч еств о м кода.

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

Head First: Вы го в о р и л и об эф ф е к т и в н о с т и . К аки м о б р азо м о н а в л и я е т н а ваш у работу? Switch: Я п р и н и м а ю р е ш е н и е н а о с н о в е зн а ­ ч е н и я ф р а гм е н т а д ан ны х. П р о и зв о ж у с р а в н е ­ н и е и о п р ед ел яю , как о й код запустить. Я н е вы ч и сл яю зн а ч е н и я в ы р а ж е н и й и н е требую вл о ж ен н о сти . Я всего ли ш ь б ы стр о п р и н и ­ маю р еш ен и е. Head First: Р асскаж и те о ваш ем друге, о п е р а ­ т о р е B reak. Г о в о р я т, вы неразлучны ? Switch: Д а, б ез о п е р а т о р а B reak я н е см ог бы р а зд ел и ть ф р а гм е н т ы кода. О н д ае т м н е п о ­ н я т ь , когда следует о с т ан о в и т ь в ы п о л н е н и е в ы б р ан н о го блока, и я прекраш ;аю работу, не т р о га я о стал ьн ы е блоки.

208

глава 4

Head First: А ч т о н а с ч е т о п е р а т о р а Case? Switch: С о п е р а т о р о м Case у м ен я о ч ен ь б л и зк и е о т н о ш ен и я , ведь и м ен н о о н п о к а­ зы в ае т м не ва р и а н т ы , с к о т о р ы м и следует ср а в н и в а т ь т е с т о в ы е д ан н ы е. Б е з н его я н е см ог бы п р и н и м а т ь р еш ен и я . Head First; Т о есть о п е р а т о р Case п р ед о с тав ­ л я е т вам в ар и а н т ы , а вы н а и х о сн о в е о п р ед е­ л я е т е , ч т о д елать. А ч т о п р о и сх о д и т , когда со вп ад ен и й нет? Switch: Если н а эт о т случай н е д об авл ен о т ­ д ел ьн ы й код, т о н и ч его . Н о м ой д о б р ы й друг D efault д ает во зм о ж н о сть д о б ави ть т а к о й код. О н и запускается п р и о тсутстви и совп ад ен и й . Head First: Я и н е знал. А как D efau lt уж и вает­ ся с Case?

Switch: П р е к р а с н о . И м н е ч его д ел и ть, каж ды й п р о с т о в ы п о л н я е т свою работу. Case о б р аб а т ы в ае т совп ад аю щ и е р езул ьтаты , в т о в р е м я как D efau lt за б о ти тс я о ситуац и и , когда со в п ад ен и й н е оказы вается. Б о л е е т о го , м не к аж ется, ч т о C ase чувствует себя с п о к о й н е й в п р и су тстви и D efault, т ак как, есл и совп ад е­ н и й н е о б н аруж и вается, о н н а ч и н а е т н е р в н и ­ ч ать. Head First: П он и м аю . Ч т о ж, н аш е вр ем я зак а н ч и в ается . Х о ти те что-нибудь сказать нап оследок? Switch: К о н е ч н о . П о м н и те, ч то н е т н и ч его хуже н е р е ш и т е л ь н о сти . Т ю ф я к о в н и к т о н е л ю б и т. Н а л и ч и е сли ш ком м н о ги х во зм о ж ­ н о с т е й н е о зн ач а ет, ч т о нуж но опускать руки. З в о н и т е м не, и я пом огу вам п р и н я т ь р еш ен и е, к о т о р о е лучш е всего п о д х о д и т для ваш его сц ен ар и я.


принятие решений

Возьми в руку карондаш

П е р е п и ш и те перв ы е д в е сцены « П р и кл ю ч е н и й » , за м е н и в о п е р а ­ то р i f / e l s e о п е р а т о р о м s w i t c h / c a s e .

if

( c u r S c e n e == 0)

(

Ь«1»= = . . « " rt “

^

Lise i f (cutscene == 1) I

Э т о исходная в е р ­ сия кода, в кот о р о й и с п о л ь зуе т с я опера^ т о р if/else.

■if ( d e c i s i o n — i) i Г е Г з Г .Г /'4 о и h av e a r r i v e d a t a c u t e U t t i e h o u s e i n t b e wood . ,

^ 'i s b r / 4 ; u

a r e s t a n d i n g on t b e b r i . . e o v e r i o o K i n . a p e a c e f u l

s t r e a m . ";

далее >

209


решение упражнения

щ^ьт в руку карандаш Вот к а к будут вы глядеть перв ы е д в е сцены « П р и кл ю ч е н и й » п о ­ сле зам ены о п е р а т о р о в i f / e l s e о п е р а т о р о м s w i t c h / c a s e .

Решение if

( c u r S c e n e == 0)

{

m e s s a g r = ^ 4 o u r jou rney b eg in s a t a fo rk in th e ro a d ." ; e l s e i f ( c u r S c e n e == 1) i f ( d e c i s i o n == 1) {

Исходная версия кода.

{

m e s s a g r / 4 o u h ave a r r i v e d a t a c u t e l i t t l e h o u s e i n t h e w o o d s ." ;

}

e lse { m e s s a g r = ^ " ? o u a r e s t a n d i n g on t h e b r i d g e o v e r l o o k i n g a p e a c e f u l s t r e a m . ";

}

З а д а ет новый ном ер и описание сцены , как и в преды дущ ей версии.

1

swiicn {CUrScene) I Оператор case 'предост авляет для сравнения н о м е р Сцены.

case О: curScene = 1 ;fce^fns at a fork in the road.”; break;

В н у т р и каждого о п е ­ р а т о р а case и м е е т СМЫСЛ во с п о л ь зо в а т ь СЯ о п е р а т о р о м if/else для обработ ки р еш ения п о ль зо в а т е ля о переходе к след ую щ ей сцене.

case i : if (decision == i) { curScene = Z ............................. message ~ "You have arrived a t a cute little house in the woods.”', .L . else {

Для остальных

curScene - 3;

сцен использу­ ется аналогичная ст рукт ура.

message = You are standing on the bridge overlooking a peaceful stream ,”;

Закроем операт ор s w itc h /c a se п р и п о ­ м о щ и }.

210

глава 4


принятие решений

Тест-драйВ нового Варианта «Приключений» Т е п е р ь , когда в о с н о в е п р и н я т и я р е ш е н и я в « П ри к л ю ч ен и ях» л е ж и т совсем другая л о ги ка, Э лли н е т е р п и т с я п о с м о т р е т ь н а результат. Н а в е р н о е , и зм е н е ­ н и я будут зам етн ы н ев о о р у ж ен н ы м глазом ...

VJelcONVe t o

ST IC K FIGURE Click e'rtber

buttoN to StariPlease

Не всегда правка сце­ нария меняет его внеш­ ний вид. Но это вполне можно пережить.

У дивл ен ы , ч то н и ч е го н е изм ен и л о сь! Н о ведь о п е­ р а т о р s w i t c h / c a s e п о м ен я л т о л ь к о структуру кода н аш и х « П р и к л ю ч ен и й » , а н е в н е ш н и й вид. К ак ви д и те, и н о гд а и зм е н е н и я п р о и с х о д я т за в аш ей с п и н о й ... в бук­ вал ьн о м см ы сле слова! далее *

211


на чем же мы ост ановимся?

Приключения продол)каются... Н а сам ом деле м ы то л ь ко н ач ал и р а б о т а т ь над и с т о р и е й . Д л я со ­ зд ан и я д ей с тв и те л ь н о и н т е р е с н о г о в еб -п р и л о ж ен и я п о тр еб у ется х о р о ш и й с ц е н а р и й , к а ч е с тв е н н а я г р а ф и к а и д о п о л н и т е л ь н ы й код Jav aS crip t. Куда бы нам т е п е р ь н ап р ави ть ся? Сцена ?

Сцена 8

Сцена ?

Сцена ?

Сцена 9

КОНЕЦ

Сцена ?

212

глава 4


принятие решений

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

Когда не хватает if/e lse ... _

хоРоШо, а ДВа Jiyiffle

С це на 7

ВбеЭенме

f,OMV^O (Svv^t^p) I

С ценаї

Р азвилка на дороге

Хотя оператор if / else кршне полезен, оп имеет ограничения. Например, невозможно выбрать из множества вариантов. Если вы не верите, убедитесь сами.


U -K JT b i

Говорят, что повторение — мать учения.

Заниматься новыми и ин­ тересными делами здорово, но наши дни, как правило, состоят из рутины. Доведенное до автоматизма мытье рук, нервный тик, щелчок на кнопке Reply То АН при получении любого дурацкого сообщения! Кажется, повторение не самая лучшая вещь в этом мире. А вот в мире JavaScript без него никак. Вы удивитесь, как часто бывают востребованы одни и те же фрагменты кода. Здесь вам на помощь приходят циклы. Без них пришлось бы снова и снова набирать один и тот же код.


"стадии" поиска сокровищ

М есто помечено крестом С ам ое с о б л а зн и т е л ь н о е в м и р е —эт о чуж ие зар ы т ы е со кр о ви щ а. В от кар та, к о т о р о й вы см о ж ете в о с п о л ь зо в аться п р и по м о щ и JavaS cript.

3 7 шагов.

О И д и те, п о к а н е увидите скалу в ф о р м е поч атк а.

С н ач ал а 37 ш а­ гов н а восток.

;т указы вает место!

С н ач ал а вам нуж но п о в т о р и т ь д ей ств и е (ш аг) у казан н ое к о л и ч е ­ ств о р аз (37). С д елать 37 ш агов — о зн а ч а е т п о в т о р и т ь о д и н ш аг 37 раз.

Ш аг я вля ет ся п о ­ вт о р я ю щ и м с я Эей ст ви е м .

4,7 сскро.

ГОВ « а

3 7 циклов

3 7 ш агов ~ эт о на сам ом деле 1 -ш аг, повт оренный 37 раз.

О стал о сь п о н ять, каким о б р азо м в Jav aS crip t р еал и зую тся п о в т о р е н и я .

216

глава 5


циклы

Цикл for позволяет повторить код нужное количество раз.

U снова де)кавю... цикл for П о в т о р е н и е в Jav aS crip t р еал и зу ется п р и п о м ощ и ц и клов. Н а п р и м е р , ци кл f o r п о зв о л я е т п о в т о р и т ь ф р а гм е н т кода нуж ное ко л и ч е с т в о раз. О н п р е к р а с н о п о д х о д и т для п о д сч ета к о л и ч е с т в а п о в т о р я ю щ и х с я д ей стви й . С о ст о и т э т о т ц и кл и з ч е т ы р е х частей:

И н и ц и а л и за ц и я

о

И нициализация

И м е е т м есто о д и н р а з в н а­ ч ал е ц и к л а f o r .

©

О

П р о в е р ка условия

о

У сл о ви е п о к азы в ает, следует л и п р о д о л ж а ть в ы п о л н е н и е цикла.

Д е й с тв и е С о б ств ен н о код, к о т о р ы й п о в т о р я е т с я в п р о ц е сс е р а б о т ы цикла.

О б н о в л ен и е в э т о й ч ас ти о б н о в л я ю тся зн а ч е н и я всех п е р е м е н н ы х цикла.

■■■

■■■

■■■

■■■

■■■

'

— V ----- —

Ш ТУРМ

Один шаг цикла. В т о р о й ш аг цикла.

Каким образом четыре стадии цикла f o r помогут нам в поисках сокровищ?

далее >

217


цикл for: подсчитаем

Охота за сокровищами с циклом for Ц и к л f o r по д х о ди т для р а б о т ы с к а р т о й , так как вкл ю ч ает в себя и зв е с т н о е ко л и ч е с т в о ш агов. Его п р и м е н е н и е к п е р в о й ч асти п о и с­ ка будет в ы гл яд еть п р и м е р н о так:

О

О

О

for (var X = 0; X < 37; х-1-+)

Л

И нкрем ент X — э т о т о ж е сам ое, чт о U X = X +- І .

takeStep();

О

В и а у а З сп р Ь о т ­ сч ет раб от ы цикла начинает ся с о , х о т я его мож но н а ча т ь и с 1 .

В от а н ал и з ко д а ц и кл а f o r :

П е р е м е н н о й X п р и с в о и м н а ч а л ь н о е зн а ч е н и е 0. П р о в е р и м , м ен ьш е л и х, чем 37. Если да, п е р ей д е м к ш агу 3 и п р о д о л ж и м ци кл. Е сли н ет, вы йд ем и з ци кла. Запустим код ци кла. В д ан н о м случае эт о ф ун кц и я ta k e S te p (). У вел и ч и м зн а ч е н и е х н а 1 и в ер н е м с я ко втором у шагу.

П о сл е 37 ш агов х ст ан е т р а в е н 37, и ц и кл завер ш и тся . В от каким о б р азо м в Jav aS crip t р еал и зу ю тся повторяю ш ;иеся д ей ств и я.

И нициализация

Q

Ц и к л н а ч и н а е т с я п р и х, р а в н о м 0.

var X = О

П р о в е р ка условия © С ледую щ ий ш аг ц и кл а со в е р ш а ет ся то л ь к о п р и условии, ч т о X м ен ьш е 37.

X < 37

Д ействие

В ы зы вается ф ун кц и я ta k e S te p {).

37 циклов

ta k e S te p О

Обновление ^ З н а ч е н и е сч е т ч и к а х уве^, л и ч и в а е т с я н а 1. Х++

218

глава 5

^

И н к р е м е н т X озн ачает X = X + 1.


циклы

Составные части цикла for К аж д ы й к о м п о н е н т ц и кл а f o r д о л ж ен н ах о д и ться н а п р е д н а зн а ч е н ­ ном ему м есте. В п р о ч ем , сущ ествует м н о ж ество в о зм о ж н о с те й н ап и ­ сать св о й с о б с т в е н н ы й ци кл f o r . На эт олл э т а н е значение с ч е т ­ чика обычно увели ч и ва е т с я или Цикл начинается ум е н ь ш а е т с я на 1. Здесь задает ся с клю чевого слооа начальное значение for. . счет чика.

f

A c tio n

П роверка условия-, оозвраицает ся р е з у л ь т а т tr u e или fake.

) П овт оряю ш ,иеся дей ст ви я м о г у т бы т ь описаны как единичи1?(М^ т а к и с о с т а в ­ ны м о п е р а т о р о м .

М

.

/ Инициализация, проверка цсловия и изменение п о ­ казаний счетчика з а к л ю ­ ч а ю т с я в скобки.

Точка с за п я т о й ' ст а ви т с я после кода инициализации и кода п р о вер ки условия.

-------------------------------------Завершите код, который

сначала предлагает пользователю ввести число больше О, а затем использует его в качестве начального значения счетчика цикла f o r , выполняю­ щего обратный отсчет до начала фильма (4, 3, 2, 1, Roll film!). Перед началом обратного отсчета не забудьте удостовериться, что введенное значение действительно больше 0.

•У п р аж н ен и е

С о х р а н и т е ббеЭенное

число б п е р е м е н н о й -^

^р^Ш гТ т ся

.

^

var count ■= prompt("Enter а number greater than 0:", "10");

далее »

219


решение упражнения

Вот как выглядит код, который сначала предлагает пользователю ввести положительное число, а затем использует его в качестве начального значения счетчика цикла f o r , вы­ полняющего обратный отсчет до начала фильма (4, 3, 2, 1, Roll film!).

нение

ение

Ч исло сохраняет ся в п ер ем ен н о й count.

Пользователю предлагается ' е с т и число.

обрат ны й _от счет

Л

У б еди м ся. чт о c o u n t = p r o m p t( " E n te r а number greater than О:", !^ерем енная ................................................. count больше о if (count > o) { ............. ............... Ф .................................................................................................. w r (var X = count; x > О; у - - ) Г П рисвоим счет ч и ку цикла (х) значение пер ем ен н о й co u n t.

......чаг............................ a le r t(" S ta r tin g in..." + x alertC'Roll F ilm !"^

,

Мй каждом ш аге ц и к ­ ла значение счет чика ум е н ь ш а е т с я на 1 . 'екуицее значение перем енно й count.

} else alertC 'The n u m b e r wasn’t greater th a n o . No m o vie fo r you!");

Н екоррект ны е ■данные. ......................3 —

^ ..................................................................

The number wasn’t greater than 0. No movie for you!

RoUfilml

Специальные места для мачо О б р ат н ы й о т с ч е т до нач ала сеанса — это н е ед и н ств ен н ы й эп и зо д , в ко то р о м ц и кл ы могут б ы ть и сп о л ьзо в ан ы в ки н о ­ те ат р е . М ож ет бы ть, вы слы ш али, ч то м ачо требую т, ч то б ы между н и м и б ы ло пустое кр есл о . П оэтом у С ет и Д ж ей со н р еш и л и создать програм м у M an d an g o , осущ ествляю ш ую п о ­ и ск пусты х кр есел в к и н о театр е. Д рузьям требую тся группы и з т р е х м ест, ч то б ы между ни м и всегда оставал о сь свобо д н ое кресло. Н о п о ка о н и еш;е не зн аю т, как п о д о й ти к р еш ен и ю д ан н о й проблем ы .

220

глава 5

Отсчет за ­ кончен!


циклы

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

Все т р и hhicwKO. свободны!

Все т р и м е с т а занят ы . J

Классно!

Плохо

Т р и свобод н ы х кресла, сто ящ и х п од ряд, даю т н а­ стоящ ем у м ач о нуж ное п р о ­ стр ан ство .

Все в а р и а н т ы , о т л и ч н ы е от т р е х сто ящ и х п о д р я д свобод ­ н ы х к р есел , н е п о зв о л я ю т п о ­ к а за т ь «мачизм».

5озьми1 в руку карандаш _^Возьм Взяв за о сно ву р и с у н о к снизу, п о к а ж и те , ка ки м о б р а з о м при

V

п о м о щ и ц и кл а f o r

вы будете и скать м еста для н а ш и х м ачо.

далее >

221


решение упражнения

Возьми в руку карандаш Решение

И так, вот к а к и м о б р а зо м при п о м о щ и ц и кл а f o r м о ж н о найти по д х о д я щ и е места для м ачо.

П редст авив д о с т у п н о с т ь м е с т а в виде логической п е р ем ен н о й , нужно н а й т и п р и п о м о щ и цикла м р и подряд значения tru e.

-луКонйц цикла.

false

tr u e

false

tr u e

tr u e

tr u e

false

tr u e

false

Н ачало цикла. М е с т о за ­

нят о.

Всего одно м е с т о сво бодно.

М есто

занят о.

Т ри подряд!

Циклы, HTML U свободные кресла О с н о в н ая и д ея п р о гр ам м ы M a n d a n g o п о н ем н о гу ст ан о в и т ся п о ­ н я т н о й , но каким ж е о б р азо м за п и с ать ее в ви д е код а H TM L?

HTM L и гра­ фические Фрагменты для этого прим ера м о ж ­ но скачать по адресу h ttp ://w w w . headfirstlabs. со м /b o o k s / hfjs/.

222

глава 5

<img <img <img <img <img <img <img <img <img

id = "se a tl" id = "seat2" id= "seat3" id = "se at4 " id = "seat5" id = "se at6 " id = "seat7" id = "se at8 " id = "se at9 "

На ст р а н и ц е M andanqo осе кр есла показаны о оиде рисунков.

s r c = ' s e a t_ u n a v a i l . p n g " a l t - " U n a v a i l a b l e s r c = ' 'se at_ a v a i l . p n g " a l t = " A v a i l a b l e " /> s r c = ' 'se at_ u n a v a i l . p n g " a l t = " U n a v a i l a b l e " /> sr c = ' 'se at_ 'avail.png" a l t = " A v a i l a b l e " /> s r c = 'se at_ "avail.png" a l t = " A v a i l a b l e " /> s r c = 'seat_ "avail.png" a l t = " A v a i l a b l e " /> s r c = ' s e a t ^ unavail.png" a l t = " U n a v a i l a b l e " /> s r c = ' s e a t a v a i l . p n g " a l t = " A v a i l a b l e " /> s r c = " s e a t "unavail.png" a l t = " U n a v a i l a b l e " />

Вам нуж но н е т о л ь к о п р о с м о т р е т ь п р и п ом о щ и ц и к л а гр а ф и ч е с к и е ф р а гм е н т ы с и зо б р а ж е н и е м кр есел , н о и с о х р а н и т ь и н ф о р м а ц и ю о д о сту п н о сти м ест в коде JavaS cript.


циклы

М еста, как переменные П ер е д тем как п р и сту п и ть к в ы п о л н е н и ю ци кла, нуж но п р ед став и ть и н ф о р ­ м ацию о д о сту п н о сти каж дого кр есл а в ви д е кода JavaS cript. Д л я р я д а и з д евя ­ т и кр е с е л вам п о тр еб у ется д ев я т ь л о ги ч ес к и х п ер ем ен н ы х .

var seatl = false;

Информации 0 доступности каждого м е с т а х р а н и т ­ ся в виде пер е м е н н о й т и п а boolean.

var seat2 = true; var seats = false; var seat4 = true; var seats = true; ^

_True о зн ачает , ч т о м е с т о свободно.

var seat6 = true; var seat? = false;

False о зн ачает , чт о м ест о з а ­ нят о.

var seats = false;

Получается, я дол­ жен просматривать различные фрагменты данных с помощью все­ го одной переменной?

var seat9 = false; Т е п е р ь все го то в о д ля со зд ан и я ц и кл а f o r , к о т о р ы й будет и ск ать т р и сво бо д н ы х м еста подряд.

о

о

for (var і = 0; і < 10; і++) { if (seatl)

Вы не м ож ет е м е н я т ь и м я п ер ем ен н о й при каж дом прогоне цикла!

} К аж ется, у нас п р о б л ем а. Ц и к л f o r д о л ж ен п р о в е р я т ь зн а ч е н и я р а зл и ч н ы х п е р е м е н н ы х s e a t н а каж дом ш аге. Н о т а к как все п е р е м е н н ы е и м ею т р а зн ы е и м ен а, эт о п о п р о сту н ево зм о ж н о .

U T V P M Каким же образом сохранить информацию в том случае, когда отдельные переменные не работают?

далее *

223


массив данных

Массивы Jav aS crip t п о зв о л я е т с о х р а н я т ь н а б о р ы д ан н ы х в о д н о й п е р е м е н н о й о с о б о го ти п а , н азы в а е м о й м ассивом . М ассив, как и о б ы ч н а я п е р е м е н ­ н ая, и м еет всего одно им я, за т о у н е го ц е л ы й н а б о р м ест для х р а н е ­ н и я. П р е д с та в ь те себе ш каф с п о л к ам и — это о д и н п р ед м ет м ебели, н о с м ассой м ест для х р а н е н и я . К аж д ы й эл ем ен т м асси ва с о с то и т и з двух ч астей : зн а ч е н и е и уни каль­ н ы й клю ч, по к о то р о м у осуш ;ествляется доступ к этом у зн ач ен и ю . В р о л и кл ю чей о б ы ч н о вы ступ аю т ц и ф р ы , н а ч и н а я с нуля. Т ак и е кл ю чи о б ы ч н о н азы в аю тся ин дексам и : Э т о т массив хранит пят ь

фрагментов

Индексы массива начинаются с О и подсчит ывают коли чест во

Численный ключ или индекс и с п о л ь з уе т с я для дост упа к значению.

элементов.

Д л я с о зд ан и я м асси ва д о ст а т о ч н о д ать зн а т ь об это м JavaS cript. П о больш ом у счету вы с о зд аете о б ъ ект.

var showTime = new Array();

_Новый о б ъ ект т и п а A rra y .

^ м я массива. Создание нового объекта.

Не беспокойтесь о том, что массив является объектом. Д л я ваш и х текущ их ц ел ей эта и н ф о р м а ц и я н е и м е ет осо б о го зн ач ен и я . П о д р о б н о м ы п о го в о р и м об о б ъ ектах в главах 9 и 10.

224

глава 5


циклы

Значения сохраняются с ключами М ассив го то в, т е п е р ь в н его м о ж н о д о б а в л я ть д ан н ы е. Д л я до­ ступа к ни м будут и с п о л ь зо в ать с я ключи. К аж ды й клю ч ун и ка­ лен и св я зан со сво и м ф р а гм е н т о м дан ны х. Сохраняем ое в п ер ем ен н о й

И м я п ер ем ен н о й т и п а arra y. И ндекс эл е м е н т а м ассива ука зы ва ет ся в ква др а т н ы х скобках. Э то т код зад ает п е р в ы й эл е м е н т м асси ва sh o w T im e, п р и с в аи ­ вая ему зн а ч е н и е в р ем ен и . В о зм о ж н а как ин ди ви дуальн ая, т а к и груп п о вая и н и ц и а л и за ц и я эл е м е н то в м ассива.

Список всех значений через за п я т у ю .

var ShowTime = [ "12:30", "2:45", "5:00"Г "7:15", "9:30" ];

, — и е р в а я чаете? п р о цедуры создания м ассива о с т а е т с я без изм енений.

V ^ д

о

Не заб удьт е м очки с за п я м о й в конце.

Список э л е м е н т о в м а с с и л ж е н бы т ь заклю чен д квадрат ны е скобки, “

П о д о ж д и те, это н е п о х о ж е н а со зд ан и е о б ъ екта. Ч т о п рои сходи т? В д ан н о м случае м ы заб егаем в п ер ед и создаем н е пустой о б ъ ект, а сразу м ассив со всем и его зн а ч е н и я м и . И м е н н о о н и п е р е ч и с л е н ы в к вад р атн ы х скобках. Т е п е р ь , когда м ассив за п о л н е н д ан н ы м и , мы го то в ы с ни м работать!

В о зь м и т е последний э л е м е н т м ассива

alert("The late movie starts at " + showTime[4] +

Массивы сохраняют целые наборы данных в одном месте.

The late movie starts at 9:30.

далее ►

225


массив о себе

М Л Р С И В

О

(Й Й В Ё

И нтервью н ед ел и :

С екреты х р а н и те л я д а н н ы х

Head First: Р ады в и д еть вас, М ассив. С лы ш ал, ч то вы ум еете с о х р а н я т ь н а б о р ы дан ны х. Массив: Д а. Е сли вам нуж но с о х р а н и т ь 50 ст р о к т е к с т а и л и 300 ч и сел , о б р ащ ай тесь. Head First: З в у ч и т зам ан ч и в о . Н о ведь д ан н ы е м ож но сохранить и в обы чной перем енной. Массив: Р азум еется. А н а р або ту м о ж н о х о д и ть б о си ко м . В идиш ь л и , н е к о т о р ы е в ещ и м о ж н о д е­ л а ть р а зн ы м и спо со б ам и . В д ан н о м случае б олее у д о бн ы й сп о со б х р а н е н и я н а б о р о в д ан н ы х п р ед ­ ставл яю и м е н н о я.

Head First: Д а, я п р е д п о ч и т а ю х о д и ть н а р аботу в б о ти н ках . Н о ч ем и м е н н о вы лучш е других?

Массив: П р ед став ь, ч т о т ы ведеш ь д н ев н и к . К аж ­ д ы й день. Ч т о со всем и эт и м и с т р ан и ц а м и ст ан е т ч е р е з н еск о льк о лет? Head First: А ч то с н и м и м о ж ет случиться? Массив: Т ы сей ч ас п р ед став л яеш ь с т р ан и ц ы , каким -то сп о со б о м с о е д и н е н н ы е друг с другом. А есл и п р е д с та в и ть о б ы ч н ы е л и с т ы бумаги, склад ы ваем ы е в коробку? Р ан о и л и п о зд н о , теб е с т ан е т сл о ж н о их с и с те м ати зи р о в а ть . Head First: Т ы нам екаеш ь, ч т о с о х р а н е н и е д ан ­ н ы х в м асси ве — эт о то ж е сам ое, ч т о и со е д и н е­ н и е о тд ел ь н ы х л и с т о в в книгу? Массив: И м ен н о . Ведь я си стем ати зи р у ю д ан н ы е, о б ес п е ч и в а я к ни м л е гк и й доступ. В д н е в н и к е т ы м ож еш ь н а й т и нужную зап и сь н а о п р е д е л е н н о й ст р ан и ц е . В случае м асси ва вм есто с т р а н и ц исп ользую тся клю чи.

Head First: Я слы ш ал п р о и н д ек сы м ассива. А ч то т а к о е «клю чи»?

226

глава 5

Массив: К лю ч ом н а зы в ае т ся ф р а гм е н т и н ф о р м а ­ ц и и , п р и п ом о щ и к о т о р о г о л егк о н а й ти нуж ны е д ан н ы е. И н д екс —э т о всего л и ш ь ч а с т н ы й случай клю ча. Т аки м о б р азо м , н о м е р а с т р ан и ц в д н ев н и ­ ке я в л я ю т ся н е т о л ь к о клю чам и, н о ещ е и и н дек­ сам и.

Head First: Я п о н ял . А каким о б р азо м все это с в я за н о с циклам и? Массив: В п р и н ц и п е я могу с о х р а н я т ь д ан н ы е и б ез уч асти я ц и кл ов. Н о их пом ощ ь уп рощ ает доступ к м ои м эл ем ен там . Head First: К аки м образом ? Массив: П о м н и те, ч т о ц и кл ы и сп ользую т ч и с ­ л е н н ы й счетч и к? О н м о ж ет служ ить и в к ач естве и н декса, в и т о ге о б л е гч а ется ц и к л и ч ес к и й п р о ­ см о тр х р а н и м ы х во м н е дан ны х. Head First: Т о ес ть м ож н о и сп о л ьзо в ат ь сч е т ч и к ц и кл а в кач естве и н д ек са м ассива? Массив: И м е н н о так. Head First: Э то п отрясаю щ е! Массив: Я знаю . И м е н н о п оэтом у м ен я т ак л ю б ят с ц е н а р и и , в к о т о р ы х н еоб ходи м ц и к л и ч е ск и й п р о с м о т р д ан н ы х. Н ес к о л ьк о с т р о ч е к кода, и вы л егко п р о с м а т р и в а е т е ц е л ы й м ассив. Head First: М огу в о о б р ази т ь . С паси бо, ч то рас­ сказал и о себе и о ваш ей со в м ес тн о й р а б о т е с ци клам и. Массив: Н е за ч то. В сегда р ад пом очь!


циклы

Возьми в руку карандаш Н а п и ш и те ко д со зд ан и я м ассива s e a t s для п р о гр ам м ы M a n d a n g o , а затем п р о с м о тр и те в ц и кл е е го элем енты , выводя для пользователя и н ф о р м а ц и ю о д о с ту п н о с ти к а ж д о го из кр есел .

_

часвдо

чадаБаеМые В опросы Возможен ли бесконечный цикл

J y * Можно ли использовать в цикле

fo r?

f or составные операторы?

Q ; Страшный бесконечный цикл? Конечно, вы можете запрограммировать цикл, который не закончится, пока вы не перезагрузите страницу. Но такие циклы считаются вредной вещью, так как не дают сценарию перейти к следующей задаче, — их можно считать эквивалентом заблокированного приложения.

Q ; Конечно! Более того, во всех случаях, кроме самых простых сценариев, вам придется их использовать.

хотя это и не совсем удобно. Поэтому если у вас нет на то веской причины, не начинайте нумерацию элементов массива с чисел, отличных от нуля. Сохраняемые в массивах данные должны принадлежать к одному типу?

Когда результатом проверки условия становится значение false, выполняется ли цикл в последний раз?

Бесконечный цикл возникает или при некорректном обновлении счетчика шагов, или в случае, когда он не меняется и результатом проверки условия всегда является значение f a l s e . Поэтому всегда следует тщательно проверять

Q l Нет. Операторы в цикле for выполняются, только когда проверка условия дает результат true. В противном случае происходит немедленный выход из цикла и никакой код не запускается.

условие выхода из цикла f o r . Понять, что у вас бесконечный цикл, можно по тем признакам, что сценарий долгое время не выполняет никаких действий.

3 * Первым индексом массива всегда является О?

0 ; Вовсе нет. Все зависит от предназначения массива. Например, если вы хотите циклически просмотреть массив оценок и вычислить среднюю, вы не сможете этого сделать, если часть значений будет принадлежать, например, к логическому типу. Поэтому, несмотря на наличие принципиальной возможности сохранять в массив данные различных типов, лучше этого не делать.

Q ; и да, и нет. По умолчанию нумерация всех числовых массивов начинается с 0. Но это можно переопределить, начав нумерацию с любого другого числа,

далее >

227


решение упражнения

Возьми В руку карандаш Решение

И так, вот код м ассива s e a t s для п р о гр ам м ы M a n d a n g o , которы й при п о м о щ и ц и кл а п р о в е р я е т места в ки н о те а тр е и с о о б щ а е т об их д о сту п н о с ти пользователю .

л

Так как индексы м ассива на чи на ю т ся с О, начнем с О и сч ет ч и к цикла. Х о т я в данном случае мож но было об ойт ись ч и с ло м я, лу ч ш е и с п о л ь ­ зо в а т ь свойст во len g th на случ а й , если длина м а сси ва п о т о м и з м е - ^ ^ нит ся. С чет чик цикла и с п о ль зуе т с я в ка чест ве и н д ек­ са м ассива и по очереди д а ет до с т у п ко всем его элем ент ам .

Значения м ассива у к а з и б й н .т с я через за п я т у ю

ские значения.

I

единицу.

v a r sea ts - [ false, tr u e , false, tr u e , tr u e ,T r u e , false, tr u e , ft fo r (v a r I = O; і < seats.length; ;V+) { if (seats[ij) ■Щa lertC 'S ea t “ + і +

.............. k : is available.");

else a lertC 'S ea t " + і + " is n o t available.");

Seat 1 is twaiSable. Seat Оis not avaitable.

A

Циклы for повторяют фрагменты кода JavaScript

228

ув е л и ч и в а е м

\

В за ви с и м о с т и о т т о го , д о ст уп н о м е с т о (tru e ) или н ед о ст уп но (raise), б уд ут п о я вля т ь с я разны е окна диалога.

КЛЮ ЧЕВЫЕ МОМЕНТЫ

^

заданное число раз.

Массив хранит набор фрагментов данных, но при этом имеет всего одно имя.

Операторы инкремента (++) и декремента (— ) по­

Доступ к элементам числового массива осуществля­

зволяют легко менять показания счетчика цикпа.

ется с помощью индексов.

Массив — это способ хранения наборов данных в одном месте.

Счетчик цикла удобно использовать для доступа к данным числового массива.

глава 5


циклы

О т JavaScript к HTML Н а д ан н ы й м о м ен т д о сту п н о сть к р есел п р е д с тав л ен а в виде м асси в а л о ги ч еск и х зн а ч е н и й . Т е п е р ь нам нуж но п р е о б р а зо в а т ь эт о т м асси в в н а б о р и зо б р а ж е н и й H T M L (их м ож н о скач ать п о адресу http://www.headfirstbbs.com /books/hJjs/), к о т о ­ р ы е будут п о к азы в ать св о б о д н ы е к р е с л а н а веб -стр ан и ц е M an d an g o .

var seats = [ false, true, false, true, true, true, false, true, false ]

71

Mandartgo ~ Thg

Movie Ttcfeei Finder

______

В ы гл яд и т все п р е к р а сн о , н о п р о б л ем а в то м , ч т о у нас н е т кода, п ер ево д ящ его м ассив л о ги ч ес к и х эл ем ен то в в визу ал ьн ы е эл ем ен ты н а веб-страни це.

Гы турм Каким образом вы реализовали бы связь между массивом логи­ ческих элементов иауаЗспр! и картинками на веб-странице?

далее ►

229


я вижу... место!

Визуализация кресел С в я зы в ая м ассив Jav aS crip t с к а р ти н к а м и , у бедитесь, ч то г р а ф и ч е с к и е ф а й л ы п о л н о стью доступн ы , затем о п р е д е ­ л и т е д ля себя, как£1я к а р т и н к а будет со о т в ет с т в о в ать каком у со сто я н и ю . Н ач н ем с р е ш е н и я п о сл ед н ей задачи.

I

по являет ся

Доступно М е с т о уж е ,, занят о. Нв0ОСтупНО

1001 К \llOiOl Ш ои 101оіц

Э т о М ест о дост упно!

5еаІ_ауаіІ.рпд

5еа1_8е1ес1.рпд 8еаІ_ипаУ8іІ.рпд

С оо тветству ю щ и е гр а ф и ч е с к и е ф а й л ы н а зн а ч е н ы атрибуту з г е в Н Т М Ь -коде и зо б р а ж е н и й :

<ітд id»"seat8" згсв"зеаі_ипауаі1.рпд" alt="UnavailaЫe" /> П а р а м е т р IV о п р е д е л я ­ е т с о о т в е т с т в и е меж оу э л е м е н т а м и м ассива —— ы изображ ениями — он должен начинат ься с О и за ка н ч и ва т ься Я, как и индексы м ассива.

Т е п е р ь вам нуж но в ц и к л е п р о с м о т р е т ь м ассив л о ги ч еск и х эл е­ м ен тов, со п о с та в и в и зо б р а ж е н и е с каж ды м Н Т М Ь -тегом < 1 тд > н а с т р ан и ц е . Ф ак ти ч еск и вы будете и сп о л ьзо вать уже зн ак о м ы й вам ци кл п р о с т о с другим н а б о р о м дей стви й : О

О

\ 230

глава 5

П р и с в о й т е счетч и ку ц и кл а 1 зн а ч е н и е 0. У д о сто вер ь тесь, ч то 1 н е п р ев ы ш а ет 9. Если это так, п е р е й д и ­ т е к ш агу 3, в п р о т и в н о м случае в ы й д и те и з цикла.

О

З ап у сти те код, задающий изображение кресла.

^

У в ел и ч ьте зн а ч е н и е 1 н а 1 и в е р н и те с ь к ш агу 2.


циклы

IJoAj^ogHo про И н и ц и а л и за ц и я м ест в п р о гр а м м е M a n d a n g o осущ ествл яется п р и п ом о щ и ф у н кц и и i n i t S e a t s O , ц и к л и ч е с к и со п о ставл я ю щ ей м асси в Jav aS crip t с и зо б р а ж е н и я м и кресел.

in it^ e a ts ()

С чет чик цикла

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

Проверяет,, все ли м ест а были просм от рены .

4UU

о

function initSeats O' { ^ / / Задаем вид-К ртсел X for (var i = 0; i < s eats.length; i++) { if (seats[i]) { // Вид доступных кресел i).src documdht.getElementByld("seat" i).alt docujjifent.getElementByld ("seat iocuafent.( elsзе/ { 11 Вид занятых кресел document.getElementByld{"seat" document.getElementByld("seat"

i ) .src i) .alt

У величение счет чика цикла на 1 .

"seat_avail.png"; "Available seat";

"seat_unavail.png " ; "Unavailable seat";

}

Если перемен,ная s e a t и м е е т

Л

значение tr u e ,

п о м е ч а е м кресло

В ка ч ест ве п а р а м е т р а ID к р есла в ы с т у п а е т сч ет ч и к цикла.

как до ст уп н о е.

<body onl <div St <img <img <img <img <img <img <img <img : <img ; </div> </body>

=" in itS e a ts 0 ;" > - " m a r g i n - t o p : 75px; t e x t - , a l i g n s e a tO " s r c = " " a l t = "" /> " s e a t l " src=" " a l t = " s e a t 2 " s r c = " " a l t = "" /> Am и at ' s e a t 3 " s r c = " " a l t = "" /> ped: ' s e a t 4 " s r c = " ’" a l t = .... Эля ’s e a t s " s r c = " ' " a l t = .... ’s e a t 6 " s r c = " ' ' a l t = ' ---/> ' s e a t ? " s r c = " ' ' a l t = ' ... s e a t s " s r c = " '' a l t = ' / X b r />

se a t и м е е т значение false

(

® id эт о го ‘изображения 'seat&".

</html>

далее *

231


переменные поиска

Поиск любых свободных кресел Т е п е р ь , когда и н и ц и а л и за ц и я зав ер ш ен а, м о ж н о п е р е й т и к поиску, р а д и к о т о р о го , со б ств ен н о , и б ы ла задум ана п р о гр а м м а M an d an g o . С ет и Д ж е й с о н реш и л и , ч т о сн ач ал а и м е е т см ы сл н а п и с ать ал го р и тм п о и с к а о д н о го сво б о д н о го м еста. В и т о ге м ы п од ой д ем к р еш ен и ю сл о ж н о й зад ач и п о с т е п е н н о , р еш ая б о л ее п р о с т ы е в ар и ан ты . Д л я п о и ск а св о бо д н о го м еста нам п о тр еб у ется п ер е м е н н а я , отслеж иваюш,ая р езу л ьтат вы бора. Если э т о глобальная п е р е іу м е н н а я , т о она б у д е т д о ­ с т у п н а для всего сценария.

П е р е м е н н а я , храняш ,ая и н ф о р м а ц и ю о в ы б р ан н о м кресл е, будет нуж на нам н а п р о т я ж е н и и всей ж и зн и с ц е н а р и я , п о э т о ­ му о н а д о л ж н а б ы ть гл о бал ьн о й . П р и с в о и м е й и м я s e l S e a t . И м е н н о в эту пер ем ен н у ю ф у н кц и я i n d S e a t () будет со х р ан я т ь и н дек с в ы б р ан н о го кресла. А какое значение указывает \ на невыбранные кресла? J

С ет задал х о р о ш и й во п р о с. П е р е м е н н а я s e l S e a t х р а н и т и н ф о р м а ц и ю о в ы б р ан н о м кр есл е, т о есть ч и сл о о т О до 8. А как б ы ть в т е х случаях, когд а п о л ьзо в а т е л ь п о к а н е вы б р ал н и од н ого вар и а н т а. Д л я это го нам п о тр еб у ется с п е ц и а л ь н о е зн ач е н и е. П усть эт о будет 1. И м е н н о тако е н ач ал ь н о е зн а ч е н и е д о л ж н а и м еть п е р е м е н н а я s e l S e a t . П ерем енной selS ea t присвоено начальное значение - 1 . Ведь сценарий на чи на ет работ у^ когда ни одного м е с т а ещ е не выбрано. ' ■—

var selSeat = -1;

И так, р а б о т а над п е р е м е н н о й в ы б о р а м еста о к о н ч е н а, и все го то в о для н а п и с а н и я ф у н кц и и £ i n d S e a t {). Э та ф у н кц и я будет п р о с м а т р и в а т ь все м еста, н ах о д и ть н е за н я т ы е и сп р аш и в ать п о л ьзо в ат е л я, н е х о ч е т л и он за б р о н и р о в а т ь и м е н н о эт о м есто. Р азум еется, для ц ел ей настояш ;их м ачо эт а п р о гр а м м а п о к а н е п од ходи т, н о м ы д ви ж ем ся в нуж ном н ап р авл ен и и !

232

глава 5


циклы

Магниты JavaScript Ф у н к ц и я £ i n d S e a t ( ) д о л ж н а и скать незан яты е кр есл а и п р е д ­ лагать их пол ьзователю , которы й м о ж е т к а к п о д тв ер д и ть бр о н ь , та к и вер нуть ся к д а л ь н е й ш е м у пои ску. В оспол ьзуйтесь м а гн и та м и , чтобы за в е р ш и ть код.

U a -o , if

>= 0)

( =

-

„ р о „ = .е .„ .е п о „ о р и у .

{

1;

О; } //

п о и с к с в о б о д н о г о м е с т а с р е д и в с е х в о зм о ж н ы х

,0 .

.р е е л ,

^

//'в ы д е л я е т 'к р е с л о и обн овляет его вид

= І; docu m e n t . q e t E l e m e n t B y l d C 's e a t "

+ i ) ■....................

s e a t ^ s e l e c t .р g

document.,etEle»„tById|-seat" t i) ........ ' /,

по л ь зо в ател ю „ р е д л .г а е .о я = oo„£l»(-Seat

принять „реллож еннм й в а р и а н , - *

,1 t 11

* - 1=

ayailable.

Aoceptr',;

Vdi- ............

" " /)'п 'о л ь з о в 'а т е 1 1 Ь ^ о т к а з а л с я ,

............. =

-

продолжаем поиск

1;

г, d o c u m e n t.g e tE le m e n tB y ld ( s e a t

+

„ -Г Л d o c u m e n t.g e tE le m e n tB y ld ( s e a t

+ it = "С вободное м е с т о " ; + i ) ....................

initSeats

±)

+ D •..................

accept

= "se a t a v a il.p n g " ;

IselSeat

seats[i]

далее ►

233


решение задачи с магнитами

Решение задачи с магнитами И так, вот к а к д о л ж н а вы глядеть ф ункци я f i n d S e a t ( ) , ищ ущ ая с в о б о д н о е м есто и п р е д л а га ю щ а я им воспользоваться.

fu n c tio n fin d S e a tO { / / Е с л и м е с т о уже в ы б р а н о , if

п р о и з в е д и т е повторную инициализацию

«ре««*“

(

Показываемые п о л ь зо в а т е л ю номера м е с т на единицу больше реальных., т а к каь

иск заново. }

П о и с к с в о б о д н о г о м е с т а с р е д и в с е х в о зм о ж н ы х кинот еат рах f o r ( v a r ii = 00; ; ii < sseats.xengta; e a t s . l e n g t h ; iхт-г; + + ) {x / / П р о в е р к а д о с т у п н о с т и р а с с м а т р и в а е м о г о в д а н н ы й м о м е н т к р е с л а ну м е р а ц и я начи ____ 1 ________ _ ^ иается с 1 , а не ^ ------------- — --------------- -- ^ Если м ест о свободн свободноJ с О. s e a t s [х] 1 if I5еаЬ$11] и м е е т значе

//

3

есло и обновляет его вид

selSeat

}

i;

+ i)

d o c u m e n t.g e tE le m e n tB y ld (" s e a t"

+ i) .

П ользователю п р е д л а г а е т с я принять пре

!accept~|j

Проверяем,, согласился ли пользователь занять место. ■

( i + 1)

co n firm ("S eat

accept

234

■= " s e a t _ s e l e c t . p n g " ;

d o c u m e n t.g e tE le m e n tB y ld C 's e a t"

//

±гие.

;нный в а р и а н т + " is

a v a ila b le .

A cc e p t? ");

{

1ЛЬ о т к а з а л с я , =

= "Y our s e a t " ;

-

продолжаем п оиск

1;

document. g e t E l e m e n t B y l d ( " s e a t '

+ i) •

" s e a t_ a v a il.p n g " ;

document.g e t E l e m e n t B y l d ( " s e a t

+ i) •

"A v a ila b le

глава 5

se a t";


циклы

проверка П е р в а я в е р с и я п р и л о ж е н и я M an d a n g o и сп о льзует ци кл f o r и м ассив д ля п о и с к а о д и н о ч н ы х сво б о д н ы х м ест. И я в ­ л я е т с я в п о л н е ф у н к ц и о н ал ь н о й , х о т я и н е для м ачо.

Так как кресло но м ер 4 каж ет ся е м у подходящ им , п о л ь зо в а т е л ь щ е л к а е т на кнопке ОК.

JasissiJ

Seat 4 is avaHable. Accept?

далее >

235


цикл за циклом...

Бесконечные циклы П о и с к н е за н я т ы х о д и н о ч н ы х м ест с т е х н и ч е с к о й т о ч к и зр е н и я р а б о т а е т х о р о ш о , в о т т о л ь к о ц и кл н е зн ает, когд а ему следует п р е к р а т и т ь свою р а б о ­ ту. Д аж е п о сл е т о го , как п о л ь зо в а т е л ь за б р о н и р о в а л себе м есто, щ елкнув н а к н о п к е О К , п е р е б о р и п о и с к д ал ь н ей ш и х сво б о д н ы х м ест п р о д о л ж ается.

П о льзо ва т ель уж е вы брал себе кр есло но м ер 4 ,а п р о гр а м м а все продол ж ает поиск.

236

глава 5

'

м

т

я

я


циклы

Условие выхода из цикла Т ак как п р и ч и н о й слиш ком б о льш о го у сер д и я п о и ск о в о й п р о гр ам м ы , судя п о всему, я в л я е т с я б ес к о н е ч н ы й ц и кл , Д ж е й с о н р е ш и л в н и м ател ь­ н е й п р и с м о т р е т ь с я к циклу f o r в ф у н кц и и f i n d S e a t ( ) .

co n firm Q п р е д л а га е т п о л ь з о ­ в а т е л ю о т в е т и т ь на вопрос д а /н е т , возвращ ая значение tr u e (да) или false (нет ).

fo r 11

if

( v a r i = 0; i < s e a t s . l e n g t h ; i+ + ) { П р о в е р к а д о с т у п н о с т и р а с с м а т р и в а е м о г о в_^5 ййны й м о м е н т к р е с л а (se a ts [ i ] ) { / / В ы д е л я е м к р е с л о иу(!Гбновляем е г о в и д s e l S e a t = 1; d o c u m e n t.g e tE le m e n y fe y ld C se a t" + i ) . s r c d o c u m e n t.g e tE le m e r* B y Id ("se a t" + i ) . a l t

= "s e a t_ se le c t.p n g " ; = "Y our s e a t " ;

/ / П ользователю г ^ д л а г а е т с я п рин ять предложенный в а р и а н т v a r a c c e p t = c o n f i r m ( " S e a t " + ( i + 1) + " i s a v a i l a b l e . A c c e p t ? " ) ;

-i-£. ( 'a r^ c e p t)

{ J

I I Пользователь отказался, продолжаем поиск selSeat = -1; document.getElementById("seat" + i).src = "seat_avail.png"; document.getElementByld("seat" + i).alt = "Available seat";

К огда п о л ь зо в а т е л ь б р о н и р у ­ е т свободное м е с т о , ничего не п р о и схо д и т , и ц и кл продолж ает р а б о т у.

Э т о т код за п у с к а е т с я , если M 3 o 6 a m e A t> от казы вает ся б ронироват ь свободное м ест о.

П р и щ ел ч ке н а к н о п к е C an cel п е р е м е н н о й s e l S e a t п р и с в аи в а е тс я зн а­ ч е н и е -1 (н и ч е го н е в ы б р ан о ), и ци кл п р о д о л ж ае т работу. О д н ако н ет кода, к о т о р ы й в ы п о л н я л ся б ы п осле б р о н и р о в а н и я сво б о д н о го м еста. С о д н о й с т о р о н ы , эт о х о р о ш о , т а к к ак п о зв о л я е т п е р е м е н н о й s e l S e a t зап о м н и т ь в ы б р ан н о е зн а ч е н и е . А с другой — н и ч т о н е м еш ает циклу п р о д о л ж и ть п о и с к сво б о д н ы х м ест.

Ш ТУРМ Что должно происходить при щелчке на кнопке ОК и бронировании места?

далее ►

237


перерыв

прерывание действия П р о б л е м а с кодом п р и л о ж е н и я M an d a n g o в том , ч то вам нуж но б ы ло вы х о д и ть и з ц и к л а сразу ж е п о сл е б р о н и р о в а н и я кресл а. Э того м о ж н о д о б и ться, к пр и м ер у , путем п р и с в о е н и я счетч и ку ц и к л а f o r зн а ч е н и я , п р ев ы ш аю щ его длину массива. В э т о м случае, про вер ка .у с л о в и я п р и в е д е т к п р е р ы в а ­ н и ю цикла... но е с т ь и долее изящ ны е ва р и а н т ы реш ени я проблем ы .

i = seats.length + 1;

Д а н н ы й код я в л я е т с я зам еч ател ьн ы м о б х о дн ы м м ан евром , н о е с ть и б о лее п р о с т о й путь вы хода и з цикла. Э то о п е р а т о р b r e a k , со зд ан н ы й с п ец и ал ь н о для п о д о б н ы х случаев.

З а с т а в л я е т нем едленно вы й т и из цикла.

З а в е р ш а е т все операции на т е к у щ е м ш аге ци кла , п р и н у д и т е л ь н о переводя на следую щ ий.

О б н ар у ж и в о п е р а т о р b r e a k , ц и кл н ем ед л ен н о зав ер ш а ет работу, и гн о р и р у я п роц едуру п р о в е р к и условия. Т аки м о б р азо м , д ан н ы й о п е р а т о р д ае т вам в о зм о ж н о сть в ы й т и и з ц и к л а в л ю б о й м ом ент. С н и м б л и зк о свя зан о п е р а т о р c o n t i n u e , к о т о р ы й п р е к р ащ ае т в ы п о л н е н и е текущ их о п е р а т о р о в б ез вы ход а и з цикла. Д ругим и сл овам и, о п е р а т о р c o n t i n u e п ри н у д и тел ьн о п е р е в о д и т ц и кл на следую щ ий шаг.

continue;

О п е р а т о р ы b r e a k и c o n t i n u e по­ зв о л я ю т н а с т р а и в а т ь р або ту ц и кл о в нуж ны м вам о б р азо м . И и м е н н о о п е р а т о р b r e a k р е ш а е т п роблем у с б ес к о н е ч н ы м ц и кл о м в п р о гр ам м е M an d an g o .

238

глава 5


циклы Ч асщ о

^аД аБаеМ ы е Б о Ц Р о С Ь! Выполняется ли код, стоящий в цикле f o r после оператора b r e a k ?

Чем плох вариант с увеличением показаний счетчика для выхода из цикла?

; Нет. Оператор b r e a k приводит к немедленному прекращению работы цикла, и все стоящие после него операто­ ры игнорируются.

0:^

^ j Вы заставляете счетчик работать непредусмотренным образом, и это может привести к проблемам. Он предназначен для подсчета элементов массива, а вы присваиваете ему значение, выходящее за границы диапазона, провоцируя выход

из цикла. В общем случае показания счет­ чика должны обновляться только в одном месте. Разумеется, бывают случаи, когда допустимы различные обходные манев­ ры, но это — не один из них. в конце концов, к вашим услугам всегда оператор b r e a k , мгновенно прерывающий цикл без принудительного изменения значения счетчика.

Возьми в руку карандаш Ц и кл f o r в ф ункци и f i n d S e a t ( ) д о л ж е н преры ваться после то го , к а к пол ьзователь за б р о н и р о в а л кр е с л о . В пи ш ите н ед о стаю ­ щ и е с тр о ч ки кода и к о м м е н та р и и к ним .

//

поиск свободного м еста

с р е д и

в с е х в о зм о ж н ы х

.р е е . If и

(se a ts [i]) { выделяем к ресло и обновляем е го вид

s e l S e a t = 1; , ^ "seat d o c u m e n t.g e tE le m e n tB y ld seat + i -s ^ d o cu m en t. g e tE le m e n tB y ld ( " s e a t + 1)•a it / / П ользователю п р е д л а га е тс я v ar accep t = co n firm ("S eat +

П ользователь о тк азал ся, selSeat = - 1 ;

se le c t.p n g " ; ;

A ccep t?") (1 +

продолжаем поиск

.n„Tri("4eat" + i).src = "seat_avail . p n g " ;

d o c u m e n t.g e tE le m e n tB y ld

s e a t _

d o c u m e n t.g e tE le m e n tB y ld (

s e a t

^ +

- A v a il a b le

s e a t " ;

i ) - a

далее ►

239


решение упражнения

Возьми в руку карандаш Решение

Ц икл f o r в ф ункци и f i n d S e a t { ) д о л ж е н преры ваться посл е того, к а к пол ьзователь за б р о н и р о в а л кр е с л о . Вот к а к вы глядят н е д о с та ю щ и е с тр о ч ки кода и к о м м е н та р и и к ним .

// Поиск свободного места среди возможных f o r ( v a r i = 0; i < s e a t s . l e n g t h ; i+ + ) { / /

П р о в е р к а

if

д о с т у п н о с т и

(seats[i]) / /

р а с с м а т р и в а е м о г о

в

д ан н ы й

м о м ен т

к р е с л а

{

В ы д ел яем

к р е с л о

и

о б н о в л я е м

е г о

ви д

se lS e a t = 1 ; document.g

e tE le m e n tB y ld { " s e a t"

+

i ) . s r c

=

document.g

e tE le m e n tB y ld ( " s e a t"

+

i ) . a l t

- "Your

/ /

П о л ь зо в а т е л ю

п р е д л а г а е т с я

п р и н я т ь

" s e a t _ s e l e c t . p n g

п р ед л о ж ен н ы й

v a r a c c e p t = c o n f ir m ("S e a t " + (i + D

+ " is

;

s e a t " ;

в а р и а н т

a v a ila b le .

A c c e p t?

_(f_(a c c e p t),............................................................................................................................... / / К р ес л о заб ронировано, п о э т о м у ц и кла з а в е р ш а е т с я ........... break;

.............................................................................

■}......................... .......................................................................................................................... e lse / /

{ П о л ь з о в а т е л ь

о т к а з а л с я ,

п р о д о л ж аем

п о и с к

s e lS e a t = -1;

.п

do c u ment.getElementById("seat " + D - s r c = "seat_avail.png ; d o c u ment.getElementByld("seat" + i).alt - "Available seat ;

} } }

М еста для мачо К ак вы п о м н и те, и зн а ч а л ь н о нлани ровгш ось со зд ать п рограм м у к о т о р а я будет и с к а ть группы и з т р е х п о д р я д сво б о д н ы х м ест. В а р и а н т для п о и ск а о д н о го сво б о д н о го м еста уж е го то в, и н аш и друзья С ет и Д ж е й с о н го то в ы н а ч а ть р або ту над н о в о й в е р с и е й св о ей п р о гр ам м ы . Три свободных кр есла п о д ­ ряд... сколько м е с т а !

240

глава 5


циклы

- Г

'

Думаю, что несколько вложенных операторов if без проблем помогут найти три свободных места подряд. Да, именно так я и сделаю!

К од Б д еталях

--------------------------------

П о сл еЭ о б ател ь н о сть из п р о б е р я е т с я п р и у^омощи вложенных о п ер а т о р о в iffor

(v a r i =

0;

i < s e a t s . lengflh; i++)

Пры обнаруж ении т р е х м е с т подряд вы деляем первое из них.

{

М еняем изображение всех т р е х кресел на « за н я т ы е » , чтобы п о ль зо ва т е ль видел, какие м е с т а о с т а ­ ли сь свободными.

// Проверяем, свободно л и т к у щ е е место и два места за

if

( s e a t s [ х ]) ( i f ( s e a t s [ i + 1]) { i f ( s e a t s [ i + 2]) { / / Выделяем кресла и обновляй1й их вид

selS eat = i ; - ^ document.getElementByldC'seat" document.getElementByld("seat" document.getElementByld("seat" document.getElementById("seat" document.getElementByld("seat" document.getElementById("seat"

+ + + + + +

i) .src = "seat_ i).alt = "Your (i + l)).src = (i + l)).alt = (i + 2)).src = (i + 2)).alt =

select.png"; seat"; "seat__select .png "Your seat"; "seat_select.png "Your seat";

// Пользователю предлагается принять предложенный вариант

v a r a c c e p t = c o n f i r m (" S e a t s " + ( i + i f (accept) {

1)

+ " through " + (i +

3)

J + " a r e a v a i l a b l e . A c c e p t? " ) ;

// Кресла забронированы, поэтому работа цикла закончена break;

} else { // Пользователь отказался, продолжаем поиск

s e l S e a t = - 1; document.getElementByld("seat" document.getElementByld("seat" document.getElementByld("seat" document.getElementByld("seat" document.getElementByld("seat" document.getElementByld("seat"

}

+ + + + + +

i).src = "seat_avail.png"; i).alt = "Available seat"; (i + l)).src = "seat_avail.png"; (i + l)).alt = "Available seat"; (i + 2)).src = "seat_avail.png"; (i + 2)).alt = "Available seat";

* Н апом инаем : код п р о гр а м м ы M andango и все с о п у т с т в у ю щ и е изображ ения можно ска ча т ь по адресу h ttp ://w w w .k e a d fir s tla h s . с о т / b o o k s/h fjs/.

Если п о ль зо в а т е ль не б ро н и р ует М е­ ст а возвращ аем им изображ ение « неза пят ы е».

далее *

241


с надеждой на изящество

А здорово было бы, если бы все эти вложенные операторы if заменил какой-нибудь более из­ ящный вариант?

242

глава 5


циклы

Логичное

U

элегантное решение

П р о в е р к у д о сту п н о сти т р е х м ест п о д р яд в п р о гр ам м е M an d an g o м ож н о в ы п о л н и ть и б о л ее п р о с т ы м и средствам и . В л о ж ен н ы е о п е р а т о р ы i f в п о л н е сп р ав л яю тся со с в о е й зад ач ей , н о код м ож н о улучш ить, сделав его б о лее изяш ,ным.

Изящный?! Вы из­ деваетесь? Все ведь и так работает!

Q

Н е с м о т р я н а в о зр а ж е н и я С ета, ст о и т вн е с ти в код и зм е н ен и я , сделав его б о лее «изящ ны м », то есть б о лее э ф ф ек т и в н ы м , л егк и м д ля п о н и м а н и я и р е д а к ти р о в а н и я . Р азве н е зд о р о в о б ы ло бы п р е в р а т и т ь вл о ­ ж ен н ы е о п е р а т о р ы 1 £ в о д и н о п ер ато р ?

Л огически й о п е р а т о р И (&&) про вер я ет , все ли п ар а м ет р ы и м е ю т значение true.

if (seats[i] && seats[i + 1] && seats[i + 2 ] )

tr u e

tr u e

{

tr u e Л о г и ч е с к и й о п е р а т о р И (&&) п р о в е р я е т , все ли п а р а м е т р ы и м ею т од н о и т о ж е зн а ч ен и е . В д ан ном случае два о п е р а т о р а И исп ользую тся для п р о в е р к и д о сту п н о сти т р е х м ест п од ряд. Если все т р и р аза мы наблю даем зн а ч е н и е t r u e , зн ач и т , м ы наш ли т о , ч то нуж но. П р о б л е м а реш ен а... и как изящ но!

далее *

243


исследуем

булеву логику

Логические операторы Вы уж е зн ак о м ы с так и м и о п е р а т о р а м и с р а в н е н и я , как == и <■ О н и с о п о став л я ю т два зн а ч е н и я и получаю т резу л ьтат в ф о р м е t r u e / f a l s e . А н ал о ги ч н ы й р езу л ьтат д аю т л о ги ­ ч ес к и е о п е р а т о р ы , к о т о р ы е м ы р а с с м о тр и м ни ж е.

Э т о т операт ор вы уже видели!

OR

а II Ь В о звр а щ а ет значение tr u e , если а И Ь и м е ­ ю т значение tru e.

В о звр а щ а е т значение tr u e , если а И Л И Ь и м е ­ е т значение tru e .

В о звр а щ а е т значение false, если а и м е е т значение tru e , и значение tr u e в п р о т и в ­ ном случае.

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

Л огические выражения гр у п п и р у ю т с я п р и п о м о щ и скобок.

г

if ((largeDrink && largePopcorn) freeCandyO ;

В д ан н о м п р и м е р е о п е р а т о р И п р о в е р я е т , сделал л и кл и ен т к о м б и н и р о в а н н ы й заказ, купив б о льш ой стакан н а п и т к а и б о льш о е в ед р о п о п ко р н а! В это м случае он пол у ч ает в награду кон ф ету. С ущ ествует и другой способ п ол у ч ен и я б ес п л атн о й к о н ф е т ы , как п о к а зы в а ет о п е р а ­ т о р И Л И , —н а л и ч и е купона. Т о есть вам даю т кон ф ету, если вы зака зы в а е те б о льш о й н а п и т о к И б о льш ой п о п ­ ко р н И Л И п р е д ъ я в л я е т е купон. Б е з л о ги ч е с к и х о п е р а т о ­ р о в за п р о гр а м м и р о в а т ь т а к о е условие б ы ло бы к р ай н е слож но.

244

глава 5

/

|| coupon)

П о луч и т ь б ес п л а т н у ю ■ к о н ф е т у (free ca ndy) можно п у т е м ком бинированного заказа И Л И п р и наличии купона.

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


циклы Часщо Задаваем ы е Б о Ц Р о Сь !

Ti-» J» в чем разница между операторами сравнения и логическими операторами. Q ; Начнем с того, что все они являются логическими операторами в том смысле, что результатом их работы является выражение t r u e или f a l

s e .

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

гч.

3 * То есть оператор НЕ является логическим?

верно вообще для всех операторов, а не только для логических. Первым делом

! Именно так. Ведь он работает с логическими данными. Кроме того,

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

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

l a r g e P o p c o r n , а только потом | | .

выполняется часть l a r g e D r i n k

&&

3 * Какую функцию в логических операторах выполняют скобки? ! Скобки позволяют менять заданный по умолчанию порядок выполнения операторов. Причем это утверждение

^Возьми в руку карандаш Это шестой п р о го н цикла f o r в пр огра м м е M an da ngo ( i = 5). О пределите д оступн ость рассматриваемы х мест и укажите, подходят ли о н и для настоящ их мачо.

for (var i = 0; i < seats.length; i++) { // Проверяем, свободно ли текущее место и два места за ним if (seats[i] && seats[i + 1] && seatsti + 2 ] )

{

далее >

245


решение упражнения

Возьми В руку карандаш

X

Решение

Вот каким образом распределились д оступны е места на шестом пр о го н е цикла f o r в програ м м е M an da ngo ( i = 5). К сожалению, рассматриваемы е на этом шаге места не подойд ут наш им мачо.

tr u e

г =

false

tr u e

S'

/ +2 = 7

for (var i = 0; i < seats.length; i++) { // Проверяем, свободно ли текущее и следующие два места if (seatsli] && seats[i + 11 && seats[i + 2 ] )

■f.'T“ ?....

&&

{

false

&&

Наконец поиск заработал Т е п е р ь п р о гр ам м а M an d a n g o к о р р е к т н о и щ ет п о с л ед о в ател ьн о с ти и з т р е х п о д р я д н е за н я т ы х м ест, п о д н я в се р в и с р е зе р в и р о в а н и я б и ­ л е т о в н а такую вы соту, ч т о о ц е н и т ь его м огут даж е н аш и м ачо.

.......

■П»MachoMow

......

Теперь пользоват елю предлагаю т выбрать 1лоследоват елш ост ь из т р е х мест .

I Seats 4 through 6 are avaitable. Accept’

[andseaVii

('"C^cel j f

J 246

глава 5

OK


циклы

U сноВа карта сокровищ Раз п р о гр а м м а M a n d a n g o п р е к р а сн о р а б о т а е т , м о ж н о в ерн уть­ ся к пои ску со кр о ви щ . П о м н и те эту карту?

37 шагов.

О И д и те, п о к а н е увидите скалу в ф о р м е п оч атка.

А

^

Ч У С н ач ал а 37 ша-

Цикл fo r ув ер ен но проводит в а с ___ У по первой части м арш рут а!

О К р ес т указы вает место! .... Д л я п р о х о ж д е н и я п е р в о й ч ас ти м арш рута вам д о стато ч н о ц и к л а f o r . Н о во т п р е о д о л е ть следую щ ий уч асток о н вам н е п о м о ж ет. В едь н е в о зм о ж н о со зд ать ци кл f o r , н е зн ая т о ч н о ­ го к о л и ч ес т в а его ш агов. Сокровищ е

ждет...

Ш ТУРМ в чем разница между двумя частями карты? Каким образом вы бы создали цикл для прохождения второй части?

далее ►

247


сколько? некоторое время...

Цикл while Х отя т е о р е т и ч е с к и ци кл f o r м о ж н о со зд ать и д ля в т о р о й ч аст и к ар ты , сущ ествует лучш ий в ар и ан т. О с н о в о й ц и кл а f o r я в л я е т с я сч етч и к , а в о т ц и кл w h i l e р а б о т ае т , пока н е будет в ы п о л н е н о зад ан н о е условие. И эт о услови е м о ж ет б ы ть н и к а к н е с в я за н о с ч и сл о м и т е р а ц и й (п о в то ­ р е н и й ). Ц и к л w h i l e с о с т о и т и з двух частей:

Проверка условия

Цикл №Ы1е повторяет код, пока результатом проверки условия пе станет значение true. Проверка условия П р о в е р я е т с я , д о л ж ен л и п р о д о л ж а т ься цикл.

Ш аги 1 U Я п о л н я ю т с я нд каждой и т е р а ­ ции цикла.

О

Действие

О ператоры , которы е следует в ы п о л н я т ь н а каж дом п р о г о н е цикла.

\ .

•••

Действие

...

...

.

О дин илаг цикла.

Проверка условия О

П р и м е н е н н ы й ко в т о р о й ч асти к а р т ы ци кл w h i l e д ае т т ак о й ж е н е о ж и д ан н о п р о с т о й код, как и ци кл f o r в п е р в о й части:

О

С ледую щ ий ш аг вы ­ п о л н я е т с я , то л ь ко есл и скалы все ещ е н е видно.

while (!rockVisible) takeStepО ;

О

?госкУ ± з± Ы е

В от как ф у н кц и о н и р у ю т р а зл и ч н ы е ч ас ти ц и к л а w h i l e :

Действие ^

^

П р о в е р я е м , ви д н а л и скала. Если да, п ер ех о д и м к ш агу 2, если н ет, вы ход им и з цикла.

О

Запускаем код ци кла. В д ан н ом случае вы зы ваем ф ункц ию t a k e S t e p ( ) .

В ы зов ф у н кц и и t a k e S t e p ( ) .

takeStep О 248

глава 5


циклы

Анализ цикла while Б о л е е п р о с т о й по структуре, ч ем ци кл f o r , ци кл w h i l e т о ч н о т а к ж е о п и с ы в а е т с я о п р е д е л е н н о й ф орм улой : П роверка ус ло ви я , к о т о ­ р а я должна во звр а щ а т ь значение tr u e или false.

i Проверка

while

|Д к ш е

I

осш орож ны ! Действие

П овт орянущ иеся дейст вия зада ю т ся как п р о с т ы м ^ т й к и со ст а вны м опера тороМ-

Будьте аккуратны с условием выхода из цикла.

Цикл while не имеет встроенного кода обновления, поэт ому его внутрен­ ний код должен быть написан таким образом, чтобы влиять на условие выхода. Иначе цикл может оказаться бесконечным.

Перепишите код уже знакомого вам упражнения, в котором пользова­ телю предлагалось ввести число больше О и который использовался для обратного отсчета перед началом фильма (4, 3, 2, 1, Roll film!). Замените цикл f o r циклом w h i l e . var count = prompt{"Enter a number greater than 0:", "10"); if (count > 0) {

} else alert{"The number wasn't greater than 0. No movie for you!");

далее *

249


решение упражнения

Вот как после замены цикла f o r циклом w h i l e выглядит код уже знакомого вам упражнения, в котором пользователю предлагалось ввести число больше О и которое использовалось для обратного отсчета перед началом фильма (4, 3, 2,1, Rollfilm!).

^пражнеше реш ение С охраним число в п ер ем енно й count.

Пользователю предлагается в сти число.

а

var count = prompt("Enter a number greater than 0:", "10");

Убедим­ ся, что •леременная count больше о.

if (count > 0) {

___

обрат ны й от счет до О.

v a r X = count;

................

I В данном случае счетчик создается вне цикла while.

while (x > O) { ................................................................................................................................................ a le r t( " S ta r tin g in..." + x); Значение ........................................................................................................................................ п ер ем ен н о й X уменьшается на 1 вн у т р и цикла.

Внутри цикла с о ­ ст а вно й оператор. alert("The number wasn't greater than 0. No movie for you!");

Некорректные данные. The number wasn't greater than 0. Ho movie for you!

Обратный отсчет закончен! Roil film!

C__0 k'" )

КЛЮ ЧЕВЫЕ МОМЕНТЫ

250

Оператор b r e a k немедленно завершает цикл, пропуская оставшийся код.

Цикл w h i l e выполняет указанный код, пока вы­ полняется заданное условие.

Логические операторы позволяют создавать слож­ ные условия.

Код в теле цикла w h i l e должен влиять на условие выхода.

глава 5


циклы

Выбор подходящего цикла П реды дущ ее у п р аж н ен и е п о к азало , ч т о и н о гд а одну и ту ж е проб л ем у м о ж н о р е ш и т ь как п р и п о м о щ и ц и кл а f o r , т а к и п р и п ом о щ и ц и к л а w h i l e . Б о л е е то го , п р е в р а щ е н и е ц и к л а f o r в ц и кл w h i l e осу щ ествл яется по следую щ ей ф орм уле:

Циклы while и цикл ’

Р

ЯП Н аШ Ф О а Л о Л Л Ш 1 1//1

взаимозаменяемыми.

Иниц.

while

1

^ □

О бно влени е

с

Действш

И нициализация вы п о лн яет ся вне цикла.

□ И так , вы убедились, ч то т е х н и ч е с к и одну и ту ж е задачу м ож н о р е ш и ть с пом ощ ью лю б о го и з ци кл о в. Н о в б о л ьш и н стве слу­ ч аев следует и с п о л ьзо в ат ь с т р о го о п р е д е л ен н ы й ци кл. М ож ет б ы ть, все д ел о в изящ естве? /

\

for (var i = 0; i < Ю ;

О бновление вы полняет ся в т е л е цикла.

var i = 0; while (i < 10)

(

alert(i);

i++)

i++;

alert (i); }

Э т и циклы Kopomcf подходят для р еш е ния п о ст а влен н о й задачи.

Н е т обновления.

Н ет и ни ц и а ли за ц и и ^

while (!finished) dolt О ;

___________ с for (; !finished; ) dolt О ;

\ В ы б о р между ц и кл ам и f o r n w h i l e п од обен вы б ору н аи б о л ее под х о дящ его д ля р аб о т ы ин струм ен та. Д ругим и словам и, «ме­ хани ка» ц и к л а до л ж н а со о т в ет ст в о в а ть п о с т а в л ен н о й задаче.

далее *

251


цикл fo r против цикла while

Беседа у камина Циклам For и While сложно не повториться.

Цикл For: В от и м ы , п а р а п о в то р я ю щ и х с я п а р н ей , ко­ т о р ы е д ер ж а тс я вм есте.

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

З ву ч и т слиш ком н е о п р е д е л е н н о , х о т я я ду­ маю , ч то это д о л ж н о р аб о тать. Н о м н е по душе б о льш ая то ч н о ст ь . И м е н н о п оэтом у я п р е д п о ч и т а ю и н и ц и а л и зи р о в а т ь с я до н а­ ч ал а р а б о т ы и о б н о в л я тьс я в п р о ц е сс е и т е ­ р а ц и й , п р о с т о ч то б ы б ы ть у вер ен н ы м , ч то все р а б о т а е т так, как нуж но. Я м ан и ак ал ьн о слеж у за тем , ч то б ы р а б о т а т ь к ак часы .

Цикл While; Д а. Х о тя д о л ж ен сказать, ч т о к о л и ч е ств о ш а­ гов, п р и п ом о щ и к о т о р ы х т е б я заставл яю т р аб о та ть, п р е д ста в л я е тс я м не и зб ы то ч н ы м .

Э то так, но, как т ы пом н и ш ь, дал еко н е все ц и к л и ч е ск и е п о в т о р е н и я св я зан ы со счетом . Е сть п о т р я са ю щ и е ц и кл ы , вооб щ е н и к ак н е св я за н н ы е с ц и ф р а м и . К огда тр еб у ется т о л ь к о сказать «Эй, д ел ай в о т эт о н е к о т о р о е врем я!», я незам ен и м .

В осхищ ен тв о и м п од ходом к р аб о те. Н о п о н и м аеш ь л и ты , ч то ц и к л и ч е ск о е п о в т о р е ­ н и е д ей ств и й в п о л н е осущ ествим о и б ез всех эт и х ф о р м ал ь н о с те й вр о д е п р ед в ар и т ел ь ­ н о й и н и ц и а л и за ц и и и о б н о вл ен и я ? К ром е т о го , я ч асто п о в т о р я ю код, для к о т о р о г о н е тр еб у ется и н и ц и ал и за ц и и . А о б н о в л ен и е п р о и сх о д и т п р я м о внутри м еня, и то ге я могу сф о к у си р о в аться н а н е п о ср ед с тв е н ­ н о й р аб о т е , то есть н а и т ер а ц и я х .

в

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

252

глава 5


циклы

Цикл While;

Цикл For:

Н а в е р н о е , все д ел о в том , ч то каж ды й ци кл и м е ет свой сти л ь р аб о ты . Т е б е н р ав и тс я и м е т ь под рукой все эл ем ен ты у п р ав л ен и я, в т о вр ем я как я со с р е д о т о ч е н н а п р о ц ессе. Д а, эт о так. Г лавное, ч то м ы о б а делаем свою работу. И я даж е и н о гд а виж у, где м о й под ­ ход я в л я е т с я изли ш н и м . П о л н о стью с т о б о й согласен! Г лавное, ч то р аб о т ы х в а т и т нам обоим . Я го то в слуш ать эт о сн о ва и снова! Г л авн ое, ч т о раб о ты ... о й , к аж ется, м н е п о р а п р е р ы в а т ь работу. П рош у п р о щ е н и я . Н и ч е г о с тр аш н о го . С п аси бо за беседу!

Часто '^ а Д а Б а е М ы е Б о 1 1 |э о с ь 1 3 * Цикл w h i l e кажется очень про­ стым. Я чего-то не понимаю?

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

Может ли случиться так, что тело цикла никогда не будет выполнено?

S Вовсе нет. Простота не является синонимом слабости или ограниченности.

иметь значение t r u e . А цикл w h i l e продолжает работу, пока условие не пере­ станет выполняться, то есть результатом

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

Более того, вы удивитесь, обнаружив, на­ сколько мощным инструментом является цикл w h i l e . Разумеется, он состоит только из условия и выполняемого кода, но в некоторых случаях большего и не требуется. Особенно в тех случаях, когда условие выхода из цикла является до­ статочно сложным. Кроме того, в тело цикла можно поместить любое количество кода, ведь вы можете воспользоваться составным оператором.

Будет ли работать цикл вида w h i l e ( t r u e ) ...?

его проверки не станет значение f a l s e . Страшно подумать, сколько бесконечных циклов вынуждены работать, работать и работать... эй, прекратите немедленно!

проверки условия было значение t r u e . Поэтому если условие не проходит про­ верку, перехода к телу цикла не происхо­ дит. Вы выходите из него еще до начала его работы.

Б

>Допустимы ли вложенные циклы?

! Конечно! Вложенные циклы по­ зволяют создавать различные уровни повторений. На данном этапе это может звучать для вас странно, но это — правда. Вы познакомитесь с вложенными цикпами позже, когда программа Mandango от ряда перейдет к целому кинотеатру!

далее *

253


успех цикла

Сокровище В награду В о сп о л ьзо вавш и сь ц и кл о м f o r , за к о т о р ы м следует ц и кл w h i l e , вы см о ж ете п р о й т и ук азан н ы й н а к ар те м арш рут и п р и б ы т ь в точку, пом еч ен н у ю кр естом .

3 7 шагов.

И д и те, п о к а н е увидите скалу в ф о р м е поч атк а.

while (!rockVisible)

С н ач ал а 37 ш а­ гов н а восток.

takeStep ();

for (var X = 0; X < 37; х++

При пом ощ и цикла while вы без задер­ жек преодолеете вт орую часть!

takeStep();

Ц и к л f o r уверенФ НО проводит вас _J по первой части м арш рут а!

К р е с т указы вае т место!

Сундук открывает­ ся, и вы находите..

...билеты в кино!

Р азве эт о н е зн ак судьбы? Вы п о зн а к о м и л и сь с ц и кл ом w h i l e и о б н аруж и л и б и л еты в ки н о, зн ач и т , нам п о р а вернуться... к р а б о т е над п р и л о ж е н и ем M andango!

254

глава 5


циклы

далее >

255


решение упражнения

Возьми в руку карандаш Решение

Вот как выглядит функция f i n d S e a t s () после замены цик­ ла f o r циклом w h i l e и ввода новой переменной f i n i s h e d , которая вместо оператора b r e a k будет отвечать за выход из цикла.

Э т о т ц и кл в к а к о м -т о см ы сле я в л я ­ ет с я гидридом т о го , чт о м ы видели раньш е. Ведь выход из цикла за ви си т как о т показаний сч ет чика, т а к и о т логического выражения. В т а к и х с л у ч а ЯК лу ч ш е испол(узов^иль цикл while. J

Ц и кл р а б о т а е т , пока значение сч ет ч и ка м ен ьш е числа сидений И п е р е м е н ­ ная "finished" не п р и н и м а ­ е т значение tru e.

Инициализация счетчика цикла и переменной "finished".

L .ШК.!.л.??Л

г..

.

w hile ((i < seats.len0 th ) §£& lfm ^ ^ 11

п р о в е р я е м

i f

( s e a t s [ i ]

т е к у щ е е &&

м е с т о

s e a t s [ i

к р е с л а

и

+

и 1]

........... д в а

м е с т а

&&

s e a t s [ i

о б н о в л я е м

+

ним 2 ])

{

/ /

В ы д ел я ем

„ о л ь ,о . а , е л . „ р е „ а ™ . , с , _ „ р » я , ь „ р е л л о ж ,.™

var accept = confirm( Seats "

a r e

a v a i l a b l e .

и х

з а

+ u

в и д

^

^

+

A c c e p t ? " ) ;

if_(acce0 ) , l ....................................................................................................... ......................... ..................... / / К р ес л а забронированы ^ п о э т о м у р а б о ^ finished - tru e;

.......................................................................................................

// Пользователь отказался7''п?10ДОЛжаем поиск

И нкремент счет чика цикла.

256

глава 5

П рисвоение п ер ем ен н о й "finished" значения tr u e п р и во д и т к в ы ­ ходу из цикла. И м енно п о э т о м у в данном м е с т е вам больш е не т р е б у е т с я о п е р а т о р break.


циклы

Приложение Mandango выглядит здоро­ во, вот только я не знаю ни одного кино­ театра со всего одним рядом кресел. Надо бы его отредактировать...

Кинотеатр — место моделирования данных Д ж е й с о н прав. Ч т о б ы п р о гр а м м а M an d a n g o стал а ф у н к ц и о н ал ьн о й ее нуж но п е р е п и с а т ь с у ч етом р е а л ь н ы х условий. П р и м е р с од ним ряд о м кр е с е л о ч е н ь пом ог, т а к как п о зв о л и л п р я м о св я зать м ассив л о ги ч ес к и х д ан н ы х с и зо б р а ж е н и я м и . Т е п е р ь нам нуж но д о б ави ть к м ассиву в т о р о е и зм е р е н и е . Д а, да, м ы го в о р и м и м е н н о о двум ер­ ном массиве!

в эт ом к ш т е а п р

т

т

т

Каждый э л е м е н т двум ерного м ассива о т н о си т с я к л о г и ­ ческом у т и п у . Н ам п о тр еб у ется м ассив р а зм е р о м 9 x 4 , к о т о р ы й будет с о о т в ет ­ ство в ать ч ет ы р е м рядам и з д е в я т и кресел.

Э т о еще. одно и зм ерени е индексов м ассива.

далее

257


больш е, чем одно изм ер ени е

двумерные массивы Д л я со зд ан и я д вум ерн ого м асси ва вам н е п о тр еб у ется н и к ак и х н овы х свед ен и й . Вы всего ли ш ь сф о р м и р у е те м ассив, эл ем ен там и к о т о р о го будет другой м ассив. И м е н н о эт о д о б а в и т в т о р о е и зм е р е н и е . В р е ­ зультате вы п о л у ч аете таблицу д ан н ы х , р а с п р е д ел е н н ы х п о стр о кам и столбцам . Н ачнем с м а сси ва , к о т о р ш — .с т а н е т основой для д о п о л н и т е л ш ы к м ассивов. Э т о п ервое изм ерение!

Создадим д ополнит ельны е м ассивы , кот оры е с т а н у т эл е м е н т а м и первого м а с с и ­ ва. Э т о вт о р о е изм ерение!

var seats = new Array(new Array(9), new Array(9), new Array(9), new Array(9));

V

_____ Ч ет ы ре влож енных м ассива дадут на м чет ы р е ряда.

Р аб о та я с п р о гр а м м о й M an d a n g o , м ы зн аем н ач а л ь н ы е зн а ч е ­ н и я эл ем ен то в , по это м у д ля со зд ан и я д ву м ерн ого м асси ва вос­ п ользуем ся м ассивом ко н стан т. Д р у ги м и сл овам и, м ы о д н о в р е ­ м е н н о создадим и и н и ц и ал и зи р у ем массив! /двойны е скобки указы ваю т , на д в у ­ м ер ны й массив.

var seats = [[ false, true, false, true, true, true, false, true, false ], [ false, true, false, false, true, false, true, true, true ], [ true, true, true, true, true, true, false, true, false ], [ true, true, true, false, true, false, false, true, false ]]; Первый перечень логических значений с о о т в е т с т в у е т п е р во м у ряду д вум ерного м ассива.

Каждый влож енный м а с с и в и м е е т свои собст венны е и н д ек­ сы. в данном случае

False — м е с т о уже занят о.

258

глава 5

T rue - - м е ~сто свободно.


циклы

Двумерные массивы позволяют сохранять строки и столбцы таблиц.

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

ряду.

В т о р о м у ряду с о о т в е т с т в у е т индекс X (н у м е р а ц и я начинает ся

с О).

Д бд изм ер ени я /

alert(зеа18[1][3]);

V

Одно изм ерение.

___ 1^ е т в е р т о м у э л е м е н т у в ряду с о о т в е т с т в у е т индекс 3.

Д л я п р о с м о т р а эл ем ен то в д вум ерн ы х м асси во в н ам п о тр еб у ю т­ ся в л о ж е н н ы е ц и кл ы . В н еш н и й ци кл будет у п р авл я ть п е р е х о ­ дом о т о д н о го р я д а к другому, в т о в р ем я как в н у т р ен н и й — п р о ­ см а тр и в а ть м еста.

Влож енные ц и ­ клы д а ю т д о с т у п к данны м д в у м е р ­ ных м ассивов.

далее >

259


решение упражнения

Возьми В руку карандаш Решение

Вот код просм отра элементов д вум е р н о го массива s e a t s , извещ аю щ ий пользователя о состоянии ка ж д о го места.

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

В неш ний ц икл п е р е х о д и т о т одного ряда к д р у го м у , м еняя показания сч ет чи ка /.

П р о с м о т р данных двум ер но го м ассива осуш ,ест вляет ся >лри п о м о щ и двух влож енных циклов.

Э т о длина влож енно­ го м ассива в ряду I.

fo r (v a r i - О; i < sea ts.len ^th ; ('++) ^

fo r (v a r j = O; J < seatsp'].length; J++) (

Д л я д о ст уп а к каж д ом у кр е с лу нужн у к а з а т ь , в каком ряду ( 1) и в ка ко м ст о лб ц е ( j ) оно располож ено.

if (seats[i][j]) r t(" S e a t " + i -h " in ro w " + j + " is available.'');

alertC 'S ea t “ + i + " in ro w " +J +■ " is n o t available.");

В за ви с и м о с т и о т т о го , свободно м е с т о (tru e ) или за н ят о (false), б уд у т п о ­ я вля т ь с я окна с р а зн ы м и сообщ ениям и.

В сообщ ении о свободном м е с т е ука зы вает ся его н о м ер и в ка ко м ряду оно располож ено. Часто

'^адаБаеМые БоИ роС Ь! Существуют ли массивы большей размерности? 0 ; Да, хотя визуализировать их сложнее. Трехмерные массивы обычно соответству­ ют х-у-1-координатам точки в простран­ стве. Массивы еще большей размерности применяются в редких случаях. Чтобы ' добавить очередное измерение, достаточ­ но сделать элементы внешнего массива в свою очередь массивами.

Если инициализация элементов массива происходит в момент его создания, можно ли добавлять в него элементы постфактум? ; Вы в любой момент можете назна­ чить данные неиспользуемому элементу массива. Например, в нашем примере можно создать еще один ряд (с индексом 4). Достаточно назначить массив элементу

s e a t s [ 4 ] . Можно также воспользовать­ ся функцией p u s h () и добавить новый элемент в конец массива.

260

глава 5

3 * Двумерные массивы должны содержать одно и то же количество рядов? ! Не обязательно. Но помните, что в этом случае могут возникнуть пробле­ мы с циклами, так как вложенные циклы обычно работают с массивами одинако­ вой длины. Так что, несмотря на принци­ пиальную возможность варьировать длину рядов двумерного массива, лучше этого избегать.


циклы

КЛЮ ЧЕВЫЕ МОМЕНТЫ

Двумерные массивы позволяют сохранять строки и столбцы таблиц.

Для просмотра элементов двумерных массивов ис­ пользуются вложенные циклы.

в

Для доступа к элементам двумерного массива ука­ зывайте индексы строки и столбца.

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

двумерная Версия Mandango Вы уже р а б о т а л и с о тд ел ьн ы м и ч ас тя м и ко д а M an d an g o , но п е р ех о д о т е д и н ств ен н о го р я д а к целом у к и н о т еа тр у тр еб у ет с е р ь е зн о го р е д а к ти р о в а н и я . П о это м у будьте в н и м ател ьн ы . Д ля просм от ра д вум ер но го м ассива кр есел ва м п о т р е ­ б ую т с я два с ч е т ­ чика.

П ереход о т одном ерной к двум ер­ ной версии Мапе1апдо т ребует внесения серьезны х и зм енений в код.

Ш ТУРМ Каким образом нужно поменять код программы Mandango, чтобы она начала работать с целым кинотеатром? Как бы вы это визуализировали?

д алее >

261


для этого кода вам не нужны стереоочки

<htm l> <head> < title> M a n d a n g o - поиск билетов для Ma4o</title>

В о т полны й код для Щ т е р н о й версии M andango!

< sc rip t ty p e = "te x t/ja v a sc rip t"> v a r s e a t s = [[ f a l s e , t r u e , f a l s e , t r u e , t r u e , t r u e , f a l s e , t r u e , f a l s e ], [ f a l s e , t r u e , f a l s e , f a l s e , t r u e , f a l s e , t r u e , t r u e , t r u e ], [ t r u e , t r u e , t r u e , t r u e , t r u e , t r u e , f a l s e , t r u e , f a l s e ], [ tru e , tru e , tru e , fa ls e , tru e , fa ls e , fa ls e , tru e , fa ls e ]]; v a r s e lS e a t = -1;

mandango.html

fu n ctio n i n i t S e a t s 0 { Создан двум ерны й м ассив / / З а д а єм вид в с е х к р е с е л логических конст ант , co~ сг f o r ( v a r і = 0; і < s e a t s . l e n g t h ; i+ + ) { f o r ( v a r j = 0; j < s e a t s [ 1 ] . l e n g t h ; j + + ) { держ ащий и н ф о р м ац и ю if (se a ts[i][j]) { о дост упност и кресел. / / Задаем свободные м е с та d ocum ent. g etE le m e n tB y ld (" s e a t " + (І * s e a t s [ І ] . l e n g t h + j ) ) . s r c "se a t_ a v a il.p n g " d ocum ent. g e tE le m e n tB y ld (" s e a t" + (і * s e a t s [ і ] . l e n g t h + j ) ) . a l t "A v ailab le s ea t"

)

e lse { / / Задаем заняты е места d o c u m e n t. g e tE l e m e n t B y l d (" s e a t " + ( i * s e a t s [ i ] . l e n g t h + j ) ) . s r c = " s e a t _ u n a v a i l . p n g " d o c u m e n t.g e tE le m e n tB y ld ("se at" + ( i * s e a t s [ i l . l e n g t h + j ) ) . a l t = "U n a v ailab le s e a t"

)

} fu n ctio n fin d S ea tsO { / / Е с л и м е с т а уже вы бр аны , п р о и з в е 1&1т е п о в т о р н у ю и н и ц и а л и за ц и ю i f ( s e l S e a t >= 0) { s e lS e a t = -1; i n i t S e a t s () ;

} / / П оиск с в о б о д н ы х м е с т с р е д и в с е х во змож ных v a r i = о, f i n i s h e d = f a l s e ; w h i l e ( i < s e a t s . l e n g t h && I f i n i s h e d ) { ^ f o r (v a r j = 0; j < s e a t s [ i ] . l e n g t h ; j++) { / / П р о в е р я е м , с в о б о д н о л и т е к у щ е е м е с т о и д в а м е с т а з а ним i f ( s e a t s [ i ] [ j ] && s e a t s [ i ] [ j + 1] && s e a t s [ i ] [ j + 2 ]) { / / Выд еляем к р е с л а и о б н о в л я е м и х в и д selS eat = i * s e a ts [ i] .le n g th + j; docu m en t.g etE le]T ien tB y Id ("seat" + (i * s e a t s [i] . l e n g t h + d o c u m e n t.g e tE le m e n tB y ld C 's e a t" + (i s e a t s [ і ] . le n g th d ocum ent. g e tE le m e n tB y ld (" s e a t (і * s e a t s [ і ] .le n g th + d ocum ent. g e tE le m e n tB y ld (" s e a t (і * s e a t s [ і ] .len g th + d o cu m en t. g e tE le m e n tB y ld (" s e a t s e a t s [ і ] . len g th + j (і d o cu m en t. g e tE le m e n tB y ld (" s e a t s e a t s [ i l . len g th + j (і

Если п о ль зо ва т е ль — ______ на ч и на ет новый поиск щ елч ко м на кнопке Find S e a ts, п о вт о р н о (инициализируем э л е ­ м е н т ы м ассива. Д л я п р о с м о т р а рядов и с п о л ь зуе т с я ц и кл w hile, в т о вр ем я как ц и к л fo r о с у щ е ст в л я е т п р о с м о т р от д ельн ы х кресел.

) ) .s r c = "seat_ select.p n g "; ) ) . a l t = "Your s e a t " ; + l) } .s r c = "seat_ select.p n g "; + 1 ) ) . a l t = "Your s e a t " ; + 2) ) . s r c = " s e a t _ s e l e c t .p n g " ; + 2 ) ) . a l t = "Your s e a t " ;

/ / П о л ь з о в а т е л ю п р е д л а г а е т с я п р и н я т ь предл ож е нн ы й в а р и а н т v a r a c c e p t = c o n f i r m ( " S e a t s " + ( j + 1) + " t h r o u g h " + (j + 3) + " i n Row " + ' ( i + 1) + " a r e a v a i l a b l e . A c c e p t ? " ) ; i f (accept) { / / К р е с л а з а б р о н и р о в а н ы , п о э т о м у р а б о т а в н е ш н е го ц и к л а з а к о н ч е н а fin ish ed = true; b reak;

) e lse

262

глава 5

{


циклы

fI

П ользователь

отказался,

п родолж аем

s e lS e a t = -1; d o c u m e n t.g e tE le m e n tB y ld C 's e a t" d o c u m e n t. g e tE l e m e n t B y l d (" s e a t " d o c u m e n t.g e tE le m e n tB y Id (" s e a t'‘ d o c u m e n t.g e tE le m e n tB y Id { "se a t" d o c u m e n t . g e t E l e m e n t B y l d C ’s e a t " d o c u m e n t.g e tE le m e n tB y Id (" se at"

//

У величиваем

счетчик

вн еш н его

+ + + + + +

цикла

( ( ( (i {i (i

на

поиск

sea ts[i].le n g th s e a t s [ i ] . len g th s e a t s [ i ] . le n g th s e a t s [ i ] •le n g th sea ts[i].le n g th s e a t s [ i ] . le n g th

един ицу

i++;

< /scrip t> < /head>

vT

Ф у н к ц и я in itSeatsQ вы зы вает ся п р и п е рвой за гр у зке ст раницы .

j ) ) . s r c = • 's e a t _ a v a i l .p n g " ; j ) ) . a l t = "A v ailab le s e a t" ; j + l ) ) . s r c = " s e a t_ a v a il.p n g " j + l ) ) . a l t = "A v ailab le s ea t" j + 2) ) . s r c = " s e a t _ a v a i l . p n g " 2 ) ) , a l t = "A v ailab le s e a t"

с

Именно благодаря счетчиКйМ м е н я ю т ­ ся изображения к р е ­ сел и всплывающии т екст .

<body o n l o a d = " i n i t S e a t s { ) ;" > « d i v sty le= "m argin -to p:2 5 px ; <i m g i d = " s e a t O " s r c = " " a l t = Н е п у га й ­ <im g i d = " s e a t l " s r c = " <im g i d = " s e a t 2 " s r c = " тесь <im g i d = " s e a t 3 " s r c = " разм еров <img i d = " s e a t 4 " src==" <img i d = " s e a t 5 " s r c = " это го кода. <im g i d = " s e a t 6" s r c = " <img i d = ' ' s e a t ? " s r c = " " a l t = " " / > З д е сь и сп ользуется уж е зн ак о м ая вам <img i d = ' ■ s e a t 8" s r c = " " a l t = " " / X b r / > т е х н и к а р а б о т ы с двум ерн ы м и м асси­ <img i d = ' ' s e a t 9 " s r c = " " a l t = " " / > <img i d = ' ’s e a t l O " s r c = " " a l t = " ' " / > вам и, ад а п ти р о в а н н а я д ля п р и л о ж е н и я <img i d = ' ' s e a t l l " s r c = " " a l t = " ' " / > M a n d a n g o , с е г о H T M L -кодом и и зо ­ <img i d = ' " s e a t l 2" s r c = " " a l t = " ' " / > б р аж е н и я м и (все эт и м а тер и ал ы м ож н о <im g i d = ' " s e a t l 3 " s r c = " " a l t = " ' " / > <im g i d = ' " s e a t l 4 " s r c = " a l t = " " / > с к ач ать здесь: http://xmvw.headfirstlabs.com/ V Д ля <im g i d = ' " s e a t l S " s r c = " " a l t = " " / > books/hfjs/). ^ ^ ч г т ш е к " a l t = " /> <img i d = ' " s e a t l G " s r c = " <img i d = ' " s e a t l ? " s r c = " " a l t = " " / x b r / > f рядов по <img i d = ’" s e a t l S " s r c = " " a l t = " " / > девят ь <img id = '" s e a t l 9 " s r c = " " a l t = " ’■ / > сидений <img id = '" s e a t 20" s r c = " " a l t = " " / > пот ре­ <im g i d = " s e a t 21" s r c = " " a l t = " " / > бует ­ <im g i d = " s e a t 22" s r c = " " a l t = " " / > ся 36 <img i d = " s e a t 2 3 " s r c = " " a l t = " " / > <img i d = " s e a t 2 4 " s r c = " " a l t = " " / > изобра­ <img i d = " s e a t 2 5 " s r c = " " a l t = " " / > жений... " / x b r " a l t = " / > <img i d = " s e a t 2 6 " s r c = " кошмар! <img i d = " s e a t 2? " s r c = " " a l t = " " / > Ф у н к ц и я FindSeatsQ <img i d = " s e a t 2 8 " s r c = " " a l t = " " / > вы зы вает ся ш ,елч<im g i d = " s e a t 2 9 " s r c = " " a l t = " " / > к о м на к н о п ке Find <img i d = " s e a t 3 0 " s r c = " " a l t = " " / > Seats. <img i d = " s e a t 3 1 " ' s r c = " " a l t = " " / > <img i d = " s e a t 3 2 " ' s r c = " " a l t = " " / > <im g i d = " s e a t 3 3 " ' s r c = " " a l t = " " / > <im g i d = " s e a t 3 4 " ' s r c = " " a l t = " " / > <img i d = " s e a t 3 5 " 1 s r c = " " a l t = " " / x b r / > < i n p u t t y p e = " b u t t o n ' l d = " f i n d s e a t s " v a l u e = " F i n d S e a t s " o n c l l c k = " f i n d S e a t s () < /div> < /body> </htm l>

J

далее >

263


вне себя от радости

Целый кинотеатр мест для мачо Т е п е р ь , когда п р о гр а м м а M a n d a n g o стал а двум ерн ой , С ет и Д ж е й с о н могут и ск ать м еста по всем у ки н отеатру... и со с в о и ­ м и к р и т е р и я м и поиска! П а р н и в в о с то р ге .

Мы больше никог­ да не будем сидеть рядом!

Класс!

Т еп ер ь M a n d a n g o м ож ет и с к а т ь наборы из т р е х свободных м е с т подряд по всем у к и н о т е а т р у .

М^ап§^

пев

т

Ticlusi Findef

л

J

Seats 2 through 4 in Row 3 are

(

■ iiip e

264

глава 5

Cancel

available. Accept?

(

OK


циклы

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

Что общего у ЦИКЛОВ с фильмами? \ } Д х.у роШ о. а д В а лу'ІЯіе!

Некоторые фильмы имеют сюжет, за которым сложно уследить. Другае фильмы привлекают зрителя постоянным движением. Но любой фильм — это только фильм.


с :>ункДии

Многократное использование

Начни JavaScript выступать за экологию, это выступление возглавили бы функции. Ведь именно они увеличивают эффективность кода и позволяют использовать его многократно. Они ориентированы на ре­ шение задач и позволяют все систематизировать. Функции дают возможность упростить любой сценарий, ну кроме разве что и так простых. Их значение не­ возможно оценить, поэтому просто скажем, что именно функции делают сце­ нарии такими экологичными.


анализ большой проблемы

источник Всех проблем П о больш ом у счету н а п и с а н и е с ц е н а р и е в д ля веб-стран и ц я в л я е т с я р е ш е н и е м задач. В дум чивы й подход и п л а н и р о в а н и е всегда п о зв о л я ю т н а й ти в е р н о е р еш ен и е. Н о как б ы ть с о ч е н ь б о л ь ш и м и за д ач а м и ?

Мир во всем мире В о т наш а больш ая задача!

Б о л ьш и е зад ач и и м е е т см ы сл р еш ать путем р а зд е л е н и я и х н а б олее м ел ки е. Е сли даж е п о сл е эт о го зад ач и о с таю тся слиш ком б ольш и м и , п о ­ д ел и те их еш;е раз.

бо льш а я задача.

Вш,е м еньш ая задача.

/ Выращ ивание

\ |1

Продажа

Право на

С т ройка

1

зем л ю

Свобода слова

Право г о ­ лоса

1 Э ту проц едуру м о ж н о п р о д о л ж и т ь снова, и снова, и снова...

268

глава 6


функции

Решение задач снизу Р азд ел я я в о п р о с о м и р е во всем м и р е н а б о л ее м ел ки е, м ы р а н о и л и п о зд н о п р и д ем к задачам , р е ш и ть к о т о р ы е м о ж н о п р и п ом ощ и Д ауа8спр. Кров

\

чая

П р ед став и м п р о б л ем у у п р ав л ен и я кл и м ато м в т е р м и н а х JavaS cript. Вам п о тр еб у ется эк в и в а л е н т т е р м о с т а т а , к о т о р ы й о б ы ч н о и сп о л ь­ зуется д ля к о н т р о л я те м п е р а ту р ы о круж аю щ ей среды . С ам ы й п р о ­ с т о й т е р м о с т а т с о с т о и т и з е д и н с т в е н н о й к н о п к и «H eat».

Л роет ейилий т е р /л о с т л т — н й Ж М ите кн о п к у, и он за р а б о т а ет .

HEAT FIRST В ам не и н т е р е с ­ но, ка ки м образом работ ает т е р м о ­ с т а т , дост ат очно т о го , ч т о вы у м е ­ е т е его вклю ч а т ь.

П о д о б н а я м одель т е р м о с т а т а н е д аст вам п р е д с тав л е н и я о том , как осущ ествл яется н агр ев. В ы н аж и м аете кн опку H e a t, и ст ан о в и т ся теп л о . П р о б л е м а у п р ав л ен и я кл и м ато м реш ена!

далее *

269


методы как решение маленьких задач

Функции как способ решения

Функции превращают большие задачи в маленькие.

К н о п к а H e a t н а т е р м о с т а т е э к в и в а л е н т н а ф у н к ц и и в JavaS cript. И д ея п р о с т а я — ч ел о в е к п р о с и т сдел ать п о т е п л е е, и ф ун кц и я осу щ ествл яет н агр ев. Д е та л и р е а л и за ц и и ск р ы т ы вн утри и для кода, к о т о р ы й его в ы зы в ает, н е важ н ы . Ф ункцию м о ж н о п р ед ­ с т ав и ть в виде « ч ер н о го ящ ика» — и н ф о р м а ц и я н а входе и и н ­ ф о р м а ц и я н а вы х о д е, а за то , ч т о п р о и с х о д и т вн утри , о т в е ч а е т сам ящ и к.

Просьба сделать тепло

Нагрев

Н а я з ы к е Jav aS crip t н а ж ат и е к н о п к и H e a t эк в и в ал ен т н о вы зову ф у н к ц и и h e a t ( ) ...

Просьба оде лать тепло

heat О ;

function heat о

{

// Увеличим температуру

^

Нагрев Т о м у , к т о хо ~ чет увеличит ь т ем п ер а т ур у, до­ ст а т о ч н о вы зват ь ф у н к ц и ю heat().

shovelCoalО ; lightFire О ;

За нагрев о т в е ч а ю т т р и другие ф ункции.

harnessSun();

} В олноват ь­ ся о т о м , как им енно о с у щ е с т ­ в л я е т с я нагрев, должен т о ль к о человек, ко т о р ы й пиш ет ф ункцию кеа±().

270

глава 6

Н е и м е е т зн а ч е н и я , к аким образом ф ун кц и я h e a t () осущ ест­ в л я е т н агрев. В аж н о т о л ь к о то , ч т о о н р е ш а ет наш у проблем у. Х о т и т е с о гр еть с я , в ы зо в и т е эту ф ункц ию . Э то все, ч т о вам тр еб у ется зн ать.


функции

(1з чего состоит функция Р еш и в со зд ать ф у нкц ию , вы б е р е т е н а себ я о т в е тс т в е н н о с т ь за р е ш е н и е о п р е д е л е н н о й задачи. Вы д о лж н ы и сп о л ьзо в ат ь о п р е д е л ен н ы й си н так си с, связы ваю ш ,ий и м я ф у н кц и и с запу­ скаем ы м ею кодом . В от как о н в ы гл яд и т в общ ем виде; В начале и д ет клю чевое слово fu n ctio n .

З а т ем — идент иф икат ор, ■написанны й с п р и м е н е н и е м ст и ляВ ерблю д а.

К од 6 т е л е ф ункции п р е д ­ с т а в л я е т собой обычный сост авной о п е р а т о р , п о э т о м у он начинает ся с ^>игурной скобки.

function \ +

V И м енно в т е л е ф ун кц и и р еш а ет ся непосредст венная задача. в конце ф ункц и и не за б уд ьт е п о с т а в и т ь за к р ы ва ю щ у ю ф и ­ г у р н у ю скобку.

Скобки у к а зы ва ю т на т о , ч т о перед н ам и ф ункция.

Е щ е р аз в н и м ател ьн о п о см о тр и м н а код ф у н кц и и h e a t ( ) , ч т о ­ б ы з а к р е п и т ь п о л у ч ен н ы е зн а н и я о си н такси се:

function heat () { II

Увеличим температуру

shovelCoal(); Н агревание о с у ­ щ е с т вля е т ся в т е л е ф ункции.

lightFireО ; harnessSunО ;

Тело ф ун кц и и заклю чено в ф и гурны е скобки и я в ­ л я е т с я обычным с о с т а в ­ ны м о п ер а т о р о м .

Ш ТУРМ Какие еще функции вы можете вспомнить?

далее >

271


мет оды m andango

У)ке знакомые Вам функции Н е т а к д авн о м ы п р е к р а с н о с п р а в и л и сь с п р о б л ем о й . П о м н и те про гр ам м у M a n d a n g o д ля п о и ск а м ест в к и н о т еа тр е? Вам т р е б о ­ вал о сь и н и ц и а л и зи р о в а т ь д ан н ы е о м естах. В от каки м о б р азо м мы п о д ел и л и глобальную задачу н а б о л ее м елкие: больш ая задача.

Поиск м е с т Зля Майо

А в е м еньш и е задачи. Поиск м ест

И ни ц и а ли за ц и я м ест

М с-

И н и ц и а л и за ц и я к р е сел это м ал ен ькяя задача, к о т о р а я м ож ет б ы ть р е ш е н а п р и п ом о щ и ф у н кц и и i n i t S e a t s ( ) :

function initSeatsо { // Задаем вид всех кресел for {var i = 0; i < seats.length; i++) { for (var j = 0; j < seats[i].length; j++) if (seats [i] [j ]) { // Задаем свободные места (i document.getElementByld("seat" (i document.getElementByld("seat”

seats[i].length seats[i].length

j)).src j)).alt

"seat^avail.png"; "Available seat";

} else { // задаем занятые места document.getElementByld("seat" document.getElementByld("seat"

seats[i].length + j)).src = "seat_unavail.png" seats[i].length + j)).alt = "Unavailable seat"

}

Ф ункция i n i t S e a t s {) я в л я е т с я частью в еб -стр ан и ц ы M a n d an g o Д ля е е в ы зо в а н ам п о тр еб у ется св я за ть е е с о б р аб о т ч и к о м со б ы т и я o n l o a d . В р езу л ьтате ф у н кц и я будет запускаться п о сл е загрузки стр ан и ц ы .

А.А ч

iriitSeatsQ не ед и н ст вен н а я ф ункция О M andanqo. andango.

/

<body onload="initSeats(); "> <div style="height:2 5 p x "x/div>

<div style="text--align: center"> <img id="seatO" src="" alt="" />

<img id="seat35" src="" alt="" / x b r /> <input type="button" id="findseats" value="Find Seats" onclick- 'findSeats0 ;" /> </div> </body> </html>

272

глава 6


функции Часзи»

^аД аБаеМ ы е Б о 1 ]|э о С Ь 1 Каким образом составляются имена функций? 0 ; Первое слово пишется прописными буквами, в то время как все остальные

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

начинаются со строчных. Поэтому функцию оценки фильмов мы назовем

читаемым.

r a t e M o v i e ( ) , а функцию вывода из зала мужчины, который хочет во

^ Как определить, какой фрагмент кода может быть помещен внутрь функции?

время сеанса говорить по телефону —

логических частей.

r e m o v e In a p p r o p r ia te G u y ( ) .

Всегда ли функции превращают большие задачи в набор более мелких?

0=

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

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

0 ; к сожалению, алгоритма, позволяющего однозначно определить, что вот этот фрагмент кода будет уместен в виде функции, не существует. Но существует ряд признаков, на которые имеет смысл обратить внимание. Одним из таких признаков является дублирование кода. В этом случае вы попадаете в ситуацию, когда, например, вносить одинаковые исправления

В книге упоминалось, что ( >ункциям можно передавать аргументы и получать от них данные. Это действительно так? ! Вы правы. Функции действительно берут и возвращают данные. И скоро вы увидите эту процедуру на примере функции h e a t ( ) .

Значимое имя позволяет сразу понять назначение функции. Присвойте этим функ­ циям названия, не забывая про СтильВерблюда.

Request aisle s e a t.

Ask for refund

Throw popcorn

Receive tic k e t for aisle seat

G et refund

Popcorn is hurled a t others

далее *

273


решение упражнения

Вот какие имена можно присвоить описанным ниже функциям.

пражнш е решение Request aisle s eat — . >

Receive tic k e t for aisle seat

requestAisleSeatQ

A sk for refund

G et refund g e tR e fu n d Q

T h ro w popcorn

Popcorn is hurled a t others th ro w P o p co rn Q

НЫК при помощи ст иляіерблюда

Меня просто поджарили! Неужели это Эффект локаль­ ного потепления?

Слишком )карко П о к а ч то п о п ы тк и у стан о в и ть м и р во всем м и р е путем у п р ав л ен и я кл и м атом т е р п я т неудачу. К аж ется, н аш а к н о п к а H e a t р а б о т а е т слиш ком х о р о ш о . А м о ж ет б ы ть, п р о б л е м а в н е д о с та тк е д ан н ы х д ля ф у н кц и и h e a t () . К ак бы т о н и б ы ло , ситуацию нуж но и сп р ав л ять.

274

глава 6


функции

Улучшаем наш терм остат Т е р м о с т а т н е зн а е т , когд а следует о с т ан о в и т ь н агр ев, т ак как нужную н ам тем п ер ату р у м ы н е указали. П о л у чается, ч т о для э ф ф е к т и в н о г о р е ш е н и я п р о б л ем ы н е д о с та т о ч н о д ан ны х. И п о ­ сле н а ж ат и я к н о п к и H e a t т е м п е р а ту р а будет р а с ти бескон еч н о!

Э т о т регулят о р помож ет задать ж елаемую т ем п ер а т ур у.

HEAT FIRST

Н о в а я в е р с и я т е р м о с т а т а п о зв о л я е т указы вать ж ел ае­ мую тем п ературу. И б лагод аря этом у лучш е сп р ав л я е тся с зад ач ей «нагрева».

Просьба сделать теплее

Желаемая температура

Ж елаем ая т е м п е р а т у р а

СГе

ГІраЖН€НУ12

ЛлГфак“кц»,

Нагрев

^

heat (targetren*.) ;

Напишите код функции h e a t ( ) . Функция должна использовать в качестве параметра указанную пользователем температуру и осуществлять нагрев только до ее достижения. Подсказка: температуру в данный момент определяет функция

g e t T e m p (). fu n c tio n h e a t(ta rg e tT e m p ){ Первая с т р о ч к а ....................................................................................................................................... уж е написана.

далее *■

275


решение упражнения

іажнение У гш гн м

Вот как выглядит новый код функции h e a t ( ) , написанный с учетом перечисленных на предыдущей странице пожеланий:

fu n c tio n k e a t(ta r g e tT e m p )l

................... Ж ела ем а я т е м п е р а т у ­ р а п ер ед а ет ся ф ункц и и в ка ч ест ве а р гу м е н т а .

Н агрев н а ч и н а е т ­ ся т о ль к о в случае, когда окруж аю щ ая ‘т е м п е р а т у р а м е н ь ­ ш е желаемоіл.

w hile (g e tT e m p O < ta rg e tT e m p ) { ■/ / Н агрев ..................................................................... Ж ёлШ М -ая-т е-м пер-ат т . skovelCoalQ; иказы вает ся в услооии .....;........................................................ Ш б -д а -us-цикла-.while ........ lightFireQ; harnessSunQ ; }

Передача информации функциям Д ан н ы е п ер ед аю тся ф у н кц и ям Jav aS crip t п р и п ом ощ и аргументов. С н о в а в н и м ател ь н о р а с с м о тр и м си н такси с; о б р а т и т е вним ан и е н а то , ч то аргум ен ты ф у н кц и и зак л ю ч ен ы в скоб ки .

ß ^ указан о бы т ь число а р г у м Т н т о Т ^ ^

_^ Аргументы

Т е ло м ф ун кц и и а р гу м е н т ы во с п р и н и м а ю т с я как и н и ­ ц иализированны е локальны е перем енны е. Т е о р е т и ч е с к и вы м о ж ете п е р ед ать ф у н кц и и п р о и зв о л ь н о е к о л и ч е с т в о аргум ен тов, н о с п р а к т и ч е с к о й т о ч к и зр е н и я ж е л а т е л ь н о о г р а н и ч и т ь с я двумя-трем я. В ка ч е ств е аргум ента м о ж е т вы ступ ать л ю б о й ф р а гм е н т и н ф о р м ац и и : к о н стан та ( M a th . P I), п е р е м е н н ая (tem p) и л и п о с т о я н н о е зн а ч е н и е (72).

276

глава 6


функции

Аргументы как данные Д а н н ы е , п е р ед ав аем ы е ф у н кц и и в к а ч е с тв е аргум ента, п од об ­ н ы и н и ц и а л и зи р о в а н н ы м л о кал ьн ы м п ер ем ен н ы м . В к ач естве п р и м е р а р а с с м о тр и м ф ункц ию h e a t ( ) , к о т о р о й п е р ед ает с я ж ел аем ая тем п ер ату р а: heat (72) ;

ігГ------Ж ела ем а я т е м п е р а т у р а функции 6 биЭе иислобом к о н с т а н т ы .

ф у н к ц и я h e a t () в о с п р и н и м а е т ар гу м ен т t a r g e t T e m p как локальную п е р е м е н ­ ную, к о т о р о й б ы л о п р и с в о е н о н а ч а л ь н о е зн а ч е н и е 72. П о ст ав и м в т е л о э т о й ф у н кц и и код, в ы зы в аю щ и й о к н о д и а л о га со зн а ч е н и е м аргум ента.

72 function heat(targetTemp)

{

В т е л е ф ун кц и и heatQ а р г у м е н т вы глядит как ло к а ль н а я перем енная.

alert (targetTeii5>) ; } После за вер ш ени я р а б о т ы ф ун кц и и п ер ем ен н а я ta r g e tT e m p уда ляет ся.

С1Ж Э

Х о тя ар гу м ен т и н а п о м и н а е т локальную пер ем ен н ую , р е д а к ти р о в а н и е его в н у т р и ф у н кц и и н и н а ч т о н е в л и я е т . Э то п р а в и л о н е о т н о си т ся к п ер ед ав аем ы м в к ач еств е аргу м ен то в о б ъ ектам , н о о н и х м ы п о го во ­ р и м в главах 9 и 10.

var ten^j = 80; coollt (ten^)) ; alert (teir^)) ;

Н есм о т р я на и з ­ м енени е т е м п е ­ рат уры внут ри ф ункции, внеш ­ няя п ер ем енна я о ст а ла с ь н е и з­ м енной.

П ерем енная te m p была передана ф ун кц и и в качест ве а р гу м е н т а .

У м ен ьш и т е значение т е м п е р а т у р ы на і-

function coollt(temperature) temperature— ;

С

далее >

277


удаляем дубли при помощи мет одов

избавляемся о т дублирующегося кода Ф ун кци и н е т о л ь к о п о зв о л я ю т р а зд ел и ть больш ую задачу н а н еск о л ьк о б о ­ л ее м елких, н о и даю т в о зм о ж н о с ть и зб а в и т ьс я о т дублирую ш;егося кода. И м е н н о т а к н азы в аю тся о д н и и т е ж е ф р а гм е н т ы , появляю ш ;иеся в р а з­ н ы х м естах с ц е н а р и я. К од м о ж ет н е б ы ть п о л н о стью и д ен ти ч н ы м , н о во м н о ги х случаях все р а в н о и м е е т см ы сл п р е в р а т и т ь его в ф у н к ц и ю . В р езу л ьтате, есл и вам н ео б х о д и м о о т р е д а к т и р о в а т ь какой-то ф р а гм е н т , уже н е п о тр еб у ется и ск ать все его в х о ж д ен и я в с ц е н а р и й , д о ст а т о ч н о будет в н е с ти и зм е н ен и я в т е л о ф ункции:

// В и л е т на д н е в н о й сеанс,

м е н ь ш е на 1C

m a tin e e T ic k e t = a d u ltT ic .e t

/ /

*

Детский

(i

f/

_ о . 10, ;

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

Б и л е т д ля

U n io rT ic k et

}

= a d u ltT ic k e t

(1 - 0.15) ;

билет

c h ild T ic k e t

=

a d u ltT ic k e t

Г П о к а за н н ы е вы ш е зад ач и сво д ятся к в ы ч и сл ен и ю ц ен ы б и л ето в с у ч ето м р а зл и ч н ы х скидок. Н о н а сам ом дел е м о ж н о о г р а н и ч и т ь ­ ся за д ач е й п о в ы ч и сл ен и ю ц ен ы н а о с н о в е зад ан н о го п р о ц е н т а скидки:

fu n c tio n r e tu r n

d is c o u n tP r ic e (p ric e , (p ric e

*

(1

-

p e rc e n ta g e )

(p erc e n ta g e

/

{

1 0 0 )));

Функции воз вращ аю т данные. B ut как будут выглядеть указанны е выше ф рагм енты кода после создания функции d i s c o u n t P r i c e : // Б и л е т на

д н е в н о й сеанс,

m a tin e e T ic k e t

меньше на К

// Б и л е т

= d isc o u n tP ric e (a d u ltT ick e t,

/ /

Детский

билет,

10) ;

меньше

Г ® " ^ ° ^ Т 1с к е Г

на

глава 6

м е н ь ш е на 15%

= d iisco u n tP ric e (a d u ltT ic k e t,

20-s

childTicket = discountPrice(adultTicket,

278

пенсионеров,

20);

15);


функции

^ щ а н ь

эК сяер ш о М

П о

Э‘

Циж е Показан к°Д «рункЦии fmJ^eatsO us программы ]\|EnJango. ЦсЛоЛьЗуя Полученные знания, оёБедшюе

'рраГМеашы Кода, к°іворьіЄ М оїуш Тіосяужитоь осЯоБой ДЛЯ ноБьіх <|>ункЦий.

function f i n d S e a t s о { // Е с л и м е с т а у ж е выбраны, if

(selSeat >= 0) s e l S e a t = -1; initSeats О ;

произведите повторную инициализацию

{

// П о и с к с в о б о д н ы х м е с т с р е д и в с е х в о з м о ж н ы х v a r i = О, f i n i s h e d = false; w h i l e (i < s e a t s . l e n g t h && Ifinished) { for (var j = 0; j < s e a t s [ i ] .length; j++) { // П р о веряем, с в о б о д н о л и в ы д е л е н н о е м е с т о и д в а м е с т а за if (seats[i][j] && s e ats[i][j + 1] &s seats[i][j + 2]) { // В ы д е л я е м к р е с л а и о б н о в л я е м и х вид s e l S e a t = i * s e a t s [ i ] .l e n g t h + j; s e a t s [ i ] .l e n g t h + d o c u m e n t . g e t E l e m e n t B y l d ( " s e a t " + (i s e a t s [ i ] .l e ngth + d o c u m e n t . g e t E l e m e n t B y I d ( " s e a t " + (i s e a t s [ i ] .l e n g t h + d o c u m e n t . g e t E l e m e n t B y I d ( " s e a t " + (i s e a t s [ i ] .l e n g t h + d o c u m e n t .g e t E l e m e n t B y l d ( " s e a t " + (i s e a t s [ i ] .length + d o c u m e n t .g e t E l e m e n t B y l d ("seat" + s e a t s [ i ] .length + d o c u m e n t . g e t E l e m e n t B y l d ("seat" + (i

ним

j) ) . s r c = " s e at_select.png"; j )).alt = "Your seat"; j + l) ) . s r c = " s e at_select.png"; j + l) ) . a l t = "Your s e a t ” ; j + 2 ) ) . src = " s e a t _ s e l e c t . p n g " ; j + 2 ) ) . alt = "Your seat";

// П о л ь з о в а т е л ю п р е д л а г а е т с я п р и н я т ь п р е д л о ж е н н ы й ва р и а н т v a r a c c e p t = c o n f i r m ("Sea t s " + (j + 1) + " t h r o u g h " + (j + 3) + " in R o w " + (i + 1) + " are ava i l a ble. Accept?"); if (accept) { // К р е с л а з а б р о н и р о в а н ы , п о э т о м у р а б о т а в н е ш н е г о ц и к л а з а к о н ч е н а f i n i s h e d = true; break;

} еІЕ ,олжаем п о и с к s e l S e a t = -1; d o c u m e n t .g e t E l e m e n t B y l d ("seat" + document.getElementByld("seat" + d o c u m e n t .g e t E l e m e n t B y l d ("seat" + d o c u m e n t .g e t E l e m e n t B y l d ("seat" + d o c u m e n t .g e t E l e m e n t B y l d ("seat" + d o c u m e n t .g e t E l e m e n t B y l d ("seat" +

(І (І (І (І (i (І (І

* * * * * *

s e a t s [i] s e a t s [i] s e a t s [i] s e a t s [i] s e a t s [i] s e a t s [i]

.l ength .l ength .l e n g t h .l e n g t h .l e ngth .l e ngth

+ + + + + +

j)) .src j) ) .alt j + D ) .src j + 1) ) .alt j + 2) ) .src j + 2) ) .alt

// У в е л и ч и в а е м с ч е т ч и к в н е ш н е г о ц и к л а на е д и н и ц у i++;

далее >

279


помогите с реш ением

еШ ение З а д а ч и

какие '^аШ енгры «^ункДии GnJ^eatsQ из г^оХ^аММы ]^апс14Ю£о

Мо1^ , Б cBojo оЧе]=>еДь, служииаь осноБой для других •функций.

function f i n d S e a t s о

{

// Е с л и м е с т а у ж е выбраны, if (selSeat >= 0) { se l S e a t = -1; in i t S e a t s ();

произведите повторную инициализацию

} // П о и с к с в о б о д н ы х м е с т с р е д и в с е х в о з м о ж н ы х va r 1 = 0 , f i n i s h e d = false; w h i l e (i < s e a t s . l e n g t h && Ifinished) { for (var j = 0; j < s e a t s [ i ] .length; j++) { // П р о веряем, с в о б о д н о л и в ы д е л е н н о е м е с т о и д в а м е с т а за н им if (seats[i][j] &s sea t s [ i ] [ j + 1] && seats[i][j + 2]) { // В ь щ е л я е м к р е с л а и о б н о в л я е м и х вид s e l S e a t = i * s e a t s [ i ] .l e n g t h + j; - d o c u m e n t .g e t E l e m e n t B y l d (" s e a t ’'.+ (1 ~ ~ ^ ^ ~ з ё а ^ Т Г 7 Т Ш д Г Т Г Т - 1 Т Г Г з г с ~ ^ ~ ^ ^ ^ o c u m e n t . g e t E l e m e n t B y I d (V " s e a t " -r + v (i s e a t s [[ Ji.J].l eu ng tn h -+I- j ) ) . a l t = ”" iYoouu r seat"; -L * atiduto . j.e yc r s eat"; —^ d o c u m e n t .g e t E l e m e n t B y l d ("seat " ' ■ T i r ‘‘^‘‘'^^StiTi77TSrgt!rT°l + 77')';sTc ^ o c u m e n t . a e t ^ l e m e n t B v I d ( " s e at" + (i * seats [i 1 .l e n g t h + i + l ) l . a ] t = "Your seat": d o c u m e n t . g e t E l e m e n t B y I d ( " s e a t " + (i * s’ ^ i t i T T T T l e ^ f ^ i t t ' T T ^ 2 ) ) " . src = " seat .select. ^-■^Jtoc.ument.getElementBvId.(.".s.e.at" + (i * seats Til ,l e n g t h + -j + 2 n . a l t = "Your- ___________ // П о л ь з о в а т е л ю п р е д л а г а е т с я п р и н я т ь п р е д л о ж е н н ы й в а р и а н т v a r a c c e p t = c o n f i r m ( " S e a t s " + (j + 1) + " t h r o u g h " + (j + 3) in R o w " + (i + 1) + " a r e ava i l able. A c cept?"); if (accept) { // К р е с л а з а б р о н и р о в а н ы , f i n i s h e d = true; break; else ( // П о л ь з о в а т е л ь s e l S e a t = -1;

поэтому работа внешнего цикла закончена

отказался,

продолжаем поиск

^ - T l o c u m e n t .g e t E l e m e n f B y T a d o c u m e n t .g e t E l e m e n t B y l d (" s e a t " + (i d o c u m e n t .g e t E l e m e n t B y rai'"seat'"'"‘T — П D o c u m e n t . g e t E l e m e n t B y l d ( " s e a t " + (i ■aocument.g e t E l e m e n t B y l d ("seat" + 7 Г d o c u m e n t ■g e t E l e m e n t B y l d ("s eat" + (i

}

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

"^■етг^ахгэтгтрнд* seats [i] .length + .length 4seats[i .l e n g t h + seats [i)'"iengETr+ seats[i].length +

j ) ) . a l t = "Ava i l a b l e s e a t ' T ^ -I- i)).gf'e' = "Sei r ^ a V a i i . p n l " j 1 ) ) .alt = "__________ A v a i l a b l e _______ seat _ j' ^ "seat _ a v a i l . p n g ^ j + 2 ) ) . alt = "Ava i l a b l e seat";

N // У в е л и ч и в а е м с ч е т ч и к в н е ш н е г о ц и к л а на е д и н и ц у

i++;

280

глава 6

С войст во len g th о п р е д е ля е т число э л е м е н т о в влож ен­ ного м ассива.

^ 3 Зублирующ ^егося кода мож но извлечь некот оры е а т р и б ут ы :


функции

функция, задаюи^ая места Т е п е р ь , когда н аш и п р и ятел и -м ач о о с о зн а л и всю п ользу о т у в е л и ч ен и я э ф ­ ф е к т и в н о с т и , о н и х о т я т с о к р а т и т ь код п р о гр а м м ы M a n d a n g o , д обави в в н ее ф ун кц и и . Н о п р еж д е, ч ем м ы п р и сту п и м к н а п и сан и ю ф у н кц и и s e t S e a t ( ) , т р еб у ется п о н ять, как и е аргум ен ты е й нуж ны . Д л я эт о го поиш;ем в дублирую ­ щ ем ся ко д е т е ф р а гм е н т ы и н ф о р м а ц и и , к о т о р ы е о т л и ч аю тс я друг о т друга. В от к ак и е аргум ен ты будуш;ей ф у н кц и и f i n d S e a t s () мы обнаруж им :

Номер места

в д ан н о м случае эт о н е и н декс м ассива, а н о м е р , к о т о р ы й бы л бы п р и с в о е н месту п р и сч ете - сл ева н а п р а в о и сверху в н и з, н а­

Чувак, нам нужно больше функций!

ч и н а я с 0.

Знаю, но я тебе перезвоню... У меня звонок на другой линии.

Статуе А т р и б у т ы ф ункц и и fin d S ea tsO г\олучены исследованием д у б л и ­ рую щ его с я кода.

М есто м о ж ет б ы ть свободны м , за н я т ы м и л и в ы б р ан н ы м . О т эт о го зав и си т, каки м и зо б р а ­ ж е н и е м о н о будет п р ед став ­ л ен о .

Описание С татус м ест м о ж е т и м е т ь о д н о и з т р е х о п и с ан и й «Available seat», « U navailable seat« и «Y our seat». О н номеш,ается в атр и б у т a l t и зо б р аж е н и и .

Возьми в руку карандаш Напишите функцию s e t S e a t () для программы Mandango.

далее *

281


повт орное использование кода в m andango

Возьми в руку карандаш_ _ _ _ 'ешение

Вот как выглядит функция s e t S e a t {) в программе Mandango.

Три а р гу м е н т а перечислены 'ч е р е з за п я т у ю .

И ндивидуальны е данные из исходно­ го кода з а м е н е ны обобщ енны ми лргум & нщ ам и.

v

v statusJ descrip tio n ) {

<^^Cj^_^^_>^i.g_etElementByld('’seat'' + sea tN u m ).src ~ " s e a tj + s ta tu s + ".png"; d o c u m e n t.g e tE le m en tB yld C 'sea t" +- se a tN u m ).a (t = d escription; ......................... ...................................................................... z

z

..........................

Редактируем код Mandango П р е в р а щ е н и е дублирую щ егося ко д а в ф у н кц и ю s e t S e a t {) зн ач и тел ьн о у п р о сти л о код ф у н кц и и f i n d S e a t s ( ) .

function findSeatsO

п е р ед а ю т с я 6 качест ве а р гу м е н т о в п р и каждом вызове ф ункции setSeatQ .

{

// Поиск свободных мест среди всех возможных var 1 = 0 , finished = false; while (i < seats.length s& Ifinished) { for (var j = 0; j < seats[i].length; j++) { // Проверяем, свободно ли выделенное место и два места за ним if (seats[i][jl &S seats[i][j + 1] ss seats[i][j + 2]) { // Выделяем кресла и обновляем их вид selSeat = i * seats[i].length + j;

'

f s e ts e a td * seats [il.len g th + j , "select", ™ >' * seats [i] .length + j + 1, "select". Your seat , T s e ts e a td * seats [il.len g th + j + 2, "select" ,^ ^ Y o u rje a tJ^

J se tS e a td

/ / п о л ь з о в а т е л ю п р е д л а г а е т с я п р и н я т ь предл о ж е нн ы й в а р и а н т v a r a c c e p t = c o n f i r m ( " S e a t s " + (j + 1) + " t h r o u g h + (3 + 3) " i n Row " + ( i + 1) + " a r e a v a i l a b l e . A c c e p t ? " ) ;

Новая ф ункц и я se tS e a tQ вы зы ва­ е т с я ш ест ь раз.

^ ^ //^ К р е с л а забронированы,

+

поэтому р а б о т а внешнего цикла за к о н ч е н а

fin ish e d = tru e; break;

} else { // Пользователь отказался, продолжаем поиск

S s S e a t ( i * seats [il.len g th + j, "avail", "Available seat"); ( setSeat(i * seats [il.len g th + j + 1, "avail", Ava^.lable seat , L se tS e a t(i * seats[i] .length + j + 2, "avail". Available seat ), 1

)

)

// Увеличиваем счетчик внешнего цикла на единицу

І++;

282

глава 6


функции

Усовершенствование Mandango Ф ункция s e t S e a t () вы го д н а н е т о л ь к о с т о ч к и зр е н и я со к р ащ ен и я кода ф у н кц и и f i n d S e a t s ( ) . У в е л и ч и в а е тс я такж е э ф ф е к т и в н о с т ь ф у н кц и и i n i t S e a t s ( ) , в к о т о р о й п р и сутствует п о х о ж и й код. function initSeatsо { // задаем вид всех кресел for (var i = 0; i < seats.length; i++) for (var j = 0; j < seats[ll-length, if (seats[i][jl) ( // Задаем свободные места docvment.getElementById("seat" ^ (i document. getElementBy Id ("seat" H (i

seats[i].length + j))-src seats[i].length + j))-alt

"seat_avaxl.png "Available seat кода

) else { // Задаем занятые места document. getElementByld ("seat" ■ (i (i document.getElementByld (' seat

} )

fu n ctio n i n i t S e a t s о { / / З а д аем вид в с е х к р е с е л f o r ( v a r i = 0; i < s e a t s . l e n g t h ; i+ + ) f o r ( v a r j = 0; j < s e a t s [ i ] . l e n g t h ; if (se ats[il[j]) { / / Задаем свободные м еста setSeat(i * seats[i].length + j

Если обобщ ит ь пр о ц едур у задания вида кр есла , ф ункция setS eд tO хорош о р а б о т а е т и в э т о м случае.

e lse { / / Задаем заняты е места setSeat(i * seats[i].length + j seat");

'Available seat");

"unavail", "Unavailable

}

И та к , в с ц е н а р и и п р о гр а м м ы M a n d a n g o т е п е р ь восем ь р а з в ы зы в ае тся н е­ сл о ж н ая ф у н кц и я, со с то я щ а я и з п а р ы с т р о к кода. Э то н е т о л ь к о у п р о щ ае т код сц е н а р и я , н о и о б л е гч а ет его р е д а к ти р о в а н и е . В едь для и зм е н е н и я сп особ а зад ан и я м ест д о ст а т о ч н о в н е с т и и с п р ав л е н и я в ф ункц ию s e t S e a t ( ) . Э то нам н о го уд обн ей р е д а к т и р о в а н и я в о сьм и р а зб р о с а н н ы х по всем у сц ен ар и ю ф р а гм е н т о в кода.

КЛЮ ЧЕВЫЕ МОМЕНТЫ

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

функции предоставляют механизм разделения задач и превращения их в код многократного использо­ вания.

Функции позволяют избавиться от дублирующе­ гося кода, ведь их можно вызывать произвольное количество раз. Передача данных функциям осуществляется при помощи аргументов.

далее >

283


не бойся спросить _

Часщо

^аД аБаеМ ы е - Э

Ограничено ли количество передаваемых функции аргументов?

Б

о

Ц ^ э о С Ь !

) • Мы узнали, что функции позволяют делить крупные задачи на более мелкие, разделяют процесс написания сценария и устраняют дублирующийся код. Они действительно настолько универсальны?

0 ; И да, и нет. Если не брать в расчет ограниченность памяти компьютера, то формальных ограничений на количество передаваемых аргументов нет. Впрочем, если вы передали функции столько аргументов, что возникли проблемы с оперативной памятью, вам явно нужно сделать паузу и подумать над своими действиями. С практической точки зрения количество аргументов желательно выбирать таким образом, чтобы вызов функции не превратился в несуразно сложную задачу.

! Да, действительно. Часто функция помогает решить несколько проблем одновременно. Впрочем, если попытаться указать главное достоинство функций, наверное, это будет разделение процесса написания сценария на фрагменты.

Напомните, где именно должны появляться функции, в заголовке или в теле веб-страницы?

0 1 Функции могут располагаться, как внугри тега < s c r i p t > в заголовке страницы, так и во внешнем файле, импортированном в заголовок.

Как сделать, чтобы функция меняла значения аргументов?

О

; Напрямую изменить аргументы функции нельзя, точнее говоря, эти изменения никак не отразятся на сценарии за пределами функции. Так что для изменения фрагмента данных, который передается в качестве аргумента, нужно получить от функции измененное значение. О том, как это сделать, вы узнаете чуть позже!

С термостатом что-то не так. Я замерзаю!

Зима 8 июле с пом ощ ью ф у н к ц и й м ы улучш или програм м у M a n d a n g o , а в о т в об­ л а с ти к л и м ат-ко н тр о л я так и м и резу л ьтатам и п о х вастаться п о к а н е п олучается. К аж ется, т е р м о с т а т все р а в н о р а б о т а е т н е к о р р е к т н о . Т о л ьк о п о с м о т р и т е н а д р о ж ащ его п о л ьзо в а т ел я, скучаю щ его п о н е­ п р е р ы в н о м у н агреву п осл е н аж ати я к н о п к и H eat.

284

глава 6


функции

Обратная связь Б л а го д а р я ф у н кц и и наш т е р м о с т а т п о зв о л я е т зад ать нужную тем п ературу, но о н н е сообш ,ает о то м , н аск о льк о т е п л о в пом еш ,ении в д ан н ы й м ом ент. А эт о о ч е н ь в аж н ы й п а р а м е т р , т а к как и м е н н о о н я в л я е т с я о с н о в о й для д о с т и ж е н и я ж ел аем о й тем п ер ату р ы . К р о м е т о го , в о д н и х и т е х ж е усло­ в и я х р а зн ы е т е р м о с т а т ы м огут и м еть р а зн ы е п о к азан и я . С о о т в етст в ен н о , для к о р р е к т н о й р а б о т ы си стем ы нам нуж на о б р ат н а я связь.

О кно « т е/Л і^ер лт ур а ° м н ш й м ом е««» инф орм ации} о т о м . на

“ а“ » в л я т ь нагрей. В к ач е с тв е о б р а т н о й св я зи т е р м о с т а т т е п е р ь п е р и о д и ч е с к и п о ­ ка зы в а е т тем п ер ату р у Б п о м е щ е н и и в д ан н ы й м ом ент.

Возвращ енное Ж елаем ая

зн а ч ен и е теку-

температура Температура

^

щей температуры

в данны й мо­ ф ункция д е Ш т р О п о зв о ­ ляет определит ь т е к у ­ щ ую т ем перат уру-

мент^

д е Ъ Т е т р ()

Функция возвращ ает значение т ем перат уры о данный м ом ент .

И так , нуж но, ч то б ы ф у н кц и я в о зв р ащ ал а и н ф о р м а ц и ю вы звавш ем у ее коду.

ГШ ТУРМ Каким образом можно получить данные от функции?

далее >

285


ответ на за п р о с

Возврат данных Ч т о б ы за с т ав и ть ф ункц ию вер н у ть д ан н ы е, и сп ользуется клю ­ ч ев о е сл ово r e t u r n . П о сл е н его у казы вается, к ак и е и м е н н о д ан н ы е вы х о т и т е получить.

Оператор return позволяет получить данные от функции.

re tu rn

К лю чевое слово r e tu r n у к а в п .й Т ф ункц и я во звр а щ а ет з н а ч е н и !

К акое им енно значение б уд ет возвращ ено, за ви с и т о т ваш его выбора.

П о л о ж е н и е к л ю чево го сл о в а r e t u r n в т е л е ф у н кц и и т е о р е т и ч е с к и м о ж ет б ы ть лю бы м ; но следует уч и ты в ать, ч то п о сл е в ы п о л н е н и я это го о п е р а т о р а ф у н кц и я п р е к р а щ а е т свою работу. Д ругим и слова­ м и, д ан н ы й о п е р а т о р н е т о л ь к о в о зв р а щ ае т д ан н ы е, н о и п р е р ы в а е т р або ту ф ун кц и и . Н а п р и м е р , ф у н кц и я g e tT e m p () за в е р ш ает с я после в о зв р а щ ен и я п р о ч и т а н н о й с д и сп л ея текущ ей тем п ер ату р ы ,

function getTen^) () { // Считывание и преобразование текущей температуры var rawTemp = readSensor() ; var actualTeir^j = convertTen^ (rawTenp) ; return actualTea^;

V

}

благодаря о п е р а т о р у r e tu r n ф ункция во зВ р а -^ щ а е т значение т е к ущ е й т ем перат уры .

На дисплее д а н ­ ные от ображ аю т ся V ф ор­ м а т е , ц их т р е д у преоб р а зо ва т ь о градусы.

Если п о м н и те, ф у н кц и я g e tT e m p () уже и сп о л ьзо вал ась в сц е н а­ р и и р а б о т ы н аш его тер м о стата:

function heat(targetTemp)

{

while (getTen^sO < targetTemp) // Начинаем нагрев'

{

функция y e tT e m p Q предост авляет зн а ­ чение, и сп о ль зуем о е . п р и п р о вер ке условия работ ы ц и кла w hite в ф ун кц и и heatQ .

}

} З н а ч е н и е , в о зв р ащ аем о е ф у н к ц и ей g e tT e m p ( ) , п о я в л я е т с я в м е с т о в ы зо в а э т о й ф у н кц и и и с т ан о в и т с я ч астью п р о в е р к и усл ови я в ц и к л е w h ile .

286

глава 6

Возвращаемое значение появляется на месте вызова функции,


функции

возвращаемые значения Т ак как о п е р а т о р r e t u r n п р и в о д и т к за в е р ш е н и ю ф у н кц и и , его м ож ­ но и с п о л ьзо в ат ь для у п р ав л ен и я п р о ц ессо м р аб о ты . В общ ем случае резул ьтато м п р и м е н е н и я ф у н кц и и с ч и та е т с я и м е н н о в о зв р ащ ен н о е е й зн а ч е н и е . Р ассм о тр и м ф ункц ию h e a t ( ) :

function heat(targetTen^) if (getTempO >

П о м ни т е п е р е м е н н у ю a c tu a lT em p ? И м енно благо даря ей ф ункций g etT e m p O во звр а щ а ет значение.

{

targetTemp)"^

Е сли на гр ев не т р е б у е т СЯ,, во звращ аем значение false и за ве р ш а е м р а б о т у ф ун кц ми.

return false; while (getTen^O < targetTen^)

Э т о т код вы п о л н яет нагрев, влияя, т е м с а м ы м , на т е м п е р а >муру и на значение, возвращ аем ое ф ун кц и ей g e tT e m p ().

// Осуществляется нагрев

_ Нагрев за вер ш ен , п о э т о м у во звр а щ а ет ся значение tru e. } Т о есть п р и по м о щ и в о зв р ащ аем о го л о ги ч ес к о го зн а ч е н и я м о ж н о уп рав­ л я т ь р а б о т о й ф у н кц и и и указы вать как н а успеш ное за в ер ш е н и е н ек и х о п е р а ц и й , так и н а неудачу. Д л я вы х о д а и з ф у н кц и и о б ы ч н о и сп ользуется о п е р а т о р r e t u r n , п р и это м н и к а к и х зн а ч е н и й н е в о звр ащ ается . П о см о ­ т р и т е н а ещ е одну вер си ю ф у н кц и и h e a t ( ) , р а б о т а к о т о р о й п р е р ы в а е т с я о п е р а т о р о м r e t u r n , если н а гр е в н е тр ебу ется.

function heat(targetTemp)

{ О п е р а т о р r e tu r n за ве р ш а ет р а б о т у ф ункции на э т о м э т а п е , т а к как на гр ев в э т о м случ ае не т р еб ует ся .

if (getTempO >= targetTemp) return;

----- '

while (getTen^O < targetTemp)

{

// Осуществляется нагрев

ф ункция за ве р ш а е т р а б о т у без п о м о щ и о п е р а т о р а re tu rn .

Оператор return может использоваться для за­ вершения работы функции. далее *■

287


оператор return о себе

^ ^ О Т Т Ё Р А Т О Р

О' С Ё Б Б

Интервью недели: С екреты м а с те р а преры вания ф у н кц и й

Head First: Я слы ш ал, ч то вы сп о со б н ы н а й ти вы ­ ход и з л ю б о й ситуации.

л и ч и и эт о го зн а ч ен и я . Если ф ун кц и я н и ч е г о не в о звр ащ ает, т о и за б о ти ть ся н е о чем.

Return: И м е н н о так. П о м е с ти те м е н я в те л о л ю б о й ф у н кц и и , и я н ем ед л ен н о оттуда выйду. И заб ер у с с о б о й дан н ы е.

Head First: П о н я т н о . Т огда д ав ай те п о го в о р и м о ваш и х с п о со б н о стях . З ач ем вооб щ е нуж но п р е ­ р ы в а ть ф ункц ии? П оч ем у н е д ать им завер ш аться ес теств ен н ы м путем?

Head First: И куда вы п о сл е эт о го н ап р ави тесь? Return: Н е за б ы в ай те, ч т о ф у н кц и я в ы зы в а е т ­ ся каким -то кодом . Т ак ч т о вы ход и з ф у н кц и и о зн а ч а е т п р о с т о в о зв р а щ ен и е в э т о т код. Т ам ж е о к азы в аю тся и в о зв р а щ ен н ы е ф у н к ц и ей дан н ы е.

Head First: И как ж е эт о все рабо тает? Return: П р ед став ьте, ч т о в ы зо в ф у н к ц и и —эт о в ы р а ж е н и е , и м ею щ ее н е к и й р езультат. Если ф у н кц и я не в о зв р а щ ае т д ан н ы х , р езу л ь тат о к азы ­ в ается нулевы м. Head First: Если ф ункц ию м о ж н о п р е д с та в и ть в ви д е в ы р а ж е н и я , зн а ч и т, м о ж н о н а зн а ч и т ь в о зв р а щ ен н о е ей зн а ч е н и е какой-нибудь п е р е м е н ­ н ой . Я прав? Return: И н ет, и да. В ы р аж ен и ем я в л я е т с я не сам а по себе ф у н кц и я, а е е вы зов. И и м е н н о вы ­ зо в ф у н кц и и м о ж н о п о м е с т и т ь в код та к и м о б р а­ зом , ч т о в о зв р а щ ен н о е зн а ч е н и е будет н а зн ач ен о п ер е м е н н о й . Head First: А ч т о п р о и с х о д и т с в ы р а ж е н и е м , если ф у н кц и я н е в о зв р а щ ае т зн ач ен и я?

Return: Если для вы х о д а и з ф у н кц и и исп ользую сь я, о н а н е в о зв р а щ ае т д ан ны х, и в ы р а ж е н и е не и м е е т н и како го зн ач ен и я . Head First: А эт о н е п р и в о д и т к проблем ам ? Return: Н ет. З а б о ти ть с я о то м , ч то д ел ать с во з­ вращ аем ы м зн а ч е н и е м , следует т о л ь к о п р и н а­

288

глава 6

Return: Т о т ф акт, ч т о в т е л е ф у н кц и и и м еется н а б о р с т р о к кода, н е о зн ач ае т, ч то все о н и д олж ­ н ы б ы ть вы п о л н ен ы . О ф у н кц и ях в п р и н ц и п е н е и м е е т см ы сла думать как о чем-то, им ею щ ем н ач ал о и кон ец . «Е стественны й » к о н ец м о ж ет расп о л ага тьс я в с е р ед и н е п о м ещ ен н о го в ее тел о кода. В от тут-то н а п ом ощ ь п р и хож у я. Head First: Т о есть вы у тверж даете, ч т о н о р м ал ь­ н о и м еть в т ел е ф ун кц и и код, к о т о р ы й , м о ж ет б ы ть, н и к о гд а н е будет запущ ен? Return: Я б ы сказал, ч то сущ ествует б о л ее од н о­ го сп о с о б а созд ать т е л о ф у н кц и и , и и м е н н о это я пом огаю сделать. Если п р о и с х о д и т н еч то , указы ваю щ ее н а н е в о зм о ж н о с ть п р о д о л ж ен и я р аб о т ы ф у н кц и и , я н ем ед л ен н о е е заверш аю . В то ж е сам ое в р е м я д о ст а т о ч н о случаев, когд а тело ф у н кц и и в ы п о л н я ет с я о т п е р в о й до п о сл ед н ей с т р о ч к и , и я там п о я вл я ю сь в лучш ем случае, ч то ­ бы верн уть дан н ы е. Head First: Д ругим и сл овам и, вы п о зв о л я е т е как во зв р ащ ат ь дан н ы е, т ак и у п р авл я ть в ы п о л н е н и ­ ем ф ункций? Return: Д а, и м е н н о так! Head First: П о тр ясаю щ е. С паси бо, ч т о согл аси ­ л и сь с н ам и поб еседовать. Return: Всегда пож алуй ста. А т е п е р ь м н е нуж но о тсю д а вы йти!


функции

пражнение

Кажется, иауаЗспр! попал в эпицентр скандала вокруг климатических изменений. Люди, выступающие за прохладную атмосферу, создали сценарий, распространяю­ щий воззвание против потепления. Но их оппоненты, уставшие от холодов, внесли в код свою лепту, и сообщение перестало появляться. Вам нужно вернуть сценарию первоначальный вид и узнать, что же хотели сказать противники нагрева.

function

showClimateMsgO

{

return; a l e r t ( c o n s t r u c t M e s s a g e ());

} function

constructClimateMsgO

{

var msg = msg +=

"Глобальное

//

"Локальное

if (getTempO > 80) msg += " п о т е п л е н и е "; else msg += "похолодание "; if (true) msg += "не else msg += "это "; if (getTempO <= "/0) return msg + "обман!"; else return msg + "правда!"; return "Я в это не верю.";

function g e t T e m p O { // О п р е д е л я е т т е к у щ у ю

температуру

var actualTemp = readSensorO; return 64;

далее >

289


решение упражнения

ажнение )'"ешение

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

О перат ор retu rn не дает появит ься всплы ­ ваю щ ем у окну.

function

showClimateMsgO

{

a l e r t ( c o n s t r u c t M e s s a g e О );

} function

С э т и м кодом все '^‘^Рядке, т а к как ^появляющееся сооб­ щ ение б удет з а в и ­ сет ь от т екущ ей ^т ем перат уры .

И з-за о п ер а т о ­ ра if-else эт а ст рочка никогда _ не будет вы пол­ няться, п о э т о ­ м у писат ь ее не и м еет смысла.

Спасибо, Java5cripti^

constructClimateMsgO

{

var msg = nisg += -1ЧЗяв&ада«®«-^; // "Локальное \.

^

if

(getTemp 0

>

80)

msg += "потепление "; else msg += "похолодание

Подобное условие не им еет смысла.

if (getTempO <= 70) return msg + "обман!"; else return msg + "правда!";

function getTempO / /

О п р е д е л я е т

{

текущ ую

т е м п е р а т у р у

var actualTemp = readSensor (); return 44^ actualTemp; ^ _____ _

Локальное потепление — это правда! 290

глава 6

Исходный т е к с т был п р евр а щ ен в ком м ент а р и й , а вм е с т о него вписан другой в а р и ­ ант .


функции

информация о статусе места С ета и Д ж е й с о н а уж е т о ш н и т о т р а зг о в о р о в об окруж аю щ ей т е м п е ­ р ату р е, п оэтом у в е р н е м с я к п р о гр ам м е M an d a n g o . Ч а с т ь п о л ь зо в ат е­ л е й ж алуется, ч то по цвету к а р т и н к и с л о ж н о о п р е д е л и т ь с о с т о я н и е м еста. П о это м у им х о т е л о с ь б ы и м еть в о зм о ж н о сть п олучать данную и н ф о р м а ц и ю , н а п р и м е р , по щ елчку. С ловом , п р о гр ам м е наш их м ач о тр еб у ется ещ е о д н а ф ункц ия. М ест а п р о н ум ер о ва н ы слева н а п р а во , сверху вниз, начиная с О.

Как можно думать о температуре, когда надо работать над

Mandango!

«Г а Возвращен

Запрос статуса

^ статус места Статус места

getSeatStatus(seatWum); С т ат ус м е с т а — эт о ст р о ка вида "available", "unavailable" или "yours".

__

Функция getSeatStatus ()

Функции g e t S e a t S t a t u s () не хватает кода, позволяющего определить статус выделенного места. Функция сначала проверяет, относится ли указанное место к набору из трех, выбранных пользователем. В случае отрицательного результата проверяется, свободно это место или занято. Расставьте магниты, чтобы получить недостающие фрагменты. М

g e tS e a tS ta tu s ( s e a tN u m )

f u n c t i o n

i f

........... i =

(

-1

____________

{

+ 1)11 ( .................r e t u r n

..................N .................. -

" y o u r s " ; [ 0 ] . l e n g t h ] ) [ 0 ] . l e n g t h ) ] [

e l s e

i f

r e t u r n

{ .................. [ M a t h , f l o o r

( .............................../

" a v a i l a b l e " ;

e l s e

return

"unavailable";

}

далее >

291


решение задачи с магнитами

Решение задачи с магнитами Вот как стал выглядеть код функции g e t S e a t S t a t u s I

-...ли м е с т о уже вы б р а ­ но, глобальная п ер ем ен н а я se lS e a t и м е е т значение —1 .

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

после подстановки магнитов.

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

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

Здесь мож но было п о ­ с т а в и т ь ц и ф р у <?, но если в б удущ ем вы р е ­ ш и т е п о м е н я т ь число м е с т в р яд у, п р о гр а м м а перест анет коррект но р(^оот ат ь.

Отобра}кение статуса Н уж но, ч то б ы п о щ елчку п о л ь зо в а т е л я н а и зо б р а ж е н и и к р е сл а п о я в л я л ась и н ф о р м а ц и я о статусе эт о го кр есл а. Д л я эт о го нам п о тр еб у ется ф ун кц и я s h o w S e a t S t a t u s ( ) . В п р о ч ем , вся о с н о в н а я р а б о т а будет в ы п о л н е н а т о л ь ­ ко ч т о н а п и с а н н о й ф у н к ц и ей g e t S e a t S t a t u s ( ) .

function showSeatStatus(seatNum)

{

alert("This seat is " + getSeatStatus(seatNum) + "."); }

292

глава 6

Чт обы у зн а т ь ст ат ус м ест а, п е р ед а й т е его н о м е р ф ункции g e tS e a tS ta tu sQ .

Сообщение 0 сост оянии м ест а ф о р м и р ует ­ ся п чут т еМ СЯ ем соединения ст рок.


функции

связь функции с изобра)кением С вязав новую ф у н кц и ю с и зо б р а ж е н и я м и м ест н а веб -стр ан и ц е M an d a n g o , вы д ад и те п о л ьзо в ател ям в о зм о ж н о сть п олучать и н ф о р м а ц и ю о состоян ии^____В данном случ ае ф ункция м ест, щ елкнув н а и зо б р а ж е н и и в ы б р ан н о го кресла. С о б ы ти е o n c l i c k к а з ^ ^ o w 5 e a tS ta tu s() Вызвана д ого и з и зо б р а ж е н и й д о лж н о в ы зы в а ть ф ункц ию s h o w S e a t S t a t u s ( ) : / ‘изображении

<img id="seat23" src="" alt="" onclick="showSeatStatus(23);" />

oee ■

О "

. . . . .

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

КЛЮ ЧЕВЫЕ МОМЕНТЫ

^

Оператор r e t u r n заставляет функцию вернуть данные в вызвавший ее код.

Функция может вернуть только один фрагмент данных.

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

Оператор r e t u r n используется также для преры­ вания работы функций.

далее *

293


структурное улучшение кода

Дублирующийся код С ц е н а р и й M a n d a n g o р а б о т а е т в п о л н е к о р р е к т н о , н о п ар н и стал и задум ы ваться о д о л го с р о ч н ы х п е р с п е к ти в ах . В ч аст­ н о с т и , Д ж е й с о н н ач ал и ссл ед о в ан и е и о б н аруж и л , ч то в с о в р е м е н н ы х в е б -п р и л о ж ен и я х в ы го д н о р а зд ел я т ь код H T M L , Jav aS crip t и CSS. <html> ^^Jtitle>Mandango - The Macho Movie Ticket Finder</title> <script type=”text/javascript">

function initSeats0

{

} function getSeatStatus(seatNum)

{

) function showSeatStatus (seatNum) ( alertC'This seat is " + getSeatStatus (seatNum) +

^ - );

} function setSeat (seatNum, status, description) { status + ".png"; document.getElementById("seaf + seatNum). src d o c u m e n t . getElementByldC’seat" + seatNum).alt - descrapti

function findSeatsO

С м есь J a v a S c r ip t и H T M L м о ж е т б ы т ь и зо л и р о в а ­ на б о б р а б о т ч и ка х с о б ы H T M L -а т р и б у т о в .

{

J ^ d y onload*"initSeats() ;"> <div style-'matgin-top:25px; text-align;center > <img <img <img <img <img <img <img <img <img <lmq <i„g

На ве б ­ ст р а н и ц е M andango перемеш аны

меж ду собой J a v a S c r ip t и HTML.

.ЛШ _ 111

4

.. .. _I alt .howSea id="seatO" src="" onclic)c="showSeatStatus (1); " id="seatl" src="" alt=" o n c l i c k . = " showSeatStatus (2);" id="seat2" src=”" alt=" onclick="showSeatStatus(3);" id="seat3" src-"" alt=" o n c l i c k = " s h o w S e a t S t a t u s (4); id="seat4" src="" alt=" onclick="showSeatStatus(5); id="seat5" src="" alt=" o n c l i c k = " s h o w S e a t S t a t u s (6); id="seat6" src="" alt=" o n c l i c k = " s h o w S e a t S t a t u s (7); id="seat7" src="" alt=" ol n i' c t S t a t u s (8); O H.ciJl.J. -lk'-= " s h o w S e a—--id="seat8" src="" alt id-"seat9" stc-"" a l t - - onolick="sbo«SeatStatus (9); id-"seatlO” stc--' a l t - - onclick-showSeatStatus 10 d-"seatll" src-”" alt-"" onclick."sbo»SeatStatus 11

o n c l i c k = " s h o w S e a t S t a t u s ( 0 ) />

<img alt="" <img id="seatl2 alt="" <img id*"seatl3' ' src=" alt="" <img id="seatl4 ' src=" al t = " " <img id="seatl5" src="' <img id="seatl6" src=’" alt»"' <img id="seatl7” src=‘" alt=" <img id="seatl8" src="' alt=" <img id="seatl9" src='" alt»" <img id="seat20" src=" ' alt=” <img id="seat21" src=" ' alt=" <img id="seat22" src=" ' alt=" <img id="seat23" src=" ■ alt=" <img id="seat24" src=" ' alt=" <img id="seat25" src=" • alt="" <img id="seat26" src=" ■ alt=’’" ait="" <img id="seat27" src=" <img id="seat28" src=" <img id=”seat29" src=" ■' alt="" <img id="seat30" src=" " alt="" <img id="seat31" src=" " alt=""

/> />

/>

/> /> /> /> /xbr /> /> 1 /> , /> /> o n c l i c k = " s h o w S e a t S t a t u s (12), /> o n c l i c k - " s h o w S e a t S t a t u s (13); /> onclick="showSeatStatus(14); /> o n c l i c k = " s h o w S e a t S t a t u s (15); o n c l i c k = " s h o w S e a t S t a t u s (16) /> o n c l i c k = " s h o w S e a t S t a t u s (17);" o n c l i c k = ” s h o w S e a t S t a t u s (18); ’' o n c l i c k = " s h o w S e a t S t a t u s (19);' ' o n c l i c k = " s h o w S e a t S t a t u s (20);' ’

/ X b r /> /> /> />

■/>

o n c l i c k = " s h o w S e a t S t a t u s (21); ’ o n c l i c k = " s h o w S e a t S t a t u s (22);' ’ /> o n c l i c k - " s h o w S e a t S t a t u s (23);' ' /> o n c l i c k = " s h o w S e a t S t a t u s ( 2 4 ) ; ’ />

o n c l i c k = " s h o w S e a t S t a t u s (25); " /> o n c l i c k = " s h o w S e a t S t a t u s (26); " / X b r o n c l i c k = " s h o w S e a t S t a t u s ( 2 7 ) ; '• />

/>

" /> o n c l i c k * " s h o w S e a t S t a t u s (30); " /> o n c l i c k = " s h o w S e a t S t a t u s (31); " /> o n c l i c k = " s h o w S e a t S t a t u s ( 3 2 ) ; " /> o n c l i c k = " s h o w S e a t S t a t u s (33); " /> o n c l i c k = " s h o w S e a t S t a t u s (34); " />

o n c l i c k = " s h o w S e a t S t a t u s (28); on c l ick='’s h c w S e a t S t a t u s (29) ; " />

ait="" <img id="seat32'" src=" <img id="seat33" src=’^^"^ alt="" <img id="seat34" src="" alt^ /--x b r -/> o n c l i c k = " s h oi wws Se eaa ti aitw u-» s (\3 5 ) ; i-toSuc <img id="seat35" src="" alt 'Find Seats" onclick="findSeats0 ; " <input type="button" id="findseats value»

294

глава 6

/>


функции

Отделите функциональность о т содер)кимого Ч ем ж е т а к п л о х с м еш ан н ы й код? В к о н ц е к о н ц о в , о н ведь р аб о т а ет . П р о б л ем ы н а ч и н а ю т в ы р и с о в ы в а т ь с я п р и п о п ы тк е п о с м о т р е т ь н а веб-стран и ц ы с Jav aS crip t н е как н а ст р а­ н и ц ы , а как н а приложения. Д л я д о л го в р е м е н н о й р а б о т ы л ю б о го п р и л о ж е н и я важ н ы акк у р атн о е п л а н и р о в а н и е и структура. Р азд ели в в н е ш н и й вид, со д ер ж и м о е и ф ун кц и о­ н а л ьн о с ть с т р ан и ц ы , вы и зб е ж и те м н о ж ес т в а о ш и б о к и п ол уч и те б о л ее уд обны й для р е д а к т и р о в а н и я код. П р о в е р и м сп р а в е д л и в о с ть эт о го у тв ер ж д ен и я н а п р и м е р е п р о гр а м ­ мы M an d an g o .

Соде|»кимое H T M L -код о п р е д е л я е т структуру д ан н ы х н а с т р ан и ц е и н ап о л н е н и е

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

<style>

Внешний Bug

</style>

С88-код зад ает в н еш н и й вид с т р ан и ц ы , н а п р и м е р ш р и ф ­ ты , ц в е т а и даж е ком п он овку дан ны х.

J

<script> </script>

функциональность

JavaS cript-кoд д ел ает стр ан и ц у и н т е р а к т и в н о й . И м е н н о эта ч асть о т в е ч а е т за выполнение

различных задач.

П одум ай те, как р е а л и зо в а т ь р а зд е л е н и е кода. П р ед стави м , ч то С ет и Д ж е й с о н н аш л и уд ачны й а л го р и т м п о и с к а м ест, к о т о р ы й о н и п р е д п о ч л и бы и с п о л ь зо в ат ь в м есто с т ар о й в е р си и . З н а ч и т , тр еб у ется о т р е д а к т и р о в а т ь п р и л о ж е н и е M a n d a n g o , но, т а к к ак код Jav aS crip t п е р е п л е т е н с кодом H T M L , в п р о ц е сс е и с п р а в л е н и й м о ж н о п о в р е д и т ь структу­ ру ст р ан и ц ы . Н а ск о л ьк о уд обн ее б ы ло бы , если бы H T M L код бы л и зо л и р о в а н и его с в я зь с Jav aS crip t осущ ествлялась бы и с к л ю ч и те л ьн о ср ед ств ам и по сл ед н его .

Отделение функционально­ сти от содержимого облегча­ ет последующее редактиро­ вание веб-нриложений.

Ш ТУРМ Каким образом функции могут помочь нам отделить со­ держимое от функциональности в случае Mandango?

далее >

295


данные = функции

Функции — это то)ке данные Д л я э ф ф е к т и в н о г о р а зд ел е н и я ко д а нуж но п о н я т ь , каким о б р а ­ зо м ф у н кц и и с в я зан ы с со б ы ти ям и ; п о к а ч то м ы осущ ествляли эту св язь п р и п о м о щ и Н Т М Ь -атрибутов. Н о сущ ествует и дру­ го й сп о со б , к о т о р ы й б о л е е п р е д п о ч т и т е л е н с т о ч к и зр е н и я за­ д ач и р а зд ел е н и я кодов Jav aS crip t и Н Т М Ь . Д а в ай т е п о см о тр и м н а ф у н кц и и с д ругой т о ч к и зр е н и я.

Как ни удивительно, но функция — это не более чем пере­ менная. Ее т е л о п р е д с та в л я е т с о б о й зн а ч е н и е , а и м я —и м я п е р е м е н н о й . В от как м ы п р и в ы к л и в о с п р и н и м а т ь ф ункц ии: ф ункция, созданная 'о ш ч н ы м способом .

function showSeatStatus(seatNum)

{

alertC'This seat is " + getSeatStatus (seatNxm) +

А в о т т а ж е сам ая ф у н кц и я, со зд ан н ая другим сп о со б о м .

Б качсст бс и м е н и ф ункции в ы с т у п а е м и м я п ерем енной.

var showSeatStatus = function(seatNum) { alertC'This seat is " + getSeatStatus(seatNtam) + b-

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

литералом функции. Д ру ги м и словам и, ф у н кц и ям и м о ж н о у п р ав л я ть т а к ж е, как и п е р е м е н н ы м и . К ак вы дум аете, ч т о д ел а е т следую щ ий код?

var myShowSeatStatus = showSeatStatus;

296

глава 6

8 р о ли значения п ер ем енной 'в ы с т у п а е т т е л о ф ункции. В подобных к о н ст р у к ц и я х оно назы вает ся л и т е р а л о м ф ункции.


функции

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

Вы зов т ой же самой функции через

alert(myShowSeatStatus(23));

перем енную m ySh o w S ea tS ta tu s.

Р езультат в ы зо в а п е р е м е н н о й m y S h o w S e a tS ta tu s ( ) и ф у н кц и и s h o w S e a t S t a t u s ( ) и д е н т и ч е н , так как в о б о и х случаях п р о и с ­ х о д и т ссылка н а о д и н и т о т ж е код. С о о т в е тс т в е н н о , ссы л ко й н а ф ун кц и ю я в л я е т с я ее имя.

showSeatStatus ---^

^

myShowSeatStatus

function() {

};

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

Функция это такая переменная, значение которой является ссылкой на ее тело.

var myShowSeatStatus = showSeatStatus;

Вызовем функцию yShow SeatStatusQ j чт о эквивалент но вы ­ зову show SeatStatusQ .

myShowSeatStatus(23);

С делаем п е ­ рем енную m y S h o w S e a tS ta tu s ссы лкой на ф у н к ­ цию.

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

неиие

function doThis(num) return num++;

{

} function doThat(num) return num— ;

{

} var X = doThis(11); var Y = doThat; var z = doThat(x); X = у (z); у = x; alert(doThat(z - y));

OK

У

далее >

297


решение упражнения

іажненке

Вот как работает данный код и к какому результату он приводит.

решение function doThis(num) return num++;

{

} function doThat(num) return num— ;

{

var X = doThis(11); var у = doThat; var z = doThat (x) ; X = у (z); У = x; alert(doThat(z - y));

X = 12.

'

\

у = doThat z - d o T h a t(lZ ) = 11 X = doThat(Xl-) = l O у = XO a(eirt(doThat(XX - 1C))

Часщо

_^аДаБаеМые Б о І їр о с Г ь і Неужели разделение программы на части настолько важно?

не боясь случайно внести изменения в код иауаЗспр!, которого они не понимают.

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

( ^ ; И да, и нет. Для простых приложений это не обязательно. Почувствовать

• А чем функция отличается от обычной переменной?

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

преимущества от разделения HTML, CSS и JavaScript-кодэ можно только в сложных, многострочных приложениях. Чем длиннее программа, тем сложнее ею управлять и тем проще допустить ошибку в процессе редактирования, особенно в случае использования разнородного кода. Разделение позволяет вносить функциональные изменения без риска повредить структуру или внешний вид страницы. Кроме того, данный подход позволяет веб-дизайнерам редактировать структуру и внешний вид страницы,

298

глава 6

п

Разница заключается в том, каким образом вы можете поступить с данными. Данные, связанные с функцией, можно запустить на выполнение. Вы указываете это, ставя за именем функции скобки с набором аргументов, если таковые требуются.

В чем смысл ссылки иа функцию? 0 ; в отличие от обычной переменной, которая хранит данные в виде значения

Ссылки на функции используются в целях эффективности. Ведь проще хранить ссылку, чем набор копий одного и того же кода. Поэтому, назначая функцию обработчику событий (именно этим вы займетесь через пару секунд), вы на самом деле назначаете только ссылку на код функции.


функции

Ссылки на функции — это прекрасно, но какое отношение они имеют к раз­ делению кода?

Обратный Вызов функций С сы л ки н а ф у н к ц и и т е сн о св я зан ы с о соб ы м сп о со б о м вы зо ва ф у н кц и й , к о т о р ы й п р и го д и т с я нам п р и р а зд ел е н и и р азл и ч н ы х т и п о в кода. В п р о гр ам м е M a n d an g o вам уж е п р и х о д и л о с ь в с т р е ­ ч ат ь с я с в о т та к и м и кон струкц и ям и .

setSeat(i * seats [i] .length ■¥ j, "select", "Your seat");

Н о эт о н е е д и н с т в е н н ы й сп о со б в ы зо в а ф ун кц и й . Сущ ествует ещ е и т а к н азы в а ем а я п р о ц ед у р а обратного вызова, н е требую ­ щ ая ваш его н е п о ср е д с тв е н н о го участия.

Ш ТУРМ Каким образом вы можете использовать обратный вызов функции в Mandango?

далее >

299


ф ункция против функции обратного вызова

Беседа у камина Обычная функция против функции обратного вызова.

Обычная функция: я м н о го слы ш ала о том , ч т о т ы н е п р и е м ­ л еш ь л о к а л ьн ы х вы зо во в. И н т е р е с н о , п о ­ чему?

Т ы и м ееш ь в виду б раузеры ? Т о ж е м не эк зо ­ ти ка. М не к аж ется, т ы п р о с т о зад и р аеш ь нос п ер е д тем и , к то обш;ается с кодом с ц е н а р и я о б ы ч н ы м способом .

Функция обратного вызова:

Д а потом у, ч то у м ен я другая цель. М не н р а в и тся , когд а м ен я вы зы ваю т и з эк зо т и ч е ­ ски х мест.

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

Д а ч то т ы говориш ь! Д а ко го волнует происходяш ;ее за п р ед ел ам и сц ен ар и я?

В озм ож н о, т ы и п рава. М не н р а в и тс я узна­ вать о том , ч т о с т р ан и ц а уже загрузилась, ч т о п о л ьзо в а т е л ь щ елкнул к н о п к о й м ы ш и и л и ввел текст. Т а к т ы го в о р и ш ь, ч т о м ы н е зн ал и бы об это м , если бы н е ты?

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

И м е н н о так. Б р ау зер вы зы в ае т м ен я, и во м н о ги х случаях уже я вы зы ваю теб я. Ведь о т в е т н а в н еш н и е с о б ы т и я ч асто тр еб у ет вк л ю ч ен и я н еск о л ьк и х ф ункц ий. Б ы л о п р и я т н о узнать, ч т о м ы н е т а к уж р а з­ л и ч а ем с я , как эт о сн ач ал а казалось. Д а. Т ы см о тр и ш ь в корен ь. Н е о б р ащ а й с я ко м не, я сам а т е б я вы зову. Н у поп робуй .

300

глава 6


функции

События, обратный ВызоВ и атрибуты HTML Вам уж е п р и х о д и л о с ь в с т р еч а т ь с я с ф у н кц и ям и , к о т о р ы е в ы зы ваю тся н е ваш им кодом , а браузером . С ам ы м р а с п р о с т р а н е н н ы м п р и м ер о м т а к о й ф у н к ц и и я в л яе т с я о б р а б о т ч и к со б ы ти й . И м е н н о с его помош,ью р а б о т а е т п р о гр ам м а M an d an g o . Б о л ее то го , о б р а б о т ч и к и с о б ы т и й и м ею т сам ое н е п о ср е д с тв е н н о е о т н о ш е н и е к п р о б л ем е После загрузкы р а зд ел е н и я H T M L и Jav aS crip t-кода ст раницы браузер вы зы вает ф ун кц и ю initSeatsQ тг»

on/oadJ Ш

^ ^ 1 S ii

m

m

u showSeatStatus(26);

Д а н н ы е ф у н кц и и о б р а т н о г о в ы зо в а с в я за н ы с с о б ы т и я ­ м и в H T M L -коде с т р а н и ц ы M an d an g o . H T M L -a m p u S y m onload связы вает ф у н к ц и ю , ^ . ..„ ._ initS ea tsQ с собы т ием < body o n lo a d = " 3 .n itS e a ts ( ) ;" > onload.

<img id="seat26" src="" alt="" onclick="showSeatStatus(26);" /> H TM L- а т р и б у т onclick связы вает ф у н к ц и ю sh o w S e a tS ta tu sQ с с о ­ б ы т и ем onclick.

К со ж ал ен и ю , п р е к р а с н о р а б о таю щ ее с в я зы в ан и е о б р аб о т ч и к о в с о б ы т и й с со б ы т и я м и п р и п о м о щ и H T M L -aтpи бyтoв н ев о зм о ж н о без в за и м о п р о н и к н о в е н и я JavaScгipt- и H T M L-кoдa. П о л о ж е н и е м о ж н о сп асти п р и п о м о щ и ссы л о к н а ф ун кц и и .

далее ►

301


ссылки на функции

Ссылки на функции Д л я с в я зы в а н и я ф у н кц и и о б р а т н о г о в ы зо в а с с о б ы ти е м м ож н о н е и с п о л ь зо в ат ь H T M L -атрибуты , а н а зн а ч и т ь ссы лку н а ф унк­ ц и ю н е п о ср е д с тв е н н о KOÄyJavaScript. В р езул ьтате вам во о б щ е

После и

йп

не п р и д е т с я и м е т ь дел а с Н Т М Ь-кодом - п р о с т о в о сп ол ьзуй тесь ско б о к! fe d b м ы ^нТс^б ссы л ко й н а ф ункц ию . запускат ь, мы Ы г о т ш ь . , , . . — ссы лаем ся на нее

window.onload = initSeats;

Ссылка на ф ункцию initSeatsQ назначена свойст ву события onload.

C fb s m m onload являет ся свойст вом объект а window.

Ч т о б ы с в я зать о б р а б о т ч и к со б ы т и й и с к л ю ч и тел ьн о с Jav aS crip tкодом , нуж но н а зн а ч и т ь ссы лку н а ф ункц ию свойству со б ы т и я о б ъ екта. В случае с н аш им со б ы ти е м o n l o a d эт о п р и в о д и т к вы ­ зову ф у н кц и и i n i t S e a t s () п о сл е загрузки ст р ан и ц ы . В от как эт о м о ж н о п р е д с та в и ть сх ем ати чн о :

onload!

window.onload();

Событие onload запускает обработчик посредст вом свойства window.onload...

initSeats О ;

...и т ак как эт о м у свойст ву назначе­ на ссылка на ф ункцию initSeats(), эт а функция вызывается для обработки события.

И м е н н о эта т е х н и к а п о зв о л я е т ч е т к о р а зд ел и ть JavaScriptи Н Т М Ь-код — ведь вам уже н е тр еб у ется н а зн а ч а т ь JavaS criptкод Н Т М Ь-атрибутам .

<body>

Т е п е р ь < b o d y > н е с о д е р ж и т н и ч е го ли ш н его . О стал о сь т о л ь ­ ко за с т ав и ть код о б р аб о т к и с о б ы т и я зап у скаться как м ож н о ран ьш е, и м е н н о п оэтом у о н о б ы ч н о п о м ещ ается в за го л о во к стр ан и ц ы . Н о как ж е б ы ть в ситуации , когд а о б р аб о тч и к у с о б ы т и я нуж но п е р е д а ть аргум ент? Д л я с о б ы т и я o n l o a d в M a n d a n g o т а к о й п р о ­ блем ы н е сущ ествует, а в о т со б ы ти ю o n c l i c k нуж но п ер ед ать н о м е р кр есл а, к о т о р о е в ы б р ал п о л ьзо в ател ь. С сы л ки н а ф унк­ ц и и н е п о зв о л я ю т р е ш и т ь данную задачу...

302

глава 6

Ссылки на функции позволяют легко связать обработчик события с самим событием.


функции

Литерал функции »WMwM'ISteltlxölr

С о б ы ти е o n l i c k , с в я за н н о е с и зо б р а ж е н и я м и кр есел , д олж н о в ы зы в ать ф ункц ию s h o w S e a t S t a t u s () с н о м ер о м кр е сл а в кач еств е аргум ента. П р о с т о н а зн а ч и в ему ссы лку н а ф ункц ию , м ы н е см ож ем п е р е д а ть аргум ент. П оэтом у ссы л аться в д ан н о м случае следует н а л и т е р а л ф у н кц и и , из к о т о р о г о и будет осущ ествлен вы зов.

Я Й Й Г1Й Так M&I получаем д о ст уп к с в о й с т в у onclick о б ъ ект а с изображе нмем сид&нья. ^

л

d o c u m e n t . g e t E l e m e n t B y l d ("seat26").onclick = function(evt)

{

showSeatStatus(26) }; Л и т е р а л ф ункц и и служ и т как бы « к о н т е й н е р о м » для вызова ф у н к цыы s k o w S e a tS ta tu s (), позволяя п ер е д а ва т ь в нее а р гум ен т :

Л и т е р а л ф ун кц и и н а значен с во й ст ву собы т ия onclick как ссы лка на ф ункцию .

Л и т е р а л используется в кач естве «оболочки» для вы зо ва ф ункции s h o w S e a t S t a t u s {), и и м ен н о о н п о зв о л я ет п ер ед ать н ом ер кресла. Его м ож н о п р ед стави ть в виде б езы м я н н о й ф ункции, о б раб аты ваю щ ей собы тия. И м ен н о по э т о й п р и ч и н е л и тер ал ы ин огд а назы ваю т анонимными функциями. К од п о к а зы в а ет, каким о б р азо м в Jav aS crip t п р ед ставл ен о б ъ ект, п ер е д а в ае м ы й о б р аб о тч и ку , в д ан н о м случае п о ср ед ство м аргу­ м ен та e v t . Э то т о б ъ е к т с о д е р ж и т и н ф о р м а ц и ю о собы ти и .

ажнше

О б ъ е к т e v e n t а вт о м а т и ч еск и п ер ед а ет ся об работ чику со бы т ия ка к первы й а р гу м е н т ,

Литералы функции позволяют создавать анонимные обработчики событий.

Свяжите функцию i n i t S e a t s () с событием o n l o a d , используя вместо ссылки литерал.

далее >

303


реш ение упражнения

Вот каким образом функция initSeats {) связывается с событием onload при помощи литерала.

;НСНИ2 гш гнпг

Function(evt)_ {

initSeatsQ;

Ь.................................. Ф у н к ц и я in itS e a ts Q в ы зы ва е м ся у т р и о д р а д о т ч и ка собы т ия ^ ^

А р г у м е н т e vt игнорирует ся, т а к к а к о б р а б о т ч и ку собы т ия o n lo a d не т р е б у е т с я о б ъ е кт

event.

А где )ке связывание? По-прежнему остался нерешенным вопрос о связи событий с литералами функций. М ы увидели, что назначение обработ­ чика события onload может осуш;ествляться в заголовке стра­ ницы внутри тега <script>. В результате связанный с этим со­ бытием код не запускается до загрузки страницы. Точно такой же результат м ы получали, назначая функцию initSeats () H T M L -атрибуту onload в теге <body>. Н о в каком месте связы­ ваются со своими обработчиками остальные события? Это может происходить в функции обратного вызова обработ­ чика события onload.

window.onload //

Свяжем

=

f u n c t i o n ()

остальные

события

-------------- //

Задаем

вид

i n i t S e a t s ();

{ з

Все ост а льн ы е собы т ия с т р а н и ц ы м о г у т бы т ь связаны в н у т р и о б р а б о т ­ ч и ка собы т ия o n lo ad .

кресел

-----------

};

Таким образом, именно обработчик события onload становится функцией, инициализирующей все прочие события. Это удобно, так как в результате запуск соответствующих фрагментов кода осуществляется после загрузки страницы.

304

глава б

Обработчик события onload прекрасно подходит для инициализации всех остальных событий.

К о д , связанны й с с о ~~ б ы т и е м o n lo a d , до си х пор за п у с к а е т с я в н у т р и о б р а б о т ч и ка эт о го собы т ия.


функции

_

часзво

чаДаБаеМые Б о Т 1 |> о С Ь 1

Почему функциям обратного вызова придается такое значение?

3 * Отличаются ли функции обратного вызова от обработчиков событий?

0 ; Функции обратного вызова позволяют

; Да. В главе 12 вы познакомитесь с другим способом применения функций обратного вызова, в процессе которого они обрабатывают данные, посланные

реагировать на события, происходящие за пределами сценария. Для их запуска требуется, чтобы произошли определенные события. Узнать о том, что нужное событие произошло, функции обратного вызова позволяет браузер. Для этого нужно связать функцию с пусковым механизмом, роль которого обычно играют различные события.

сервером в ответ на запрос Ajax.

обратного вызова вызывается только один раз. То есть когда функция вызывается один раз и не вашим кодом. Литералы назначаются непосредственно свойствам события, в то время как на именованные функции в таких ситуациях делается ссылка. Фактически это просто более эффективный способ работы в случаях, когда вам не требуются именованные функции. Кроме того, именно литералы приходят на помощь, если нужно не только сослаться на функцию, но и передать ей аргумент.

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

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

onload программы Mandango.

window.onload = function О

{

// с в я з ы в а е м со щ е л ч к о м на к н о п к е F i n d Seat

document.getElementByld ( " f i n d s e a t s " ) .........

// с в я з ы в а е м со щ е л ч к а м и на и з о б р а ж е н и я х к р е с е л vn.ti = fun c t i o n (evt) d o c u m e n t . g e t E l e m e n t B y l d ( seatO ) . ........

{

„ = 'M = f u n c t i o n (evt) d o c u m e n t . g e t E l e m e n t B y l d ( s eatl ). ........

(

4.0 .M = f u n c t i o n (evt) d o c u m e n t . g e t E l e m e n t B y l d ( seat2 ) . ........

{

// З а д а е м в и д к р е с е л

далее >

305


реш ение упражнения

Возьми В руку карандаш Решение

Вот как выглядит код нового обработчика события onload в программе Mandango.

О б р а б о т ч и к со б ы ­ т и я o n lo a d я в л я ­ е т ся а н о н и м н о й ф ункц ией .

w i n d o w . o n l o a d = f u n c t i o n () 11

Ф у н к ц и я fin d S e a ts O связана с со б ы т и е м o n c lic k п р и п о м о щ и ссы лки. {

С в я з ы в а е м со щ е л ч к о м н а к н о п к е F i n d Seat

d o c u m e n t .g e t E l e m e n t B y l d ("f i n d s e a t s ") . ,

// С в я з ы в а е м CO щ е л ч к а м и на и з о б р а ж е н и я х к р е с е л d o c u m e n t. g e tE le m e n tB y ld ( " s e a tO " ) . , 0 п с 1 / с к =

f u n c tio n (e v t)

f

d o c u m e n t . g e t E l e m e n t B y I d ( " s e a t l " ) . .OnC/!Ck= fun c t i o n (evt)

(

>

d o c u m e n t. g e tE le m e n tB y I d ( " s e a t 2 " ) . ..0 n c /ic k =

{StpwSeatStatu^^^^

]

II

f u n c tio n (e v t)

Задае м вид кресел

initSeatsQ;

функция init5eats0 вы зы вает ся для з а ­ верш ения задач, с в я ­ занны х с за гр узко й .

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

п о э т о м и ей

КЛЮ ЧЕВЫЕ Щ МОМЕНТЫ Функции обратного вызова вызываются браузером в ответ на события вне пределов сценария. Ссылки позволяют назначать функции, как если бы они были переменными.

306

глава 6

Ссылки позволяют связать функции обработчиков событий с кодом иауаЗсг1р1, не затрагивая НТМ1. Литералами называются безымянные функции.


функции Ч асто З ад авае м ы е

В опросы ' Почему обработчик события o n l o a d в Mandango создан как литерал функции? ; Потому что у нас нет причин использовать в этом месте именованную функцию. Наша функция вызывается только один раз в ответ на событие o n l o a d . Можно было создать именованную функцию и назначить ссылку на нее w i n d o w . o n l o a d , но связь между функцией и событием становится более прозрачной, если их связать друг с другом при помощи литерала.

Q ; Да. Вы можете решить, что лучше связать их непо­ средственно в теге < s c r i p t > . Но вспомните о том, что на этом этапе содержимое страницы еще не загружено. Со­ ответственно, функции g e t E l e m e n t B y l d () не будут вызываться. Полную загрузку страницы гарантирует только событие o n l o a d , с которым следует связать нужные вам обработчики.

Оболочка HTML-страницы Разделение JavaScript и H T M L -кодов в програм­ ме Mandango приводит к тому, что структурная часть страницы становится совсем небольшой. В результате вы можете легко редактировать HTML, не боясь случайно внести изменения в код JavaScript.

Я хочу это видеть!

Нужно ли связывать с обработчиком события o n l o a d все остальные функции обратного вызова?

Посмотри на код! Он такой... редактируемый!

<body> <div style«"margin-top :75px; text-ali gn;center"> <amg id-"seatO" src<img id="seatl" src-’ <img id="seat2" src=' <img id»"seat3" src-' <irag ld«"seat4" src-' <img id-"seat5" src=" <lmg ld="seat6" src=" <img id-"seat7" src-" <img id="seat8" src-" <img id-"seat9" src-" <img id-"seatlO" src<img id-"seatll" src-= alt= .... /> <img id-"seatl2" src/> alt=' <img id-"seatl3" srcalt=’ /> <lmg id-"seatl4" src- "" alt=’ ^ <img ld-"seatl5" src-' alt=’■" /> <img id="seatl6" src-' alt='’ /> <img id="seatl7" src-'"" alt»" " /> <img ld-"seatl8" src»""" alt=" " /> <img id-"seatl9" src-""" alt=" " / X b r /> <img id-"seat20" src-" alt=" " /> <lmg id="seat21" src-" alt=" " /> <img id-"seat22" src-" alt="' " /> <img id-"seat23" src-" " alt="' " /> <img id-"seat24" src=" " alt="’ ’ /> <img id-"seat25" src-"'" alt="' * /> <img id="seat26 " src-"'" alt="" ' /> <img ld-"seat27" src-"'" alt="" ' /> <img id-"seat28" src-""" alt="" /> <img id-"seat29" src-""" alt="" / X b r /> <lmg ld-"seat30" src-""' alt='"' /> <img id="seat31" src-""’ alt="" /> <img id="seat32" src-""' alt="" /> <img id-"seat33" src-""' alt="" /> <img ld-"seat34" src-"" alt="" /> <lmg id-"seat35" src-"" alt="" /> <img id-"seat36" src-"" alt="" /> <img id-"seat37" src-"" alt="" /> <img id-"seat38" src-"" alt="" /> <img ld="seat39" src-"" alt="" / X b r /> <rnput type-"buttcn" id= findseats" value-"Find Seats" </aiv>

</body>

далее >

307


работ аю щ ий JavaScript

и еще немноМо про JavaScr^pt... Добиться мира во всем мире м ы не смогли, зато научились управлять температурой в комнате при помощи JavaScript. М ы узнали, как улучшить наши сценарии, деля крупные задачи на более мелкие, фокусируясь на единственной цели и создавая код, пригодный для многократного использования.

HEAT FIRST С т ройка

1 Кров

Сет и Джейсон также воспользовались данной технологией и создали более эффективную и простую в редактировании вер­ сию Mandango. П о крайней мере, в души наших мачо пришло спокойствие... «34

i f 3 V-" -ч _

r

-

;

o

a

X

a

r

*

through 3 in Row 4 are available. Ассврл?

(

D

D

O

0

i

Г П ервы й р яд !

308

глава 6

f

Canctl

Изучаем JavaScript Part 001  
Изучаем JavaScript Part 001  
Advertisement