1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
|
---
language: javascript
contributors:
- ["Adam Brenecki", "http://adam.brenecki.id.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
filename: javascript-ru.js
translators:
- ["Alexey Gonchar", "http://github.com/finico"]
lang: ru-ru
---
JavaScript был создан в 1995 году Бренданом Айком, работающим в компании Netscape.
Изначально он был задуман как простой язык сценариев для веб-сайтов, дополняющий
Java для более сложных веб-приложений, но его тесная интеграция с веб-страницами
и втроенная поддержка браузерами привели к тому, что он стал более распространённым,
чем Java в веб-интерфейсах.
JavaScript не ограничивается только веб-браузером, например, Node.js, программная
платформа, позволяющая выполнять JavaScript, основанная на движке V8 от браузера
Google Chrome, становится все более популярной.
```js
// Си-подобные комментарии. Однострочные комментарии начинаются с двух символов слэш,
/* а многострочные комментарии начинаются с звёздочка-слэш
и заканчиваются символами слэш-звёздочка */
// Выражения заканчиваються точкой с запятой ;
doStuff();
// ... но они необязательны, так как точки с запятой автоматически вставляются
// везде, где есть символ новой строки, за некоторыми исключениями.
doStuff()
// Так как эти исключения могут привести к неожиданным результатам, мы будем всегда
// использовать точку с запятой в этом руководстве.
///////////////////////////////////
// 1. Числа, Строки и Операторы
// В JavaScript только один тип числа (64-bit IEEE 754 double).
// Он имеет 52-битную мантиссу, которой достаточно для хранения целых чисел
// с точностью вплоть до 9✕10¹⁵.
3; // = 3
1.5; // = 1.5
// Некоторые простые арифметические операции работают так, как вы ожидаете.
1 + 1; // = 2
0.1 + 0.2; // = 0.30000000000000004 (а некоторые - нет)
8 - 1; // = 7
10 * 2; // = 20
35 / 5; // = 7
// Включая деление с остатком.
5 / 2; // = 2.5
// Побитовые операции также имеются; они производят операции, используя
// двоичное представление числа, и возвращают новую последовательность из
// 32 бит (число) в качестве результата.
1 << 2; // = 4
// Приоритет в выражениях явно задаётся скобками.
(1 + 3) * 2; // = 8
// Есть три специальных значения, которые не являются реальными числами:
Infinity; // "бесконечность", например, результат деления на 0
-Infinity; // "минус бесконечность", результат деления отрицательного числа на 0
NaN; // "не число", например, результат деления 0/0
// Существует также логический тип.
true;
false;
// Строки создаются при помощи двойных или одинарных кавычек.
'abc';
"Hello, world";
// Для логического отрицания используется символ восклицательного знака.
!true; // = false
!false; // = true
// Строгое равенство ===
1 === 1; // = true
2 === 1; // = false
// Строгое неравенство !==
1 !== 1; // = false
2 !== 1; // = true
// Другие операторы сравнения
1 < 10; // = true
1 > 10; // = false
2 <= 2; // = true
2 >= 2; // = true
// Строки конкатенируются при помощи оператора +
"Hello " + "world!"; // = "Hello world!"
// и сравниваются при помощи < и >
"a" < "b"; // = true
// Проверка равенства с приведением типов осуществляется двойным символом равно
"5" == 5; // = true
null == undefined; // = true
// ...а если использовать ===
"5" === 5; // = false
null === undefined; // = false
// ...приведение типов может привести к странному поведению...
13 + !0; // 14
"13" + !0; // '13true'
// Вы можете получить доступ к любому символу строки, используя метод charAt
"This is a string".charAt(0); // = 'T'
// ...или используйте метод substring чтобы получить более крупные части
"Hello world".substring(0, 5); // = "Hello"
// length это свойство, для его получения не нужно использовать ()
"Hello".length; // = 5
// Так же есть null и undefined
null; // используется для обозначения намеренного значения "ничего"
undefined; // используется для обозначения переменных, не имеющих
// присвоенного значения (хотя переменная объявлена)
// false, null, undefined, NaN, 0 и "" это ложь; все остальное - истина.
// Следует отметить, что 0 это ложь, а "0" - истина, несмотря на то, что 0 == "0".
///////////////////////////////////
// 2. Переменные, Массивы и Объекты
// Переменные объявляются при помощи ключевого слова var. JavaScript - язык с
// динамической типизацией, поэтому не нужно явно указывать тип. Для присваивания
// значения переменной используется символ =
var someVar = 5;
// если вы пропустите слово var, вы не получите сообщение об ошибке...
someOtherVar = 10;
// ...но ваша переменная будет создана в глобальном контексте, а не в текущем
// гед вы ее объявили.
// Переменным объявленным без присвоения устанавливается значение undefined.
var someThirdVar; // = undefined
// У математических операций есть сокращённые формы:
someVar += 5; // как someVar = someVar + 5; someVar теперь имеет значение 10
someVar *= 10; // теперь someVar имеет значение 100
// а так же специальные операторы инкремент и декремент для увеличения и
// уменьшения переменной на единицу соответственно
someVar++; // теперь someVar имеет значение 101
someVar--; // обратно 100
// Массивы это нумерованные списки из значений любого типа.
var myArray = ["Hello", 45, true];
// Их элементы могут быть доступны при помощи синтаксиса с квадратными скобками.
// Индексы массивов начинаются с нуля.
myArray[1]; // = 45
// Массивы можно изменять, как и их длину.
myArray.push("World");
myArray.length; // = 4
// Добавлять и редактировать определенный элемент
myArray[3] = "Hello";
// Объекты в JavaScript похожи на "словари" или ассоциативные массиы в других
// языках: неупорядоченный набор пар ключ-значение.
var myObj = {key1: "Hello", key2: "World"};
// Ключи это строки, но кавычки необязательны, если строка удовлетворяет
// ограничениям для имён переменных. Значения могут быть любых типов.
var myObj = {myKey: "myValue", "my other key": 4};
// Атрибуты объектов можно также получить, используя квадратные скобки,
myObj["my other key"]; // = 4
// или через точку, при условии, что ключ является допустимым идентификатором.
myObj.myKey; // = "myValue"
// Объекты изменяемы; можно изменять значения и добавлять новые ключи.
myObj.myThirdKey = true;
// Если вы попытаетесь получить доступ к несуществующему свойству,
// вы получите undefined.
myObj.myFourthKey; // = undefined
///////////////////////////////////
// 3. Логика и управляющие конструкции.
// Синтаксис для этого раздела почти такой же как в Java.
// Эта конструкция работает, как и следовало ожидать.
var count = 1;
if (count == 3) {
// выполняется, если count равен 3
} else if (count == 4) {
// выполняется, если count равен 4
} else {
// выполняется, если не 3 и не 4
}
// Как это делает while.
while (true){
// Бесконечный цикл!
}
// Циклы do-while такие же как while, но они всегда выполняются хотя бы раз.
var input
do {
input = getInput();
} while (!isValid(input))
// цикл for является таким же, как C и Java:
// инициализация; условие; шаг.
for (var i = 0; i < 5; i++) {
// будет запущен 5 раз
}
// && это логическое И, || это логическое ИЛИ
if (house.size == "big" && house.colour == "blue") {
house.contains = "bear";
}
if (colour == "red" || colour == "blue") {
// цвет красный или синий
}
// || используется как "короткий цикл вычисления" для присваивания переменных.
var name = otherName || "default";
// Оператор switch выполняет проверку на равенство пр помощи ===
// используйте break чтобы прервать выполнение после каждого case
// или выполнение пойдёт далее, игнорируя при этом остальные проверки.
grade = 'B';
switch (grade) {
case 'A':
console.log("Great job");
break;
case 'B':
console.log("OK job");
break;
case 'C':
console.log("You can do better");
break;
default:
console.log("Oy vey");
break;
}
///////////////////////////////////
// 4. Функции, Область видимости и Замыкания
// Функции в JavaScript объявляются при помощи ключевого слова function.
function myFunction(thing) {
return thing.toUpperCase();
}
myFunction("foo"); // = "FOO"
// Обратите внимание, что значение, которое будет возвращено, должно начинаться
// на той же строке, что и ключевое слово return, в противном случае вы будете
// всегда возвращать undefined по причине автоматической вставки точки с запятой.
// Следите за этим при использовании стиля форматирования Allman.
function myFunction()
{
return // <- здесь точка с запятой вставится автоматически
{
thisIsAn: 'object literal'
}
}
myFunction(); // = undefined
// JavaScript функции - это объекты, поэтому они могут быть переприсвоены на
// различные имена переменных и передаваться другим функциям в качестве аргументов,
// например, когда назначается обработчик события:
function myFunction() {
// этот код будет вызван через 5 секунд
}
setTimeout(myFunction, 5000);
// Примечание: setTimeout не является частью языка, но реализован в браузерах и Node.js
// Функции не обязательно должны иметь имя при объявлении - вы можете написать
// анонимное определение функции непосредственно в агрументе другой функции.
setTimeout(function() {
// этот код будет вызван через 5 секунд
}, 5000);
// В JavaScript есть область видимости функции; функции имеют свою область
// видимости, а другие блоки - нет.
if (true) {
var i = 5;
}
i; // = 5 - не undefined как ожидалось бы в языках с блочной областью видимости
// Это привело к общепринятому шаблону "самозапускающихся анонимных функций",
// которые препятствуют проникновению переменных в глобальную область видимости
(function() {
var temporary = 5;
// Мы можем получить доступ к глобальной области для записи в "глобальный объект",
// который в веб-браузере всегда window. Глобальный объект может иметь другое
// имя в таких платформах, как Node.js
window.permanent = 10;
})();
temporary; // вызовет сообщение об ошибке с типом ReferenceError
permanent; // = 10
// Одной из самых мощных возможностей JavaScript являются замыкания. Если функция
// определена внутри другой функции, то внутренняя функция имеет доступ к
// переменным внешней функции, даже после того, как контекст выполнения выйдет из
// внешней функции.
function sayHelloInFiveSeconds(name) {
var prompt = "Hello, " + name + "!";
// Внутренние функции по умолчанию помещаются в локальную область видимости,
// как если бы они были объявлены с var.
function inner() {
alert(prompt);
}
setTimeout(inner, 5000);
// setTimeout асинхронна, поэтому функция sayHelloInFiveSeconds сразу выйдет
// и тело setTimeout будет вызвано позже. Однако, поскольку внутренняя
// функция "замкнута", она по-прежнему имеет доступ к переменной prompt,
// когда sayHelloInFiveSeconds вызывется.
}
sayHelloInFiveSeconds("Adam"); // откроется окно с "Hello, Adam!" через 5 секунд
///////////////////////////////////
// 5. Подробнее про Объекты, Конструкторы и Прототипы
// Объекты могут содержать в себе функции.
var myObj = {
myFunc: function() {
return "Hello world!";
}
};
myObj.myFunc(); // = "Hello world!"
// Когда функции, прикрепленные к объекту, вызываются, они могут получить доступ
// к этому объекту с помощью ключевого слова this.
myObj = {
myString: "Hello world!",
myFunc: function() {
return this.myString;
}
};
myObj.myFunc(); // = "Hello world!"
// Какое это значение имеет к тому, как вызвана функция и где она определена.
// Итак, наша функция не работает, если она вызывается не в контексте объекта.
var myFunc = myObj.myFunc;
myFunc(); // = undefined
// И наоборот, функция может быть присвоена объекту и получать доступ к нему
// через this, даже если она не была присвоена при объявлении.
var myOtherFunc = function() {
}
myObj.myOtherFunc = myOtherFunc;
myObj.myOtherFunc(); // = "HELLO WORLD!"
// Мы можем также указать контекст для выполнения функции, когда мы вызываем ее
// с помощью call или apply.
var anotherFunc = function(s) {
return this.myString + s;
}
anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
// Функция apply аналогична, но принимает массив аргументов.
anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
// Это полезно при работе с функцией, которая принимает последовательность
// аргументов, и вы хотите передать массив.
Math.min(42, 6, 27); // = 6
Math.min([42, 6, 27]); // = NaN (не сработает!)
Math.min.apply(Math, [42, 6, 27]); // = 6
// Но, call и apply - временные. Когда мы хотим связать функцию, мы можем
// использовать bind.
var boundFunc = anotherFunc.bind(myObj);
boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
// Bind также может использоваться, для частичного применения (каррирование) функции
var product = function(a, b) { return a * b; }
var doubler = product.bind(this, 2);
doubler(8); // = 16
// Когда вы вызываете функцию с помощью ключевого слова new создается новый объект,
// и создает доступ к функции при помощи this. Такие функции называют конструкторами.
var MyConstructor = function() {
this.myNumber = 5;
}
myNewObj = new MyConstructor(); // = {myNumber: 5}
myNewObj.myNumber; // = 5
// Каждый объект в JavaScript имеет свойтво prototype. Когда вы хотите получить
// доступ к свойтву объекта, которое не существует в этом объекте, интерпретатор
// будет искать это свойство в прототипе.
// Некоторые реализации языка позволяют получить доступ к объекту прототипа
// через свойство __proto__. Несмотря на то, что это может быть полезно для
// понимания прототипов, это не часть стандарта; мы увидим стандартные способы
// использования прототипов позже.
var myObj = {
myString: "Hello world!"
};
var myPrototype = {
meaningOfLife: 42,
myFunc: function() {
return this.myString.toLowerCase()
}
};
myObj.__proto__ = myPrototype;
myObj.meaningOfLife; // = 42
// Для функций это так же работает.
myObj.myFunc(); // = "hello world!"
// Если интерпретатор не найдет свойство в прототипе, то продожит поиск в
// прототипе прототипа и так далее.
myPrototype.__proto__ = {
myBoolean: true
};
myObj.myBoolean; // = true
// Здесь не участвует копирование; каждый объект хранит ссылку на свой прототип.
// Это означает, что мы можем изменить прототип и наши изменения будут отражены везде
myPrototype.meaningOfLife = 43;
myObj.meaningOfLife; // = 43
// Мы упомянули, что свойтсво __proto__ нестандартно, и нет никакого стандартного
// способа, чтобы изменить прототип существующего объекта. Однако, есть два
// способа создать новый объект с заданным прототипом.
// Первый способ это Object.create, который появился в ECMAScript 5 и есть еще
// не во всех реализациях языка.
var myObj = Object.create(myPrototype);
myObj.meaningOfLife; // = 43
// Второй способ, который работает везде, имеет дело с конструкторами.
// У конструкторов есть свойство с именем prototype. Это не прототип
// функции-конструктора; напротив, это прототип для новых объектов, которые
// будут созданы с помощью этого конструктора и ключевого слова new
MyConstructor.prototype = {
myNumber: 5,
getMyNumber: function() {
return this.myNumber;
}
};
var myNewObj2 = new MyConstructor();
myNewObj2.getMyNumber(); // = 5
myNewObj2.myNumber = 6
myNewObj2.getMyNumber(); // = 6
// У встроенных типов, таких как строки и числа также есть конструкторы, которые
// создают эквивалентые объекты-обертки.
var myNumber = 12;
var myNumberObj = new Number(12);
myNumber == myNumberObj; // = true
// За исключением того, что они не в точности равны.
typeof myNumber; // = 'number'
typeof myNumberObj; // = 'object'
myNumber === myNumberObj; // = false
if (0) {
// Этот код не выполнятся, потому что 0 - это ложь.
}
if (Number(0)) {
// Этот код выполнится, потому что Number(0) это истина.
}
// Впрочем, обертки это объекты и их можно расширять, например:
String.prototype.firstCharacter = function() {
return this.charAt(0);
}
"abc".firstCharacter(); // = "a"
// Это часто используется в полифиллах, которые реализуют новые возможности
// JavaScript в старой реализации языка, так что они могут быть использованы в
// старых средах, таких как устаревшие браузеры.
// Например, мы упомянули, что Object.create доступен не во всех реализациях, но
// мы сможем использовать его с этим полифиллом:
if (Object.create === undefined) { // не перезаписывать метод, если он существует
Object.create = function(proto) {
// создать временный конструктор с правильным прототипом
var Constructor = function(){};
Constructor.prototype = proto;
// затем использовать его для создания нового объекта, на основе прототипа
return new Constructor();
}
}
```
## Что еще почитать
[Современный учебник JavaScript (Илья Кантор)](http://learn.javascript.ru) -
качественный учебник по JavaScript на русском языке.
[Mozilla Developer Network](https://developer.mozilla.org/ru/docs/Web/JavaScript) -
предоставляет отличную документацию для JavaScript, как он используется в браузерах.
Кроме того, это вики, поэтому, если вы знаете больше, вы можете помочь другим,
делясь своими знаниями.
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/ru/) - это
подробное руководство всех неинтуитивных особенностей языка.
[Stack Overflow](http://stackoverflow.com/questions/tagged/javascript) - можно
найти ответ почти на любой ваш вопрос, а если его нет, то задать вопрос самому.
|