me@helium 8 anni fa
parent
commit
4760a90386
1 ha cambiato i file con 140 aggiunte e 2 eliminazioni
  1. 140 2
      php2js.md

+ 140 - 2
php2js.md

@@ -89,6 +89,53 @@ Javascript-интерпретатор в браузере может работ
 
 ```
 
+## Семантика и её отличия от **PHP**.
+
+### Длительность и асинхронность.
+
+- **PHP** изначально **Designed To Die**, в том смысле что работа с сайтом состоит из краткий запросов, в идеале выполняющихся мгновенно; обмен данными
+    между разными запросами происходит с помощью сессий и/или СУБД. Сборка мусора изначально отсутствовала, да и сейчас не является приоритетной. Освобождение
+    памяти происходит по окончании обработки запроса, вместе с прекращением работы интерпретатора. 
+- В **JS** код наоборот, работает длительное время (обычно всё время работы страницы), что приводит к другой семантике и организации кода в событийной среде.
+
+
+- В **PHP** код исполняется многопоточно (однако каждый поток работает изолированно, многопоточность зачастую реализуется как запуск нескольких копий 
+    интерпретатора в многозадачной ОС) и **синхронно**, т. е. код выполняется в том порядке, в котором он написан; в скрипте никаких фоновых и 
+    непоследовательных операций обычно не предусмотрено, ввод-вывод (запись и чтение файлов, сетевые запросы, запросы к СУБД) происходят в **блокирующем**
+    режиме, т. е.  интерпретатор останавливает выполнения и ожидает отправки или приема той или иной порции данных.
+- В **JS** код исполняется однопоточно (за редким исключением), и **асинхронно**, т. е. код представляет из себя не единую последовательность действий,
+    а набор функций, которые могут исполнятся в произвольном порядке в качестве обработчиков событий на странице, событий, связанных с временными задержками
+    или сетевых событий. Однако надо учитывать, что код, расположенный в функции, обычно работает **синхронно** и **однопоточно**, *никакой другой обработчик*
+    события не может работать, пока работает другой код. **Асинхронными являются только вызовы обработчиков событий из движка браузера**, когда же вы вызываете 
+    функцию в своем коде, весь ваш код работает *синхронно*. Ввод-вывод так же происходит в асинхронной манере - вместо ожидания данных, интерпретатор
+    освобождается для обработки других событий; по окончанию операции ввода-вывода вызывается соответствующая функция, обрабатывающая результаты.
+
+Данные отличия приводят к сложности написания, отладки и понимания **JS** кода. Стандартные ошибки:
+- Путание определения функции и её выполнения.
+- Ожидание работы кода в последовательности написания, а не в последовательности событий, которые запускают те или иные части кода.
+
+### Семантические последствия и особенности **JS**.
+
+- Язык унаследовал некоторые черты функциональных языков и языков высокого уровня абстракции (`Scheme`, `Common Lisp`)
+- Функциональный подход превалирует над "обычным" ООП-подходом, привычным после **PHP**/**C++**/**Java**.
+- Функции являются объектами первого класса, т. е. могут быть сохранены как переменные и переданы/возвращены в/из других функций.
+- Объект и ассоциативный массив - это одно и то же.
+- В ассоциативных массивах наряду с другими типами данных можно хранить функции, что превращает их в объекты. (**инкапсуляция**)
+- Функции можно заносить в объекты, запускать как методы, или как отдельные функции. `this` обычно равен объекту, указанному до `.`, однако
+  есть возможность передать функции в качестве `this` любой объект. 
+- Можно менять и переопределять структуру *почти* всех объектов, включая стандартные, что позволяет кардинально менять их поведение.(**полиморфизм**)
+  Таким образом можно сделать аналог примесей, интерфейсов и множественного наследования.
+- В **JS** реализовано так называемое прототипное ООП: вместо указания предка и обработки наследования на уровне интерпретатора, в **JS** в объекте
+  есть ключ `prototype`, который является ссылкой на другой объект-прототип. **В случае, когда тот или иной ключ (имя метода или поля) в объекте не найден,
+  JS ищет ключ в объекте-прототипе**, и далее по цепочке прототипов. Таким образом реализуется **наследование**.
+- `private`, `protected` и `public` нет.
+- Функция исполняется одновременно в *динамическом* (значение параметров при вызове) и *лексическом* (переменные из областей видимости *декларации* функции)
+  контекстах. Таким образом реализуются **замыкания**: переменные области видимости *завершенной* функции сохраняются для использования функциями, 
+  определенных внутри, *в случае* если внутренние функции были переданы как результат работы функции или другими способами остались существовать
+  после окончания внешней функции. Таким образом реализуются аналог `private` полей объекта, а так же сохраняется контекст для отложенных операций или
+  обработчиков событий. **Замыкания** являются *объектами* в общем смысле этого слова, так как инкапсулируют код и данные.
+- *Синтаксически* **JS** *более* объектно-ориентирован чем **PHP**, так как *все* типы данных являются объектами с набором методов.
+
 
 
 ## Переменные и типы данных
@@ -263,6 +310,98 @@ alert("as in JS, without semicolon")
 В большинстве своем повторяют обычный набор **PHP**, **C**, **Java** и так далее (`+`, `-`, `*`, `/`, `%`, `++`, `--`, `+=` ...). В **JS** нет `and`, `or`
 и `not`, используйте `&&`, `||`, `!`.
 
+### `&&` и `||`.
+
+В отличие от **PHP**, в **JS** **И** и **ИЛИ** возвращают *оригинальное значение операнда*, а не булевский результат логического оператора.
+
+#### `||`
+Результат `||` становится очевиден после первого же значения, интерпретируемого как `true`. **ИЛИ** *слева направо* поочередно приводит операнды к Boolean
+и возвращает *первый* операнд, *интерпретируемый* как `true`. Если такого операнда нет, **ИЛИ** возвращает последний (правый) операнд. **Результатом**
+оператора является не приведенное к типу Boolean значение, а *оригинальное значение операнда*
+
+#### `&&`
+Результат `&&` становится очевиден после первого же значения, интепретируемого как `false`. **И** *слева направо* поочередно приводит операнды к Boolean
+и возвращает *первый* операнд, *интерпретируемый* как `false`. Если такого операнда нет, **И** возврщаает последний (правый) операнд. **Результатом**
+оператора является не приведенное к типу Boolean значение, а *оригинальное значение операнда*
+
+#### Приведение к типу `Boolean`
+
+Как `false` интерпретируются:
+- `false` 
+- `0` // 0 как число
+- `""` //пустая строка
+- `null`
+- `undefined`
+- `NaN`
+
+Как `true` интерпретируются все остальные значения, в том числе:
+- `Infinity`
+- `-Infinity`
+- `"0"` //строка не пуста. однако +"0" уже 0 как число, а значит false
+- `{}` //пустой объект - всё равно `true`
+- `[]` //пустой массив `[] == false`, но в остальных случаях работает как true
+
+**Для проверки используйте** `!!`, то есть двойное отрицание: `!!null` равен `false`, таким образом мы можем почти всегда проверить как интерпретируется
+то или иное значение.
+
+В общем случае объект является `true`, за исключением `null` и `[] == false`
+
+**Примеры**
+```javascript
+2
+1+1
+2*1
+// bool type cast
+!!2
+!!0
+!!1
+// or
+2 || 1
+2 || 0
+//and
+2 && 1
+1 && 2
+0 && 2
+// or and and difference
+0 || 1 || 2
+0 && 1 && 2
+2 || 1 || 0
+2 && 1 && 0
+//null, undefined, so on
+null || 2
+undefined && 1
+//brackets and complex expressions
+(undefined || 2) && (2 || 0)
+(2 && 1) || (null && 0)
+(2 > 1) && "greater"
+(2 < 1) && null
+null && (2 < 1)
+// ternary operator
+1 ? "one" : "not one"
+0 ? "zero" : "not zero"
+"0" ? "\"zero\"" : "not `zero`"
+parseInt("0") ? 'true' : 'false'
+("" || 2) && (3 || "3.5") || (4 && 5)
+(-1 + 1) && "zero"
+"-1" + 1 && "oups"
+(typeof null === 'object') ? "null is object" : "null is null"
+// ternary && ||
+Math.random() < 0.5 && 'less' || 'more'
+(a = Math.random()) < 0.5 && 'less: '+a || 'more: '+a
+//in for array
+[2,3,5,7,11].indexOf(7) > -1 ? 'prime' : 'not found'
+'random' in Math
+'indexOf' in []
+var a = b = c = d = 5;
+```
+
+**PHP** ведет себя по-другому:
+
+```php
+echo var_dump(2 || "aaa");// bool(true)
+echo var_dump(0 && "aaa");// bool(false)
+```
+
 ### Условия `if` и `switch`.
 
 Работают аналогично **PHP**, однако не имеют своих длинных форм `if-endif` и `switch-endswitch`. Работают только обычные формы с фигурными скобками.
@@ -317,7 +456,7 @@ for ($i=0;$i<10;$i++){
 
 ### Всё является объектом
 
-Даже встроенные типы данных. Многие стандартные функции **PHP** в процедурном стиле являются методами объектов в  **JS**.
+Даже встроенные типы данных. Аналоги стандартных функций **PHP** (процедурный стиль) являются методами объектов в **JS**.
 
 ### Числа.
 Кроме того, что целые и дробные числа объединены в единый тип `Number`, особых отличий с **PHP** нет:
@@ -391,6 +530,5 @@ echo (substr("123string456",3,6)); // "string"
 
 `null` - это "`undefined` для программиста", а не для интерпретатора. Так же используется в **DOM** для пустых/незаданных значений.
 
-
 ### Массивы