ES6とそれまでのJSでどう変わったかを簡単にまとめた

忘れやすいところだけ自分用にメモ。
間違ってるところがあれば指摘していただきたいですm(__)m

#変数宣言に関して

これまではvarで変数を宣言していた。
ちなみに、varをつけずに宣言すると全てグローバル変数とみなされる。

```js
hoge = 'Global';

function getValue() {
  hoge = 'Local';  //すでに宣言されている変数への再代入とみなされる
  return hoge;
}

console.log(getValue()); //=>Local
console.log(hoge);        //=>Local
```

こんなことが起こらないように、varは基本的につけておく。

ES6では、**let**と**const**が追加された。

- let : 変数の再宣言ができない、ブロックスコープ

```js
let x = 1;
x = 2;
console.log(x); // 2
let x = 3; // Identifier 'x' has already been declared
```

```js
if (true){
  let value = "hoge";
}
console.log(value); //error
```

これからは基本的にletを使用していくと思われる。

- const : 変数への再宣言と再代入ができない（定数）

```js
const value = "hoge";
value = "fuga"; //error
```

ちなみに以下は大丈夫。

```js
const ary = [1,2,3]
arr[0] = "hoge";
console.log(ary); //["hoge",2,3]
```
再代入は禁止だが、変更は可能。




#thisの挙動

これまでのことを以下にまとめる

###メソッド呼び出し
```js
var obj = {
  value: "hoge",
  show: function() {
    console.log(this.value); // thisは呼び出し元となるオブジェクト、objをさすのでobj.valueとなる
  }
}
obj.show(); // =>hoge
```

###関数呼び出し
```js
function hoge() {
  var value = "fuga"
  console.log(this.value) //thisはグローバルをさす
}
hoge() //undifined
```

###コンストラクタ呼び出し
```js
var hogeFunc = function() {
  // {}
  this.value1 = "ARA";
  this.value2 = "KAWA";
  this.hogeMethod = function() {
    return this.value1 + this.value2;
  }
  // return {}
}

var hoge = new hogeFunc();
console.log(hoge.hogeMethod()); //ARAKAWA
```
newでインスタンス化されると、thisはそのインスタンス自身をさす。
今回でいうとhoge。

ちなみに、以下はエラーが出る

```js
var hoge2 = hogeFunc();
console.log(hoge2.hogeMethod());
```
理由は呼び出した無名関数hogeFungにreturn文がないため。JSは通常、return文が明示的でなければ呼び出し元に**undifinded**が返る。
**new演算子の場合は、return文の存在に関わらず、オブジェクトのインスタンスが返却される**。

###アロー関数（es6）
無名関数の定義を簡潔に記述できる。

```js
let hoge = (val) => {
  console.log(val);
}

hoge("fuga");
```

ちなみに、引数が１つであれば（）は省略可能。

```js
let hoge = val => {
  console.log(val);
}
```

1行の処理だったら{}やreturnも不要。

アロー関数におけるthisに関しては、以下の記事がとても参考になりました。（あとで自分なりにまとめます）

[【JavaScript】アロー関数式を学ぶついでにthisも復習する話](http://qiita.com/mejileben/items/69e5facdb60781927929)


#クラス
これまでJSにClassという概念はなかった。クラスの代わりに、「プロトタイプ」を駆使してオブジェクト指向ライクな実装が可能であった。
まずはプロトタイプからみていく。

```js
let Human = function(name) {
  this.setName(name);
};

Human.prototype = {
  setName: function(name){ this.name = name; },
  getNmae: function(){ return "名前は" + this.name + "です"; },
}

let human1 = new Human("arakawa");
console.log(human1.getName()); //名前はarakawaです
```
オブジェクトをインスタンス化した先のオブジェクトに引き継ぐことができる。
この辺をもっと詳しく知りたい方は以下とか参考になると思います。
[図で理解するJavaScriptのプロトタイプチェーン](http://qiita.com/howdy39/items/35729490b024ca295d6c)

これをES6で追加されたクラスを用いて書き直してみる。

```js
class Human {
  constructor(name){
    this.name = name;
  }

  set name(name) {
    this._name = name;
  }

  get name() {
    return this._name;
  }

  getName() {
    console.log(`名前は${this.name}です`);
  }

}

let human1 = new Human("arakawa");
human1.getName();
```

おなじみのコンストラクタを使用できます。
また、クラスではthisに追加されたプロパティがメンバ変数となります。メンバ変数の参照もthisを介します。
getName()はメソッドです。staticをつけると静的メソッドになります。
この辺は他のプログラミング言語を使っていれば、おなじみですね。

※get / setはこの場合いらないですが、プロトタイプで書いたものに似せて書くため記述しました。
※``で囲まれたところは下記で紹介します



以下からは、ES6から追加されたことだけを紹介。

#テンプレート文字列
バッククォートで囲むことで、改行をそのままかけたり、変数を文字列に埋め込める。

```js
let name = "arakawa";
let word = `My name is ${name}`;
```

他にもfor...ofや、引数にデフォルト値を持たせたり、可長変引数とかいろいろできるようになった。
便利ですね🎉


今後も追記していく予定です。