# Javascript для PHP'истов
Этот материал рассчитан на людей, которые уже знакомы с программированием на **PHP** и желают быстро разобраться с особенностями **Javascript**, без
которого сейчас не обойдется ни один веб-программист.
## Отладка.
В отличие от обычной для **PHP** ситуации: отсутствия отладчика, для **JS** в браузере есть отличная среда отладки. Доступен отладчик по
**F12**, **Ctrl-Shift-I** или с помощью контекстного меню.
**Developer Tools** содержит в себе множество средств отладки кода. Для хорошего понимания управляющих конструкций (**условий** и **циклов**) полезно
разобраться с **пошаговой отладкой** - выполнением кода по шагам. Это позволяет увидеть, какие блоки кода выполняются или не выполняются в условных
операторах и каковы значения переменных в каждый момент времени выполнения кода.
Для начала пошаговой отладки устанавливается **точка останова** - строка кода, с которой обычный режим выполнения прерывается и начинается отладка по шагам.
В **Developer Tools** найдите вкладку *Source*, в ней свой файл c кодом, и кликните на номере нужной строки слева от текста кода.
Если вы используете [repl.it](http://repl.it), другие **онлайн-IDE** или **console**, то у вас будут определенные сложности с нахождением
вашего кода и строки в нём. Поэтому вы можете вставить ключевое слово `debugger` в ваш код - это работает так же, как **точка останова** на
строке в Developer Tools.
### Отладка по шагам.
**Пошаговая отладка** позволяет детально заглянуть в процесс выполнения вашего кода - вы можете узнать всё ли работает так, как нужно, в любой строке и таким
образом упростить поиск логических ошибок в коде. Основные операции:
- **Step over next function call** (**F10**) - следующий шаг/оператор в вашем коде. После выполнения каждой команды вы можете ознакомится со значениями
переменных, наведя на них курсор мыши, написав их в консоли, или же используя вкладку Watch
- **Resume script execution** (**F8**) - переход из режима отладки по шагам в обычный режим выполнения кода. Таким способом вы пропускаете хорошо отлаженные
части кода. Этот режим может быть прерван следующей **точкой останова** или ключевым словом `debugger` в коде.
- **Step into next function call** (**F11**) - сделать следующий шаг *в функцию*, "зайти" в неё.
- **Step out of current function** (**Shift-F11**) - следующий шаг *из* функции, выйти из функции на уровень, который функцию вызвал.
### Значение переменных и выражений
- Вы можете узнать значение переменных, наведя на них курсор мыши
- Вы можете узнать значение синтаксически верного выражения выделив его и наведя на него курсор мыши. Учтите, что при этом может быть вызвана
та или иная функция и могут возникнуть побочные эффекты.
### Пошаговая отладка и консоль.
Очень удобно использовать консоль и пошаговую отладку одновременно. Консоль предоставляет все переменные и их текущие значения, которые сейчас есть в
отлаживаемом коде, таким образом вы можете поэкспериментировать с этими значениями и, например, запустить из консоли следующий проблемный оператор в коде
или его часть для нахождения логической ошибки.
### Отладочный вывод
Вы всегда можете добавить `console.log` в место, где хотите получить информацию о состоянии программы. Этот способ хорош как дополнение к остальным.
Так же вы можете написать определенное условие для отладки, вставить в него `console.log` и поставить **точку останова**.
### Примеры ниже
...могут быть запущены в отладочном режиме по красной кнопке :-), если вы откроете **Developer Tools**. Без **Developer Tools** они тоже работают.
## Подключение
"Корнем" **HTML**-документа является файл **html**, в котором указываются остальные части страницы - картинки, css, js файлы и код.
### Подключение отдельных файлов и библиотек
```html
```
### Подключение кода inline.
```html
```
## `use strict`
Javascript-интерпретатор в браузере может работать в двух режимах: "обычном" и в "строгом":
- **Обычный** режим предназначен для совместимости.
- **Строгий** режим включает *современный* стандарт **Javascript** (ECMAScript 5 или новее)
В зависимости от режима поведение интерпретатора может
меняться. Далее это будет упоминаться в тех или иных моментах. По умолчанию интерпретатор работает в обычном режиме, для включение строгого режима
используется *строка* `'use strict'` в начале **Javascript**-кода.
```javascript
"use strict";
```
или
```javascript
'use strict';
```
## Переменные и типы данных
В отличие от **PHP**, **Perl** и **Shell**-интерпретаторов, с которых это и пошло, в **Javascript** переменные объявляются *без* знака `$`:
```javascript
a = 5;
```
```php
$a = 5;
```
Такой код в обычном режиме **Javascript** декларирует *глобальную* переменную, которая становится полем объекта `window`, даже если переменная
определена внутри функции:
```javascript
a = 5;
function b(){
a = 10;
}
b()
alert(a);
```
Код выше аналогичен:
```php
$a = 5;
function b(){
global $a;
$a = 10;
}
b();
echo($a);
```
Для декларации локальных переменных используется ключевое слово `var`.
```javascript
a = 5;
function b(){
var a = 10;
}
b();
alert(a);
```
Код выше аналогичен:
```php
$a = 5;
function b(){
$a = 10;
}
b();
echo($a);
```
> В **строгом** режиме определение переменных без `var` недопустимо и вызывает ошибку:
```javascript
'use strict';
var a = 5; //без var тут бы была ошибка
function b(){
var a = 10;
}
b();
alert(a);
```
**Во избежание ошибок ВСЕГДА определяйте переменные через `var`**.
### Типы данных
Основные типы данных в **JS** совпадают с типами данных **PHP**, за некоторыми исключениями:
- Целые и дробные числа представлены едиными типом `Number`
- Под "массивом" в **JS** подразумевается массив с целочисленными ключами.
- Ассоциативные массивы и объекты - это одно и то же;
- Для переменных без значения и значений отсутствующих ключей в ассоциативных массивах вместо PHP `NULL` используется аналогичный тип `undefined`
- Так же существует тип `null`, который применяется программистами для задания "пустых" значений и/или в **DOM**.
## `;`
В отличие от **PHP** и многих других языков с **C**-подобным синтаксисом, в **JS** точка с запятой *не является обязательной*, однако нужна
в некоторых случаях, например при написании операторов в одну строку:
```javascript
var a = 5
var b = 6
var c = "string"
var d
a ++; b += a; d = c + a;
```
**Во избежание ошибок просто добавляйте `;` "как обычно", в конце строки**
## Комментарии
Как в PHP.
## Строки, переменные в них и конкатенация
В отличие от **PHP**, в **JS** нет разницы между одинарными и двойными кавычками:
```javascript
var a = "\n";
var b = '\n';
alert(a == b);
```
```php
$a = "\n";
$b = '\n';
echo (a == b);
```
В отличие от **PHP**, в **JS** нет подстановки переменных в строках в двойных кавычках:
```javascript
var a = "\n";
alert("Тут нет a переноса a строк");
```
```php
$a = "\n";
echo ("Тут есть $a перенос $a строки");
```
Таким образом, для добавления значения переменной в строку надо использовать **конкатенацию**
В отличие от **PHP**, в **JS** конкатенация делается с помощью оператора `+`, а не `.`:
```javascript
var a = '\n';
alert("Тут есть" + a + "перенос" + a + "строки");
```
```php
$a = "\n";
echo ("Тут есть" . $a . "перенос" . $a . "строки");
```
## `+` и динамическая типизация.
Так как в **JS** нет отдельного оператора конкатенации (в **PHP** это `.`), то `+` между числами в строках может вас удивить:
![суть](https://pp.vk.me/c631923/v631923540/45dbe/uK3mUei6G5s.jpg)
Для того что бы избежать подобных ситуаций, приводите числа в строках перед использованием в математических операциях:
- `+"123"`. Простой и краткий способ для приведения строки к числу
- `parseInt("123")` или `parseFloat("123.45")` работает схожим образом, однако обладает другими странностями и возможностями (например есть возможность
задать систему счисления)
## Операторы, условия, циклы.
### Вызов функций
Большинство кода состоит из тех или иных вызовов функций. В **JS** они выглядят почти так же:
```javascript
alert("as in PHP");
alert("as in JS, without semicolon")
```
Во второй строке примера нет `;`, в этом невеликое отличие.
### Операторы
В большинстве своем повторяют обычный набор **PHP**, **C**, **Java** и так далее (`+`, `-`, `*`, `/`, `%`, `++`, `--`, `+=` ...). В **JS** нет `and`, `or`
и `not`, используйте `&&`, `||`, `!`.
### Условия `if` и `switch`.
Работают аналогично **PHP**, однако не имеют своих длинных форм `if-endif` и `switch-endswitch`. Работают только обычные формы с фигурными скобками.
### Циклы
#### `foreach`
В **JS** нет `foreach`, однако есть форма `for`, схожая по функционалу:
```javascript
var car = {brand: "Lada",
'model': "2101"};
for (var key in car){
alert(key + ": " + car[key]);
}
```
```php
var $car = ["brand" => "Lada",
"model" => "2101"];
foreach ($car as $key => $value){
echo("$key: $value");
}
```
Как можно заметить, при этом в цикле нет переменной со значенинем, а только с ключем, по которому можно в цикле получить значение из итерируемого массива.
#### `for`, `while` и `do-while`
работают так же как в **PHP**:
```javascript
for (var i=0;i<10;i++){
console.log(i);
}
```
```php
for ($i=0;$i<10;$i++){
echo $i;
}
```
## Типы данных и Объектная модель.
### Обращение к полям и методам объектов **JS**
Аналогом `->` в **JS** является `.`.
### Всё является объектом
Даже встроенные типы данных. Многие стандартные функции **PHP** в процедурном стиле являются методами объектов в **JS**.
### Числа.
Кроме того, что целые и дробные числа объединены в единый тип `Number`, особых отличий с **PHP** нет:
```javascript
console.log(1/0); //Infinity
console.log(-1/0);//-Infinity
console.log(1/"asdf");//NaN
```
```php
echo(1/0); //INF + исключение Division By Zero
echo(-1/0);//-INF + исключение Division By Zero
echo(1/"asdf");//INF + исключение Division By Zero
```
**PHP** при приведении к числу превращает некорректные строки в 0:
```php
echo intval("aaa100500");
```
**JS** в подобной ситуации возвращает `NaN`:
```javascript
console.log(+"aaa100500");
```
Также **JS** не выбрасывает исключение "Деление на ноль", а просто возвращает бесконечность.
#### Число как объект
С числами можно работать как с объектами:
```javascript
console.log(5.123456.toFixed(2)); // "5.12"
```
Аналогично
```php
echo(round(5.123456,2)); // 5.12
```
Тем не менее, многие математические операции вынесены в глобальный объект-коллекцию `Math` (например, Math.round, Math.ceil, Math.random и другие)
### Строки
Большинство строковых операций являются методами объекта-строки:
```javascript
console.log("12345".length); //5
console.log("aBcDe".indexOf("D")); // 3
console.log("123string456".substr(3,6)); // "string"
```
```php
echo (strlen("12345")); //5
echo (strpos("aBcDe","D")); // 3
echo (substr("123string456",3,6)); // "string"
```
### Boolean
Работает почти как в **PHP**, однако:
- в **JS** `true` и `false` регистрозависимы. В **PHP** допустимы `FALse` и `tRuE`.
- При приведении к строке в **JS** получаются строки `"true"` и `"false"`, в **PHP** - `1` и пустая строка `""`.
### `undefined`
Аналог `NULL` в **PHP**. В этом типе есть только одно значение - `undefined`
### `null`
`null` - это "`undefined` для программиста", а не для интерпретатора. Так же используется в **DOM** для пустых/незаданных значений.
### Массивы