starting es6

This commit is contained in:
Ilya Kantor 2015-07-01 11:40:57 +03:00
parent 8ebc0b769f
commit b847d3173a
6 changed files with 215 additions and 3 deletions

View file

@ -0,0 +1,72 @@
# ES-2015 сейчас
[Стандарт ES-2015](http://www.ecma-international.org/publications/standards/Ecma-262.htm) был принят в июне 2015. Пока что большинство браузеров реализуют его частично, текущее состояние реализации различных возможностей можно посмотреть здесь: [](https://kangax.github.io/compat-table/es6/), поэтому в этом учебнике ему выделена отдельная секция.
Когда стандарт будет поддерживаться почти целиком везде, то весь учебник будет обновлён в соответствии с ним.
Пока же, чтобы писать код на ES-2015, есть следующие варианты.
## Конкретный движок JS
Самое простое -- это когда нужен один конкретный движок JS, например V8 (Chrome).
Тогда можно использовать только то, что поддерживается именно в нём. Заметим, что в V8 большинство возможностей ES-2015 поддерживаются только при включённом `use strict`.
При разработке на Node.JS обычно так и делают. Если же нужна кросс-браузерная поддержка, то этот вариант не подойдёт.
## Babel.JS
[Babel.JS](https://babeljs.io) -- это [транспайлер](https://en.wikipedia.org/wiki/Source-to-source_compiler), переписывающий код на ES-2015 в код на предыдущем стандарте ES5.
Он состоит из двух частей:
<ol>
<li>Собственно транспайлер, который переписывает код.</li>
<li>Полифилл, который добавляет методы `Array.from`, `String.prototype.repeat` и другие.</li>
</ol>
На странице [](https://babeljs.io/repl/) можно поэкспериментировать с транспайлером: слева вводится код в ES-2015, а справа появляется результат его преобразования в ES5.
Обычно Babel.JS работает на сервере в составе системы сборки JS-кода (например [webpack](http://webpack.github.io/) или [brunch](http://brunch.io/)) и автоматически переписывает весь код в ES5.
Настройка такой конвертации тривиальна, единственно -- нужно поднять саму систему сборки, а добавить к ней Babel легко, плагины есть к любой из них.
Если же хочется "поиграться", то можно использовать и браузерный вариант Babel.
Это выглядит так:
```html
<!--+ run -->
*!*
<!-- browser.js лежит на моём сервере, не надо брать с него -->
<script src="https://js.cx/babel-core/browser.min.js"></script>
*/!*
<script type="text/babel">
let arr = ["hello", 2]; // let
let [str, times] = arr; // деструктуризация
alert( str.repeat(times) ); // hellohello, метод repeat
</script>
```
Сверху подключается браузерный скрипт `browser.min.js` из пакета Babel. Он включает в себя полифилл и транспайлер. Далее он автоматически транслирует и выполняет скрипты с `type="text/babel"`.
Размер `browser.min.js` превышает 1 мегабайт, поэтому такое использование в production строго не рекомендуется.
# Примеры на этом сайте
На этом сайте запускаемые примеры гарантированно работают в [последнем Chrome](https://www.google.com/chrome/browser/canary.html), браузерный Babel не используется, при желании вы можете запустить их в любом браузере вместе с Babel, как показано выше.
Ещё раз заметим, что самая актуальная ситуация по поддержке современного стандарта браузерами отражена вот тут: [](https://kangax.github.io/compat-table/es6/).

View file

@ -0,0 +1,137 @@
# Переменные: let и const
В ES-2015 предусмотрены новые способы объявления переменных: через `let` и `const` вместо `var`.
Например:
```js
let a = 5;
```
## let
У объявлений `let` три основных отличия от `var`:
<ol>
<li>**Область видимости переменной `let` -- блок `{...}`.**
Как мы помним, переменная, объявленная через `var`, видна везде в функции. В старом стандарте минимальная "область видимости" -- функция.
Переменная, объявленная через `let`, видна только в рамках блока `{...}`, в котором объявлена.
Это, в частности, влияет на объявления внутри `if`, `while` или `for`.
Например, переменная через `var`:
```js
//+ run
'use strict';
var apples = 5;
if (true) {
var apples = 10;
alert(apples); // 10 (внутри блока)
}
alert(apples); // 10 (снаружи блока то же самое)
```
То же самое с `let`:
```js
//+ run
'use strict';
let apples = 5; // (*)
if (true) {
let apples = 10;
alert(apples); // 10 (внутри блока)
}
*!*
alert(apples); // 5 (снаружи блока значение не изменилось)
*/!*
```
Здесь, фактически, две независимые переменные `apples`, одна -- глобальная, вторая -- в блоке `if`.
Заметим, что если объявление `apples` в строке `(*)` закомментировать, то в последнем `alert` будет ошибка: переменная неопределена. Это потому что переменная `let` всегда видна именно в том блоке, где объявлена и не более.
</li>
<li>**Переменная `let` не видна до объявления.**
Как мы помним, переменные `var` существуют и до объявления. Они равны `undefined`:
```js
//+ run
'use strict';
alert(a); // undefined
var a = 5;
```
С переменными `let` всё проще. До объявления их вообще нет.
Такой доступ приведёт к ошибке:
```js
//+ run
'use strict';
*!*
alert(a); // ошибка, нет такой переменной
*/!*
let a = 5;
```
</li>
<li>**При использовании в цикле, для каждой итерации создаётся своя переменная.**
Объявление `let` позволяет легко решить классическую проблему с замыканиями, описанную в задаче [](/task/make-army).
```js
//+ run
'use strict';
function makeArmy() {
let shooters = [];
for (*!*let*/!* i = 0; i < 10; i++) {
shooters.push(function() {
alert( i ); // выводит свой номер
});
}
return shooters;
}
var army = makeArmy();
army[0](); // 0
army[5](); // 5
```
Если бы объявление было `var i`, то была бы одна переменная `i` на всю функцию, и вызовы в последних строках выводили бы `10` (подробнее -- см. задачу [](/task/make-army)).
Объявление `let i` создаёт для каждого повторения блока в цикле свою переменную.
</li>
</ol>
# const
По области видимости -- это то же самое, что `let`, но константа, нельзя менять:
```js
//+ run
'use strict';
const apple = 5;
apple = 10; // ошибка
```

View file

View file

@ -0,0 +1,4 @@
# Современные возможности ES-2015
Современный стандарт ES-2015 и его расширения для JavaScript.

View file

@ -114,7 +114,7 @@ for (var i = 0; i < 10; i++) {
Если использовать Named Function Expression, то имя жёстко привязывается к конкретной функции, и поэтому в коде выше `me.i` возвращает правильный `i`.
</li>
<li>**Другое, более продвинутое решение --- использовать дополнительную функцию для того, чтобы "поймать" текущее значение `i`**:
<li>**Другое, более продвинутое решение -- использовать дополнительную функцию для того, чтобы "поймать" текущее значение `i`**:
```js
//+ run

View file

@ -120,7 +120,6 @@ alert( counter() ); // 5
Этот трюк часто используется при разработке JavaScript-библиотек. Например, популярная библиотека [jQuery](http://jquery.com) предоставляет глобальную переменную с именем [jQuery](http://api.jquery.com/jQuery/) (доступна также под коротким именем `$`), которая с одной стороны является функцией и может вызываться как `jQuery(...)`, а с другой -- у неё есть различные методы, например `jQuery.type(123)` возвращает тип аргумента.
## Задачи на понимание замыканий
Далее вы найдёте различные задачи на понимание замыканий. Рекомендуется их сделать самостоятельно.