【JavaScript】初心者向けメモ

##JavaScript初心者向け参考記事

[2017年から始めるjavascript勉強ノート](https://qiita.com/ne-peer/items/6acd5493eeadae9ab759)
[ES2015(ES6) 入門](https://qiita.com/soarflat/items/b251caf9cb59b72beb9b)
[Google流JavaScriptにおけるクラス定義の実現方法(ES6以前)](https://www.yunabe.jp/docs/javascript_class_in_google.html)
※引用｛ES6でクラスが導入されほとんどのブラウザがサポートしている2019年現在、ここで書かれている手法を直接使用することはないでしょう。 ｝
[[JavaScript]　猿でもわかるクロージャ超入門　まとめ](http://dqn.sakusakutto.jp/2009/01/javascript_5.html)

##備忘録
・ES5までしかIE11が対応していない。
・ES2015以降は、トランスパイラー(babel等)でコンパイルして利用可能。


##備忘録（テンプレートリテラル）
文字列の中で「${変数}」とすることで、文字列の中に定数や変数を含めることができます。この時、文字列全体をバッククォーテーション（`）で囲む必要があります。

``` javascript:templateLiteral.js
const hoge = "山内";
console.log(`私の名前は${hoge}です。`);
結果表示：　私の名前は山内です。
```

##備忘録（オブジェクト）
キー／バリューセットの事であるが、文献により呼称がバラバラであり混乱する。
オブジェクト、連想配列、Mapオブジェクト...。


##ES2015（ES6）以降の勉強対象抜粋
@tsin1rouさんの記事より抜粋させていただきました。
「[JavaScriptの概念たち (前編)](https://qiita.com/tsin1rou/items/90576b6c00b895478610) 」「[JavaScriptの概念たち (後編)](https://qiita.com/tsin1rou/items/b30885b189a8ec596c72) 」

１．varは現在では不要。これからは、letとconstを使用します。
２．関数定義：　const 関数名 = (引数argument)=>{ 処理 }と書きます。

```javascript:newFunctionDifinition.js
const hoge = (arg) => {
  return arg * 2;
};
// 上のように`return`の行しかないような関数は省略して`(引数)=>(返り値)`と書けます。
const hoge = (arg) => (arg * 2);
const hoge = arg => arg * 2; // さらに()を省略することも可能
```

３．即時関数は、現在では不要。
『即時関数とは関数を定義してすぐその場で実行する関数のことです。過去、グローバル変数の競合を防ぐために使用していた。
かつてJavaScriptにはvarという変数宣言がありました。これはlet、constとは異なりブロックスコープではなくfunctionスコープだったため、varで宣言した変数をローカル化するにはfunctionで囲わなければいけませんでした。』

```javascript:oldFunctionDifinition.js
var hogehoge = 'hoge';

(function() {
  var hogehoge = 'fuga';
  console.log(hogehoge); // -> "fuga"
})();

console.log(hogehoge); // -> "hoge"
```
４．Numberへの変換

```javascript:toNumber.js
Number(null)           // 0
Number(undefined)      // NaN
Number(true)           // 1
Number(false)          // 0
Number(" 12 ")         // 12
Number("-12.34")       // -12.34
Number("\n")           // 0
Number(" 12s ")        // NaN
Number(123)            // 123
```

５．==と===の違い

結論から言うと可能な限り`===`を使うべきです。
`==`は暗黙の型変換を行うので意図せぬ挙動の原因となります。
`===`は同じ型・同じ値の場合のみ`true`を返すのでより厳密な比較ができます。

```javascript:doubleEqualTrippleEqual.js
false == 0              // true
false === 0             // false
0 == ""                 // true
0 === ""                // false
```

６．スコープ
`var`を無視すればスコープについては非常に簡単で、`{}`で囲まれたブロックスコープが適用されます。`if`でも`for`でも関数でも、`{}`で囲まれてさえいればスコープが発生すると考えればOKです。

```javascript:scope.js
const hoge = 'hogehoge';
{
  console.log(hoge); // Uncaught ReferenceError: hoge is not defined
  const hoge = 'fugafuga';
  console.log(hoge); // -> "fugafuga"
}
console.log(hoge); // -> "hogehoge"
```

上記のコード3行目でエラーが発生するのに違和感を覚える人も少なくないと思います。通常の上から解釈されていく言語なら`hoge`がそのスコープ内で未定義だった場合、上のスコープのものが自動で使用されるのが自然でしょう。もちろんJavaScriptでも基本的には上のスコープを見にいくのですが、同名の変数が同じスコープで定義されていると代わりにエラーが出ます。

７．クロージャー
JavaScriptでは、関数が外側のスコープにある変数への参照を保持できるようになっています。この性質のことを「クロージャー」と呼び、これを利用すると関数にあたかも状態を持つかのような挙動をさせることができます。

```javascript:closure.js
const createCounter = () => {
  let cnt = 0;
  return {
    inc: () => ++cnt
  }
};

const counter = createCounter();

console.log(counter.inc()); // -> 1
console.log(counter.inc()); // -> 2

// 当然ですが、counterはただの関数です。cntにはアクセスできません。
console.log(cnt); // -> ReferenceError
console.log(counter.cnt); // -> undefined
```