This commit is contained in:
Ilya Kantor 2016-08-25 17:35:33 +03:00
parent b78f329c5f
commit 0818e61927
20 changed files with 264 additions and 163 deletions

View file

@ -18,7 +18,7 @@ If you haven't considered selecting an IDE, pleae look at the following variants
- Visual Studio is fine if you're a .NET developer.
- Eclipse-based products, like [Aptana](http://www.aptana.com/) and Zend Studio.
- [Komodo IDE](http://www.activestate.com/komodo-ide) and it's lightweight free version [Komodo Edit](http://www.activestate.com/komodo-edit).
- [Netbeans](http://netbeans.org/)
- [Netbeans](http://netbeans.org/).
All of them with the exception of Visual Studio are cross-platform.
@ -30,9 +30,9 @@ Most IDEs are paid, but have a trial period. Their cost is usually negligible co
They are mainly used to instantly open and edit a file.
The main difference between a "lightweight editor" and an "IDE" is that the latter works on a project-level, meaning it has to load a lot of data to start, and the former one opens just the files. That's much faster.
The main difference between a "lightweight editor" and an "IDE" is that IDE works on a project-level, so it loads much more data on start, analyzes the project structure if needed and so on. A lightweight editor is much faster if we need only one file.
In practice, "lightweight" editors may have a lot of plugins including directory-level syntax analyzers and autocompleters, so there's no strict border between a lightweight editor and an IDE.
In practice, lightweight editors may have a lot of plugins including directory-level syntax analyzers and autocompleters, so there's no strict border between a lightweight editor and an IDE.
The following options deserve your attention:
@ -43,7 +43,7 @@ The following options deserve your attention:
## My favorites
I believe one should have both an IDE for projects and a lightweight editor for quick and easy file editing.
The personal preference of the author is to have both an IDE for projects and a lightweight editor for quick and easy file editing.
I'm using:
@ -54,7 +54,7 @@ If you don't know what to choose -- you can consider these ones.
## Let's not argue
The editors in the lists above are those that me or my friends -- good developers use for a long time and are happy with.
The editors in the lists above are those that me or my friends -- good developers are using for a long time and are happy with.
There are other great editors in our big world, please choose the one you like the most.

View file

@ -12,9 +12,9 @@ To see errors and get a lot of other useful information about scripts, browsers
Other browsers also provide developer tools, but are usually in a "catching-up" position, compared to Chrome/Firefox which are the best.
If there is an error in the certain browser only, then we can always switch to it's developer tools for the concrete problem.
Sometimes, it may be required to switch to another browser, if a problem is browser-specific, but that's rare.
Developer tools are really powerful, there are many features. On this stage let's just look how to open them, look at errors and run JavaScript commands.
Developer tools are really powerful, there are many features. Here, for the start, we'll learn how to open them, look at errors and run JavaScript commands.
[cut]

View file

@ -1,10 +1,10 @@
# Hello, world!
About 98% of the tutorial is core Javascript, that is platform-independant. So you'll be able to learn how to use Node.JS and other things based on that knowledge.
The tutorial that you're reading is about core Javascript, that is platform-independant. So you'll be able to learn how to use Node.JS and other things based on that knowledge.
But we need something like a "base environment" to run our scripts, and browser is probably a good choice.
But we need a working environment to run our scripts, and browser is probably a good choice. Also we'll use few browser-specific commands like `alert`, but will keep their amount to the minimum.
So we'll start with attaching a script to the webpage. For other environments like Node.JS there are other ways to run it.
So we'll start with attaching a script to the webpage. For other environments like Node.JS there are other, probably even easier ways to run it.
[cut]
@ -134,4 +134,3 @@ The example above can be split into two scripts to work:
There is much more about browser scripts and their interaction with the web-page. But let's keep in mind that this part of the tutorial is devoted to Javascript language. So we shouldn't distract ourselves from it. We'll be using a browser as a way to run Javascript, very convenient for online reading, but yet one of many.

View file

@ -193,7 +193,7 @@ let имя = '...';
let 我 = '...';
```
Technically, there is no error here, such names are allowed, but there is an international tradition to use English in variable names. Even if we're writing a small script, it may have a long life ahead. People coming with another language background may need to read it some time.
Technically, there is no error here, such names are allowed, but there is an international tradition to use English in variable names. Even if we're writing a small script, it may have a long life ahead. People from other countries may need to read it some time.
````
````warn header="Reserved names"

View file

@ -2,7 +2,7 @@
There are 7 data types in JavaScript.
Here we will get the common understanding of them. In the next chapters we'll talk about each type in detail.
In this chapter we'll get the common understanding of them. In further chapters we'll talk about each type in detail.
[cut]

View file

@ -1,102 +1,53 @@
# TODO: Всё вместе: особенности JavaScript
# JavaScript specials: all together
В этой главе приводятся основные особенности JavaScript, на уровне базовых конструкций, типов, синтаксиса.
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.
[cut]
## Структура кода
## Code structure
Операторы разделяются точкой с запятой:
Statements are delimited with a semicolon:
```js run no-beautify
alert('Привет'); alert('Мир');
alert('Hello'); alert('World');
```
Как правило, перевод строки тоже подразумевает точку с запятой. Так тоже будет работать:
Usually, a line-break is also treated as a delimiter, so that would also work:
```js run no-beautify
alert('Привет')
alert('Мир')
alert('Hello')
alert('World')
```
...Однако, иногда JavaScript не вставляет точку с запятой. Например:
```js run no-beautify
let a = 2
+3
alert(a); // 5
```
Бывают случаи, когда это ведёт к ошибкам, которые достаточно трудно найти и исправить, например:
That's called "automatic semicolon insertion". Sometimes it doesn't work, for instance:
```js run
alert("После этого сообщения будет ошибка")
alert("There will be an error after this message")
[1, 2].forEach(alert)
```
Детали того, как работает код выше (массивы `[...]` и `forEach`) мы скоро изучим, здесь важно то, что при установке точки с запятой после `alert` он будет работать корректно.
Most codestyle guides agree that we should put a semicolon after each statement.
**Поэтому в JavaScript рекомендуется точки с запятой ставить. Сейчас это, фактически, общепринятый стандарт.**
Поддерживаются однострочные комментарии `// ...` и многострочные `/* ... */`:
Подробнее: <info:structure>.
## Переменные и типы
- Объявляются директивой `let`. Могут хранить любое значение:
Semicolons are not required after code blocks `{...}` and syntax constructs with them:
```js
let x = 5;
x = "Петя";
```
- Есть 5 "примитивных" типов и объекты:
function f() {
// no semicolon after function declaration
}
```js no-beautify
x = 1; // число
x = "Тест"; // строка, кавычки могут быть одинарные или двойные
x = true; // булево значение true/false
x = null; // спец. значение (само себе тип)
x = undefined; // спец. значение (само себе тип)
for(;;) { /* no semicolon */ }
```
Также есть специальные числовые значения `Infinity` (бесконечность) и `NaN`.
...But even if we can put a semicolon there, that's not an error, extra semicolons do nothing.
Значение `NaN` обозначает ошибку и является результатом числовой операции, если она некорректна.
- **Значение `null` не является "ссылкой на нулевой адрес/объект" или чем-то подобным. Это просто специальное значение.**
More in: <info:structure>.
Оно присваивается, если мы хотим указать, что значение переменной неизвестно.
## Strict mode
Например:
```js
let age = null; // возраст неизвестен
```
- **Значение `undefined` означает "переменная не присвоена".**
Например:
```js
let x;
alert( x ); // undefined
```
Можно присвоить его и явным образом: `x = undefined`, но так делать не рекомендуется.
Про объекты мы поговорим в главе <info:object>, они в JavaScript сильно отличаются от большинства других языков.
- В имени переменной могут быть использованы любые буквы или цифры, но цифра не может быть первой. Символы доллар `$` и подчёркивание `_` допускаются наравне с буквами.
Подробнее: <info:variables>, <info:types-intro>.
## Строгий режим
Для того, чтобы интерпретатор работал в режиме максимального соответствия современному стандарту, нужно начинать скрипт директивой `'use strict';`
To fully enable all features of modern JavaScript, we should start scripts with `"use strict"`.
```js
'use strict';
@ -104,90 +55,118 @@ alert("После этого сообщения будет ошибка")
...
```
Эта директива может также указываться в начале функций. При этом функция будет выполняться в режиме соответствия, а на внешний код такая директива не повлияет.
The directive must be at the top of a script or at the beginning of a function.
Одно из важных изменений в современном стандарте -- все переменные нужно объявлять через `let`. Есть и другие, которые мы изучим позже, вместе с соответствующими возможностями языка.
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.
Простейшие функции для взаимодействия с посетителем в браузере:
More in: <info:strict-mode>.
["prompt(вопрос[, по_умолчанию])"](https://developer.mozilla.org/en/DOM/window.prompt)
: Задать `вопрос` и возвратить введённую строку, либо `null`, если посетитель нажал "Отмена".
## Variables
["confirm(вопрос)"](https://developer.mozilla.org/en/DOM/window.confirm)
: Задать `вопрос` и предложить кнопки "Ок", "Отмена". Возвращает, соответственно, `true/false`.
Can be declared using:
["alert(сообщение)"](https://developer.mozilla.org/en/DOM/window.alert)
: Вывести сообщение на экран.
- `let` (block-level visibility)
- `const` (can't be changed)
- `var` (old-style, will see later)
Все эти функции являются *модальными*, т.е. не позволяют посетителю взаимодействовать со страницей до ответа.
A variable name can include:
- Letters and digits, but the first character may not be a digit.
- Characters `$` and `_` are normal, on par with letters.
- Non-latin alphabets and hieroglyphs are also allowed, but commonly not used.
Например:
Variables are dynamically typed -- they can store any value:
```js run
let userName = prompt("Введите имя?", "Василий");
let isTeaWanted = confirm("Вы хотите чаю?");
alert( "Посетитель: " + userName );
alert( "Чай: " + isTeaWanted );
```js
let x = 5;
x = "John";
```
Подробнее: <info:uibasic>.
There are 7 data types:
## Особенности операторов
- `number` for both floating-point and integer numbers,
- `string` for strings,
- `boolean` for logical values: `true/false`,
- `null` -- a type with a single value `null`, meaning "empty" or "does not exist",
- `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>.
Если хоть один аргумент -- строка, то другой тоже приводится к строке:
## Interaction
We're using a browser as a working environment, so basic UI functions will be:
[`prompt(question[, default])`](mdn:api/Window/prompt)
: Ask a `question`, and return either what the visitor entered or `null` if he pressed "cancel".
[`confirm(question)`](mdn:api/Window/confirm)
: Ask a `question` and suggest to choose between Ok and Cancel. The choice is returned as `true/false`.
[`alert(message)`](mdn:api/Window/alert)
: Output a `message`.
All these functions are *modal*, they pause the code execution and prevent the visitor from interaction with the page until he answers.
For instance:
```js run
alert( 1 + 2 ); // 3, число
alert( '1' + 2 ); // '12', строка
alert( 1 + '2' ); // '12', строка
```
- **Сравнение `===` проверяет точное равенство, включая одинаковый тип.** Это самый очевидный и надёжный способ сравнения.
let userName = prompt("Your name?", "Alice");
let isTeaWanted = confirm("Do you want some tea?");
**Остальные сравнения `== < <= > >=` осуществляют числовое приведение типа:**
alert( "Visitor: " + userName );
alert( "Tea wanted: " + isTeaWanted );
```
More in: <info:uibasic>.
## Operators
JavaScript supports following operators:
Arithmetical
: Regular: `* + - /`, also `%` for the remainder and `**` for power of a number.
Binary plus `+` contatenates strings.
If any of the operands is a string -- the other one is converted to string too:
```js run
alert( '1' + 2 ); // '12', string
alert( 1 + '2' ); // '12', string
```
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.
Ternary
: The only operator with three parameters: `cond ? resultA : result B`
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:
```js run
alert( 0 == false ); // true
alert( true > 0 ); // true
```
Исключение -- сравнение двух строк (см. далее).
Values `null` and `undefined` are special: they equal `==` each other and don't equal anything else.
**Исключение: значения `null` и `undefined` ведут себя в сравнениях не как ноль.**
<ul>
<li>Они равны `null == undefined` друг другу и не равны ничему ещё. В частности, не равны нулю.
- В других сравнениях (кроме `===`) значение `null` преобразуется к нулю, а `undefined` -- становится `NaN` ("ошибка").
Greater/less comparisons compare strings character-by-character, other types are converted to a number.
Такое поведение может привести к неочевидным результатам, поэтому лучше всего использовать для сравнения с ними `===`. Оператор `==` тоже можно, если не хотите отличать `null` от `undefined`.
Others
: There are few others, like a comma operator.
Например, забавное следствие этих правил для `null`:
```js run no-beautify
alert( null > 0 ); // false, т.к. null преобразовано к 0
alert( null >= 0 ); // true, т.к. null преобразовано к 0
alert( null == 0 ); // false, в стандарте явно указано, что null равен лишь undefined
```
С точки зрения здравого смысла такое невозможно. Значение `null` не равно нулю и не больше, но при этом `null >= 0` возвращает `true`!
</li>
</ol>
<li>**Сравнение строк -- лексикографическое, символы сравниваются по своим unicode-кодам.**
Поэтому получается, что строчные буквы всегда больше, чем прописные:
```js run
alert( 'а' > 'Я' ); // true
```
</li>
</ul>
Подробнее: <info:operators>, <info:comparison>.
More in: <info:operators>, <info:comparison>.
## Логические операторы

View file

@ -0,0 +1,19 @@
Sure, it works, no problem.
The `const` only protects the variable itself from changing.
In other words, `user` stores a reference to the object. And it can't be changed. But the content of the object can.
```js run
const user = {
name: "John"
};
*!*
// works
user.name = "Pete";
*/!*
// error
user = 123;
```

View file

@ -0,0 +1,18 @@
importance: 5
---
# Constant objects?
Is it possible to change an object declared with `const`, how do you think?
```js
const user = {
name: "John"
};
*!*
// does it work?
user.name = "Pete";
*/!*
```

View file

@ -1,17 +1,13 @@
```js run no-beautify
function getNames(arr) {
return arr.map(item => item.name);
}
```js run
let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 28 };
let john = { name: "John", age: 25 }
let pete = { name: "Pete", age: 30 }
let mary = { name: "Mary", age: 28 }
let users = [ john, pete, mary ];
let arr = [ john, pete, mary ];
let names = users.map(item => item.name);
let names = getNames(arr);
alert( names ) // John, Pete, Mary
alert( names ); // John, Pete, Mary
```

View file

@ -2,21 +2,21 @@ importance: 5
---
# Sort objects
# Map to names
Write the function `getNames(users)` that gets an array of "user" objects with property `name` and returns an array of names.
You have an array of `user` objects, each one has `user.name`. Write the code that converts it into an array of names.
For instance:
```js no-beautify
let john = { name: "John", age: 25 }
let pete = { name: "Pete", age: 30 }
let mary = { name: "Mary", age: 28 }
let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 28 };
let arr = [ john, pete, mary ];
let users = [ john, pete, mary ];
let names = getNames(arr);
let names = /* ... your code */
alert( names ) // John, Pete, Mary
alert( names ); // John, Pete, Mary
```

View file

@ -0,0 +1,51 @@
```js run no-beautify
let john = { name: "John", surname: "Smith", id: 1 };
let pete = { name: "Pete", surname: "Hunt", id: 2 };
let mary = { name: "Mary", surname: "Key", id: 3 };
let users = [ john, pete, mary ];
*!*
let usersMapped = users.map(user => ({
fullName: `${user.name} ${user.surname}`,
id: user.id
}));
*/!*
/*
usersMapped = [
{ fullName: "John Smith", id: 1 },
{ fullName: "Pete Hunt", id: 2 },
{ fullName: "Mary Key", id: 3 }
]
*/
alert( usersMapped[0].id ) // 1
alert( usersMapped[0].fullName ) // John Smith
```
Please note that in for the arrow functions we need to use additional brackets.
We can't write like this:
```js
let usersMapped = users.map(user => *!*{*/!*
fullName: `${user.name} ${user.surname}`,
id: user.id
});
```
As we remember, there are two arrow functions: without body `value => expr` and with body `value => {...}`.
Here JavaScript would treat `{` as the start of function body, not the start of the object. The workaround is to wrap them in the "normal" brackets:
```js
let usersMapped = users.map(user => *!*({*/!*
fullName: `${user.name} ${user.surname}`,
id: user.id
});
```
Now fine.

View file

@ -0,0 +1,36 @@
importance: 5
---
# Map to objects
You have an array of `user` objects, each one has `name`, `surname` and `id`.
Write the code to create another array from it, of objects with `id` and `fullName`, where `fullName` is generated from `name` and `surname`.
For instance:
```js no-beautify
let john = { name: "John", surname: "Smith", id: 1 };
let pete = { name: "Pete", surname: "Hunt", id: 2 };
let mary = { name: "Mary", surname: "Key", id: 3 };
let users = [ john, pete, mary ];
*!*
let usersMapped = /* ... your code ... */
*/!*
/*
usersMapped = [
{ fullName: "John Smith", id: 1 },
{ fullName: "Pete Hunt", id: 2 },
{ fullName: "Mary Key", id: 3 }
]
*/
alert( usersMapped[0].id ) // 1
alert( usersMapped[0].fullName ) // John Smith
```
So, actually you need to map one array of objects to another. Try using `=>` here. There's a small catch.

View file

@ -114,6 +114,9 @@ Class definition sets `enumerable` flag to `false` for all methods in the `"prot
If there's no `constructor` in the `class` construct, then an empty function is generated, same as `constructor() {}`. So things still work the same way.
```
```smart header="Classes always `use strict`"
All code inside the class construct is automatically in the strict mode.
```
## Class Expression

View file

@ -3,7 +3,7 @@
This repository hosts the content of the JavaScript Tutorial, to be available on [https://javascript.info](https://javascript.info).
The backend is written using [io.js](https://iojs.org/en/index.html). It is in the separate repo: [https://github.com/iliakan/javascript-nodejs](https://github.com/iliakan/javascript-nodejs), here is the text only.
The backend is written using [io.js](https://iojs.org/en/index.html). It is in the separate repo: [https://github.com/iliakan/javascript-tutorial-server](https://github.com/iliakan/javascript-tutorial-server), here is the text only.
Please use this repository to file issues and suggest PRs for the text.