1. esehara@github

    No comment

    esehara@github
Changes in body
Source | HTML | Preview
@@ -1,295 +1,299 @@
# はじめに
だいたい昔からJavaScriptを触ってたりすると、`ECMA-262 Edition 5.1`に慣れきってしまって、もうそれでいいじゃんという雰囲気になったりする。しかし、既に`5.1`だけを使うのは老害なのではないか(はっきりとは断言しない)という危機感によって、今回は`ECMAScript 2015`を勉強しようという話になった。
---
# なぜ`5.1`は老害なのか
[<img width="1638" alt="01.png" src="https://qiita-image-store.s3.amazonaws.com/0/1036/83b57021-afb7-7289-8b5c-722455be39af.png">](https://babeljs.io/)
まず最初にBabelによって、`ECMA Script2015`を無理矢理`5.1`にすることが可能になった。その後、段々と対応ブラウザが増えつつあり、今後おきかわる可能性がある。これはプロダクトの都合。プログラマーとしては格段に書きやすくなった。
---
# 参考資料
![book.jpg](https://qiita-image-store.s3.amazonaws.com/0/1036/359ca9b7-9820-75e2-065d-f1e6041ccc19.jpeg)
- [Amazon](https://www.amazon.co.jp/dp/477418411X/esehara-22)
2016年11月に出版されたので、とにかく`ECMAScript 2015`の対応は早かった。本の内容も、めくってみた感じだと、それほど悪くない印象がある。
---
# 参考資料2
## [はてな教科書 JavaScript 編](https://hatena.github.io/Hatena-Textbook-JavaScript/)
無料で見れる研修テキスト。はてななので、それほど間違っていないことを期待したい。
---
当然、全てを網羅できるわけではないので、主要トピックだけを追いかけていく。今回は、関数やクラス以外の部分について勉強する。
---
# 地道に代入からやっていく(1)
分割代入ができるように!!
```js
var [a, b] = [1, 2];
```
※ただし、間違えてこう書いちゃうとダウト
```js
var a, b = [1, 2]
```
この場合だと`b`だけに代入されるので困ったことになる。この機能は、スワップもしてくれるので楽。
```js
var [a, b] = [1, 2];
var [a, b] = [b, a];
console.log(a, b);
```
---
# 地道に代入からやっていく(2)
オブジェクトも分割代入できる
```js
let {firstname, lastname} = {firstname: "esehara", lastname: "shigeo"}
```
こういう代入は、ライブラリを実際に使っていくときにでくわしたりすることがある。
---
# 地道に`let`からやっていく
だいたいの変数宣言は`var`から`let`に起きかえることが可能。
理由としては、殆どの変数宣言はスコープ内で使われるものでしかなく、`let`はスコープから脱出すると、その変数が解放される。以下は「はてな」の教科書から取ってきた実例。
```js
if (true) { let x = 100; }
console.log(x);
// ReferenceError: x is not defined
```
余程スコープを横断したいときには`var`を使うと便利ではあるんだが……
あと地味に重要な点としては、`let`を使うと、同じ変数が宣言できなくなる。このことによって、宣言しようとした変数をかぶらせない、といった配慮が可能になるのだが、そもそも**二重に宣言してしまいそうになるコードを書くほうが悪い**ということになる。
---
# 地道に`const`からやっていく
`const`は見た目の通り、定数を宣言するときに使う。この場合の定数とは「再代入不可能」ということである。ただし、その変数に対して再代入を禁止するという意味であって、**代入された値の不変性を保証するものではない**。ここは勘違いされやすいが、再代入が不可能であるということは、必ずしもImmutableであることを意味してはいない。
```js
const hoge = [1, 2, 3];
hoge[0] = "foobar";
console.log(hoge);
```
通常、この手の配列はバグを生みやすい。**配列は地獄だ。**
---
## 配列あるある
```js
x = [1, 2, 3];
y = x;
y[0] = 9;
console.log(x);
```
詳しい解説は[値渡しと参照渡しについてあらためてまとめてみる](http://qiita.com/migi/items/3417c2de685c368faab1)を読みましょう。
---
# その他の罠
ユニコードにも[サロゲートペア文字](http://qiita.com/YusukeHirao/items/2f0fb8d5bbb981101be0)というのがある。いわゆるUnicodeの文字列が不足するに従って利用するバイト数を増やした結果、日本語の表示上では2文字であるものが、3文字として認識されてしまうような状態のことである。その一例として:
```js
console.log('😇サロゲートペア文字最悪っぽい'.match(/^.サロゲートペア/g));
```
とするとnullになる。それは当然絵文字の部分が2文字になっているせいだからである。当然、これを解決しないとまずいわけで、ECMAScript2015では:
```js
console.log('😇サロゲートペア文字最悪っぽい'.match(/^.サロゲートペア/gu));
```
`g`というオプションを付けられるところに`u`を付けることで回避することができるようになった。
---
# 地味に便利になったもの
- 2進法リテラル、8進法リテラル(正直あったんだね……という)
- **テンプレート文字列**
---
# テンプレート文字列
以前だったら
```js
let greeting = "Hello, " + name + " !";
```
`+`がうっとおしかったのが:
```js
let greeting = `Hello, ${name} !
How are you?`;
```
「`」を使うことによって便利になりました。複数行も書けるので便利〜
---
# for .. of .. 構文
```js
for(value of [1, 2, 3]) { console.log(value) };
```
特に言うことはなし。ただし`Array`のメソッドである`forEach`メソッドと若干被っているようにも見える。
また、実際に使えない例もある。ハマった例としては、`getElementsById`などのメソッドで`Document`を取得するさいに、`forEach`や、`for .. of ..`は使えない。おそらくイテレーターのインターフェイスが存在していないからだろう。
### 参考資料
- [JavaScript の イテレータ を極める!](http://qiita.com/kura07/items/cf168a7ea20e8c2554c6)
---
## スプレット演算子
イテレーターの話題が出てきたので、ついでにスプレット演算子。こいつは`Array`の中でイテレーターを展開してくれるという超便利演算子。
```js
let a = [1, 2, 3];
let b = [...a, 4];
console.log(b);
```
このように、イテレーターが代入された変数の前に「...」を付けることによって、展開が可能になる。ただし、こいつが使えるようになるのは配列の中のようで、`Unxepected Token`になる。
---
### Advanced Topic
とすると、オブジェクトでも同様の展開式が欲しいという気持ちになることが多いかもしれないが、現状、オブジェクトに対しての展開式が`ES2015`の仕様として策定さていることはない。しかし、例えば[Redux.jsの例からひっぱって来ると](https://github.com/reactjs/redux/blob/85e2368ea9ff9b308fc873921ddf41929638f130/examples/real-world/src/reducers/paginate.js):
```js
// ...
switch (action.type) {
case requestType:
return {
...state,
isFetching: true
}
case successType:
return {
...state,
isFetching: false,
ids: union(state.ids, action.response.result),
nextPageUrl: action.response.nextPageUrl,
pageCount: state.pageCount + 1
}
case failureType:
return {
...state,
isFetching: false
}
default:
return state
}
// ...
```
謎の`{...}`みたいな記法が使われているのがわかる。これは[公式の解説](http://redux.js.org/docs/recipes/UsingObjectSpreadOperator.html)の通り、提案の第二ステージくらいでまだ採用には遠いので、[Babelの拡張プラグイン使いましょう](http://babeljs.io/docs/plugins/transform-object-rest-spread/)ということがさらっと書かれている。とりあえずオブジェクト展開は現状できなくて、先走っている拡張であるということは覚えておいて損は無いかと。
---
# Symbol
いわゆるユニークなオブジェクトを返す。ユニークなので、これで生成されたオブジェクト同士を比較しても`true`にはならない。使い方としては、マジックナンバーを避ける定数の例が一般的。ただ、[あまり必要性もないのではないか](http://qiita.com/naruto/items/312adeb6145eb6221be7)とも言われている不憫な子。
---
# Map
一般的にJavaScriptでは、オブジェクトリテラルで連想配列を代用していたため、下のようなことが起こる:
```js
let my = {name: "esehara"};
console.log(my.name);
console.log(my["name"]);
```
そのため、いわゆるメソッドと連想配列的なアクセスがごっちゃになって、データ構造を作るときに面倒になる。そこで、`Map`を使うことで、キーと値が対応するような、一般的な「連想配列」を作ることが可能になった。`Map`の初期化はちょっと面倒で、次のように使うことになる:
```js
let name = new Map([["name", "esehara"]])
console.log(name.get("name"))
```
このことによって、アクセスの方法が一意になるため、便利。また、いわゆるキーリストなどの習得も楽なので、データの使いかたによっては、こっちのほうが便利である。
---
# Set
`Set`という名前から察することができるように、「擬似的な集合」を作ることができる。普通、集合は要素の重複しないようにする。
---
# 特別編: Object
---
## `is(v1, v2)`というメソッドが追加された
オブジェクト同士が同一であるかどうかを判定する。例えば、値自体は一緒だが、オブジェクトが違う例として、次のような例が挙げられる:
```js
Object.is([1], [1]);
```
この場合、オブジェクトが違うので`false`になるのだけれども、しかし次の場合は`true`になる。
```js
let a = [1];
let b = a;
Object.is(a, b);
```
これによって、オブジェクト同士が本当に同じものなのかを確かめることが可能になった。
---
## `assign(target, source)`というメソッドが追加された
`Object.assign(target, source...)`みたいな形式で書くことが可能。これはオブジェクト同士をマージすることができる。
```js
Object.assign({a: 1, b: 2}, {b: "foo", c: "bar"})
```
このとき、二つのオブジェクトが合体したオブジェクトが返ってくるわけども、最初の引数に渡されたオブジェクトも同様に変更されるようになるので、もし最初の引数に対して副作用を発生させたくなければ、空のオブジェクトを渡すとよい。
+
+---
+
+[続きはこちら](http://qiita.com/esehara@github/items/901b91c98a7936127321)