up
This commit is contained in:
parent
9ad9063d00
commit
97a0f22ff0
99 changed files with 1161 additions and 1208 deletions
|
@ -1,10 +1,8 @@
|
|||
# JavaScript specials: all together
|
||||
# Javascript specials
|
||||
|
||||
[todo finish me. is this needed?]
|
||||
This chapter aims to list features of JavaScript that we've learned, paying special attention to subtle moments.
|
||||
|
||||
This chapter aims to list features of JavaScript that we've learned, paying special attention to unobvious moments.
|
||||
|
||||
That's especially useful if you came from another language or, just as a recap.
|
||||
That's especially useful if you came from another language or just as a recap.
|
||||
|
||||
[cut]
|
||||
|
||||
|
@ -37,13 +35,13 @@ Semicolons are not required after code blocks `{...}` and syntax constructs with
|
|||
|
||||
```js
|
||||
function f() {
|
||||
// no semicolon after function declaration
|
||||
// no semicolon needed after function declaration
|
||||
}
|
||||
|
||||
for(;;) { /* no semicolon */ }
|
||||
for(;;) { /* no semicolon after the loop */ }
|
||||
```
|
||||
|
||||
...But even if we can put a semicolon there, that's not an error, extra semicolons do nothing.
|
||||
...But even if we can put an "extra" semicolon somewhere, that's not an error, it will be ignored.
|
||||
|
||||
More in: <info:structure>.
|
||||
|
||||
|
@ -61,7 +59,7 @@ The directive must be at the top of a script or at the beginning of a function.
|
|||
|
||||
Without `"use strict"`, everything still works, but some features behave in old-fasion, "compatible" way. We'd generally prefer the modern behavior.
|
||||
|
||||
Later we'll get acquanted with advanced features of the language that enable strict mode implicitly.
|
||||
Advanced features of the language (like classes that we'll study in the future) that enable strict mode implicitly.
|
||||
|
||||
More in: <info:strict-mode>.
|
||||
|
||||
|
@ -94,7 +92,13 @@ There are 7 data types:
|
|||
- `undefined` -- a type with a single value `undefined`, meaning "not assigned",
|
||||
- `object` and `symbol` -- for complex data structures and unique identifiers, we didn't learn them yet.
|
||||
|
||||
More in: <info:variables>, <info:types>.
|
||||
The `typeof` operator returns the type for a value, with two special behaviors:
|
||||
```js
|
||||
typeof null == "object" // error in the language
|
||||
typeof function(){} == "function" // functions are treated specially
|
||||
```
|
||||
|
||||
More in: <info:variables> and <info:types>.
|
||||
|
||||
## Interaction
|
||||
|
||||
|
@ -117,8 +121,8 @@ For instance:
|
|||
let userName = prompt("Your name?", "Alice");
|
||||
let isTeaWanted = confirm("Do you want some tea?");
|
||||
|
||||
alert( "Visitor: " + userName );
|
||||
alert( "Tea wanted: " + isTeaWanted );
|
||||
alert( "Visitor: " + userName ); // Alice
|
||||
alert( "Tea wanted: " + isTeaWanted ); // true
|
||||
```
|
||||
|
||||
More in: <info:uibasic>.
|
||||
|
@ -130,7 +134,7 @@ JavaScript supports following operators:
|
|||
Arithmetical
|
||||
: Regular: `* + - /`, also `%` for the remainder and `**` for power of a number.
|
||||
|
||||
Binary plus `+` contatenates strings.
|
||||
Binary plus `+` concatenates strings.
|
||||
|
||||
If any of the operands is a string -- the other one is converted to string too:
|
||||
|
||||
|
@ -143,7 +147,8 @@ Assignments
|
|||
: There is a simple assignment: `a = b` and combined ones like `a *= 2`.
|
||||
|
||||
Bitwise
|
||||
: Bitwise operators work with integers on bit-level: see the [docs](mdn:JavaScript/Reference/Operators/Bitwise_Operators) when they are needed.
|
||||
: Bitwise operators work with integers on bit-level: see the [docs](mdn:JavaScript/Refereno
|
||||
ce/Operators/Bitwise_Operators) when they are needed.
|
||||
|
||||
Ternary
|
||||
: The only operator with three parameters: `cond ? resultA : result B`
|
||||
|
@ -152,189 +157,140 @@ Logical operators
|
|||
: Logical AND `&&` and OR `||` perform short-circuit evaluation and then return the value where it stopped.
|
||||
|
||||
Comparisons
|
||||
: Equality check `===` immediately fails if types are different.
|
||||
|
||||
Other comparisons perform type conversions, usually to a number:
|
||||
: Equality check `==` for values of different types converts them to a number (except `null` and `undefined` that equal each other and nothing else), so these are equal:
|
||||
|
||||
```js run
|
||||
alert( 0 == false ); // true
|
||||
alert( true > 0 ); // true
|
||||
alert( 0 == '' ); // true
|
||||
```
|
||||
|
||||
Other comparisons convert to a number as well.
|
||||
|
||||
The strict equality operator `===` doesn't do the conversion: different types always mean different values for it, so:
|
||||
|
||||
|
||||
|
||||
Values `null` and `undefined` are special: they equal `==` each other and don't equal anything else.
|
||||
|
||||
Greater/less comparisons compare strings character-by-character, other types are converted to a number.
|
||||
|
||||
Others
|
||||
Logical operators
|
||||
: There are few others, like a comma operator.
|
||||
|
||||
More in: <info:operators>, <info:comparison>.
|
||||
More in: <info:operators>, <info:comparison>, <info:logical-ops>.
|
||||
|
||||
## Логические операторы
|
||||
## Loops
|
||||
|
||||
В JavaScript есть логические операторы: И (обозначается `&&`), ИЛИ (обозначается `||`) и НЕ (обозначается `!`). Они интерпретируют любое значение как логическое.
|
||||
|
||||
Не стоит путать их с [побитовыми операторами](/bitwise-operators) И, ИЛИ, НЕ, которые тоже есть в JavaScript и работают с числами на уровне битов.
|
||||
|
||||
Как и в большинстве других языков, в логических операторах используется "короткий цикл" вычислений. Например, вычисление выражения `1 && 0 && 2` остановится после первого И `&&`, т.к. понятно что результат будет ложным (ноль интерпретируется как `false`).
|
||||
|
||||
**Результатом логического оператора служит последнее значение в коротком цикле вычислений.**
|
||||
|
||||
Можно сказать и по-другому: значения хоть и интерпретируются как логические, но то, которое в итоге определяет результат, возвращается без преобразования.
|
||||
|
||||
Например:
|
||||
|
||||
```js run
|
||||
alert( 0 && 1 ); // 0
|
||||
alert( 1 && 2 && 3 ); // 3
|
||||
alert( null || 1 || 2 ); // 1
|
||||
```
|
||||
|
||||
Подробнее: <info:logical-ops>.
|
||||
|
||||
## Циклы
|
||||
|
||||
- Поддерживаются три вида циклов:
|
||||
- We covered 3 types of loops:
|
||||
|
||||
```js
|
||||
// 1
|
||||
while (условие) {
|
||||
while (condition) {
|
||||
...
|
||||
}
|
||||
|
||||
// 2
|
||||
do {
|
||||
...
|
||||
} while (условие);
|
||||
} while (condition);
|
||||
|
||||
// 3
|
||||
for let i = 0; i < 10; i++) {
|
||||
for(let i = 0; i < 10; i++) {
|
||||
...
|
||||
}
|
||||
```
|
||||
- Переменную можно объявлять прямо в цикле, но видна она будет и за его пределами.
|
||||
- Поддерживаются директивы `break/continue` для выхода из цикла/перехода на следующую итерацию.
|
||||
|
||||
Для выхода одновременно из нескольких уровней цикла можно задать метку.
|
||||
- The variable declared in `for(let...)` loop is visible only inside the loop. But we can also omit `let` and reuse an existing variable.
|
||||
- Directives `break/continue` allow to exit the whole loop/current iteration. Use labels to break nested loops.
|
||||
|
||||
Синтаксис: "`имя_метки:`", ставится она только перед циклами и блоками, например:
|
||||
Details in: <info:while-for>.
|
||||
|
||||
```js
|
||||
*!*outer:*/!*
|
||||
for(;;) {
|
||||
...
|
||||
for(;;) {
|
||||
...
|
||||
*!*break outer;*/!*
|
||||
}
|
||||
}
|
||||
```
|
||||
Later we'll study more types of loops to deal with objects.
|
||||
|
||||
Переход на метку возможен только изнутри цикла, и только на внешний блок по отношению к данному циклу. В произвольное место программы перейти нельзя.
|
||||
## The "switch" construct
|
||||
|
||||
Подробнее: <info:while-for>.
|
||||
The "switch" construct can replace multiple `if` checks. It uses `===` for comparisons.
|
||||
|
||||
## Конструкция switch
|
||||
|
||||
При сравнениях в конструкции `switch` используется оператор `===`.
|
||||
|
||||
Например:
|
||||
For instance:
|
||||
|
||||
```js run
|
||||
let age = prompt('Ваш возраст', 18);
|
||||
let age = prompt('Your age?', 18);
|
||||
|
||||
switch (age) {
|
||||
case 18:
|
||||
alert( 'Никогда не сработает' ); // результат prompt - строка, а не число
|
||||
alert("Won't work"); // the result of prompt is a string, not a number число
|
||||
|
||||
case "18": // вот так - сработает!
|
||||
alert( 'Вам 18 лет!' );
|
||||
case "18":
|
||||
alert("This works!"");
|
||||
break;
|
||||
|
||||
default:
|
||||
alert( 'Любое значение, не совпавшее с case' );
|
||||
alert("Any value not equal to one above");
|
||||
}
|
||||
```
|
||||
|
||||
Подробнее: <info:switch>.
|
||||
Details in: <info:switch>.
|
||||
|
||||
## Функции
|
||||
## Functions
|
||||
|
||||
Синтаксис функций в JavaScript:
|
||||
We covered 3 ways to create a function in Javascript:
|
||||
|
||||
```js run
|
||||
// function имя(список параметров) { тело }
|
||||
function sum(a, b) {
|
||||
let result = a + b;
|
||||
1. Function Declaration: the function in the main code flow
|
||||
|
||||
return result;
|
||||
}
|
||||
```js
|
||||
function sum(a, b) {
|
||||
let result = a + b;
|
||||
|
||||
// использование:
|
||||
alert( sum(1, 2) ); // 3
|
||||
```
|
||||
|
||||
- `sum` -- имя функции, ограничения на имя функции -- те же, что и на имя переменной.
|
||||
- Переменные, объявленные через `let` внутри функции, видны везде внутри этой функции, блоки `if`, `for` и т.п. на видимость не влияют.
|
||||
- Параметры копируются в локальные переменные `a`, `b`.
|
||||
- Функция без `return` считается возвращающей `undefined`. Вызов `return` без значения также возвращает `undefined`:
|
||||
|
||||
```js run no-beautify
|
||||
function f() { }
|
||||
alert( f() ); // undefined
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
Подробнее: <info:function-basics>.
|
||||
2. Function Expression: the function in the context of an expression
|
||||
|
||||
## Function Declaration и Expression
|
||||
```js
|
||||
let sum = function(a, b) {
|
||||
let result = a + b;
|
||||
|
||||
Функция в JavaScript является обычным значением.
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
Её можно создать в любом месте кода и присвоить в переменную, вот так:
|
||||
Function expression can have a name, like `sum = function name(a, b)`, but that `name` is only visible inside that function.
|
||||
|
||||
```js run
|
||||
let sum = function(a, b) {
|
||||
let result = a + b;
|
||||
3. Arrow functions:
|
||||
|
||||
return result;
|
||||
}
|
||||
```js
|
||||
// expression at the right side
|
||||
let sum = (a, b) => a + b;
|
||||
|
||||
alert( sum(1, 2) ); // 3
|
||||
```
|
||||
// or multiline syntax with { ... }, need return here:
|
||||
let sum = (a, b) => {
|
||||
// ...
|
||||
return a + b;
|
||||
}
|
||||
|
||||
Такой синтаксис, при котором функция объявляется в контексте выражения (в данном случае, выражения присваивания), называется Function Expression, а обычный синтаксис, при котором функция объявляется в основном потоке кода -- Function Declaration.
|
||||
// without arguments
|
||||
let sayHi = () => alert("Hello");
|
||||
|
||||
Функции, объявленные через Function Declaration, отличаются от Function Expression тем, что интерпретатор создаёт их при входе в область видимости (в начале выполнения скрипта), так что они работают до объявления.
|
||||
// with a single argument
|
||||
let double = n => n * 2;
|
||||
```
|
||||
|
||||
Обычно это удобно, но может быть проблемой, если нужно объявить функцию в зависимости от условия. В этом случае, а также в других ситуациях, когда хочется создать функцию "здесь и сейчас", используют Function Expression.
|
||||
|
||||
Детали: <info:function-declaration-expression>.
|
||||
- Functions may have local variables -- those declared inside its body. Such variables are only visible inside the function.
|
||||
- Parameters can have default values: `function sum(a=1, b=2) {...}`.
|
||||
- Functions always return something. If there's no `return` statement, then the result is `undefined`.
|
||||
|
||||
## Named Function Expression
|
||||
|
||||
Если объявление функции является частью какого-либо выражения, например `let f = function...` или любого другого, то это Function Expression.
|
||||
| Function Declaration | Function Expression |
|
||||
|----------------------|---------------------|
|
||||
| visible in the whole code block | created when the execution reaches it |
|
||||
| - | can have a name, visible only inside the function |
|
||||
|
||||
В этом случае функции можно присвоить "внутреннее" имя, указав его после `function`. Оно будет видно только внутри этой функции и позволяет обратиться к функции изнутри себя. Обычно это используется для рекурсивных вызовов.
|
||||
More: see <info:function-basics>, <info:function-expressions-arrows>.
|
||||
|
||||
Например, создадим функцию для вычисления факториала как Function Expression и дадим ей имя `me`:
|
||||
## More to come
|
||||
|
||||
```js run
|
||||
let factorial = function me(n) {
|
||||
return (n == 1) ? n : n * me(n - 1);
|
||||
}
|
||||
That was a brief list of Javascript specials that we need to know to code well.
|
||||
|
||||
alert( factorial(5) ); // 120
|
||||
*!*
|
||||
alert( me ); // ошибка, нет такой переменной
|
||||
*/!*
|
||||
```
|
||||
|
||||
Ограничение видимости для имени не работает в IE8-, но вызов с его помощью работает во всех браузерах.
|
||||
|
||||
Более развёрнуто: <info:named-function-expression>.
|
||||
|
||||
## Итого
|
||||
|
||||
В этой главе мы повторили основные особенности JavaScript, знание которых необходимо для обхода большинства "граблей", да и просто для написания хорошего кода.
|
||||
|
||||
Это, конечно, лишь основы. Дальше вы узнаете много других особенностей и приёмов программирования на этом языке.
|
||||
As of now that were only basics. Further in the tutorial you'll find more specials and advanced features of Javascript.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue