2017年から始めるjavascript勉強ノート


[次回 - 2017年から始めるjavascript勉強ノート2(関数型プログラミング)](http://qiita.com/ne-peer/items/564f485a671b5fedabc6)

## 勉強を始める前に

### Javascriptについての勝手なイメージ
Javascriptといえば一昔前は単体では使用せず、メイン処理を行うサーバサイドの言語と組み合わせて使用する補助的な位置づけの言語というイメージが強かった。しかし今やあらゆるイケてるページ（[SPA: Single Page Application](http://qiita.com/takanorip/items/82f0c70ebc81e9246c7a)、ページが遷移しないような作りのWebアプリケーション）で使用されており、ウェブアプリケーションなどを開発するために非常に有効な言語となった。また最近ではiOSやAndroidアプリケーションすらも [Javascriptで書けてしまう](http://animane.hatenablog.com/entry/2016/07/24/181833) 。ぜひ書けるようになりたい。

## いろいろ調べてみた

### 参考記事
[Qiita: JavaScriptことはじめ - まずはプログラミング言語の選択から](http://qiita.com/Kaoru_Yamamoto/items/37360ba30ab196f5f7e3)

### 記事を読んで
* Javascriptバージョンツリー: `ECMAScript 1 -> 2 -> 3 -> 5 -> 5.1 -> (6) ECMAScript 2015 -> 2016 -> 2017`
* ECMAScript 2015でガッツリ変わったので、それ以前のJSの知識ではもはやついていけないっぽい。[ES2015で変わったところ](http://qiita.com/soarflat/items/b251caf9cb59b72beb9b)
* Javascriptという言語はウェブブラウザ側が解析する能力を持っているので、サーバへインストールしたりコンパイルする必要はない。
* ということはバージョンアップを意識しなくてもウェブブラウザが最新の仕様で動かしてくれるってことか。
* バックエンドで動かしたいときにWebブラウザがないと動かせないから `Node.js` がいるのか。
* 逆に最新のJS使用に則っていないブラウザで動作させるには、 **トランスパイラ** と呼ばれるものを通せば新仕様で記述したソースを旧仕様に則ったコードに変換してくれる。これがよく聞く `Babel` ってやつ。
* 「**AltJS**」..素のJSでは書けない型指定などを行うためのJavascriptの拡張言語みたいなもの。参考記事には _JavaScriptの代替言語_ と説明されている。 `TypeScript, CoffeeScript, Dart ..etc`。
* [AltJSの選び方](http://qiita.com/mizchi/items/c5f101cfab8fd456ca20)
* ReactやAngularはフレームワーク（後述）。
* AngularではTypeScriptを推してる。
* `ECMAScript 2015として記述したコードは原則TypeScriptとしても実行可能です。` 、ありがたい。
* ECMAScript（エクマスクリプト）と読む。

### フレームワーク
* 言わずと知れた `jQuery` はフレームワークに分類されるらしい。
* `React` 軽量なフレームワーク、 `AngularJS, Meteor` とかはフルスタック。
<img width="400" alt="20150320133304.png" src="https://qiita-image-store.s3.amazonaws.com/0/167943/b1afd2fc-d5bf-845a-3c83-9de02ac7cbc5.png">  

画像出典: [paiza開発日誌](http://paiza.hatenablog.com/entry/2015/03/11/Backbone_JS%E3%81%8B%E3%82%89Angular2%E3%81%BE%E3%81%A7%E3%80%81%E5%85%A89%E5%A4%A7JavaScript%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%92%E6%9B%B8%E3%81%8D%E6%AF%94%E3%81%B9)


## 書いてみる

参考:
1. [ES2015(ES6) 入門](http://qiita.com/soarflat/items/b251caf9cb59b72beb9b)
2. [ES6 チートシート](http://postd.cc/es6-cheatsheet/#var-versus-let--const)

### 動作確認環境
↓で実行するとエラー箇所とか教えてくれるのでとても親切でした。
[BABELのオンラインエディタ](https://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Ces2016%2Ces2017&targets=&browsers=&builtIns=false&code=)

### コーディングスタイル
大事そうなの羅列

* 基本的なインデントはスペース 2 つ。タブを使ってはいけません。
* ファイルの最後には改行してください。（特に emacs ユーザに当てはまります。）
* 変数はcamelCase
* 定数はUPPER_CASE
* 引数（パラメータ名）は a という文字から始まるようにしてください。  
　　例: `function example(aHikisu)` →ほんとに？  
* プライベートメンバは_を先頭につける

参考:
1. [いろいろなコーディングスタイルまとめ](http://met.hanatoweb.jp/archives/466/)
2. [Mozilla](https://developer.mozilla.org/ja/docs/JavaScript_style_guide)
3. [ESLint](http://eslint.org/)でコーディングスタイルチェックを自動で行えるらしい。

### 変数宣言と比較とダンプ

```js
/**
 * 変数宣言。"var"はもはや使わない、"let"で宣言したら同じ名前の変数を宣言できなくなる。
 * 文字列の記述はシングルクォートでもダブルクォートでもよい。""で囲っても(PHPのように)変数の値は展開されない。完全同義。
 * 基本、末尾にセミコロンが必要。
 */
let name = 'kurosawa';

// 定数、上書きと再宣言不可。
const GREETING = 'Hello!';

/**
 * かんたんなif文
 * javascriptの比較演算子もPHPと同じく"=="が緩やかな比較、"==="が厳密な比較らしい。
 */
if (name === 'kurosawa') {
    // ダンプは"console.log()"を使う
    // 文字列結合は"+"
    console.log(GREETING + ' ' + name + '.');
}
```

出力結果:

```
Hello! kurosawa.
```

* [JavaScriptのシングルクォーテーションとダブルクォーテーション](http://qiita.com/niusounds/items/f21a28e862a68a098ea7)

### クロージャ(無名関数)とループ

```js
/**
 * 無名関数。ES2015からアローで定義できるようになった。
 *
 * ↓古い書き方
 * var dump = function (message) {
 *    console.log(message);
 * };
 */
const dump = (message) => {
    console.log(message);
};

// 配列の宣言。PHPとほぼ同じ。
let list = ['dia', 'ruby', 'yohane'];

// 配列のループ(foreach)
list.forEach(dump);
```

出力結果:

```
dia
ruby
yohane
```

参考: [Qiita: [JavaScript]クラス、関数、オブジェクト](http://qiita.com/maccotsan/items/45b348d4eb52f473b0e3)

### Javascript伝家の宝刀 "this"
ワタシハJavascriptノ"this"チョットニガテ

```js
let person = {
    'name': 'dia kurosawa',
    'selfIntroduction': function() {
        console.log('My name is ' + this.name);
    }
};

person.selfIntroduction(); // My name is dia kurosawa
```

* これくらいならなんとかわかる。  
  
参考: [Qiita: JavaScriptの「this」は「4種類」？？](http://qiita.com/takeharu/items/9935ce476a17d6258e27)

### 引数のデフォルト

```js
// デフォルトを設定できる
function say(message = 'hello') {
    console.log(message);
}

say();         // hello
say("ohayou"); // ohayou
```

### クラス

```js
// 親クラスを定義
class Person {
    constructor(name) {
        this.name = name;
    }
    
    getName() {
        return this.name;
    }
    
    sayHello() {
        console.log("Hello, I'm " + this.getName());   
    }
}

// クラスの継承
class Dia extends Person {
    constructor() {
        // コンストラクタのオーバーライドはこう呼ぶ（たぶん）
        super('Dia Kurosawa');
    }
    
    sayDia() {
        // 親クラスの関数はsuperで呼ぶ
        console.log(super.getName() + ' desuwa!');
    }
}

// PHPと同じく使うときは"new"
let dia = new Dia();
dia.sayHello(); // Hello, I'm Dia Kurosawa
dia.sayDia();   // Dia Kurosawa desuwa!
```

* 親コンストラクタを呼ぶときだけ罠があるので注意。

参考: [Qiita: ES2015新機能: JavaScriptのclassとmethod](http://qiita.com/niisan-tokyo/items/83582bc0646239cf6cb8)

### 配列とfor文

```js
// 下記は実行出来ない。PHPのようにキーを指定するのはできないようだ。
// このような形でデータを持ちたい場合はオブジェクトを使う。（後述）
// let invalidList = ['ruby' => 15];

// シンプルな配列
let nameList = ['dia', 'ruby', 'yohane'];

// 普通のfor
for (let num = 0; num < 5; num++) {
    console.log(num);
}

// for...ofは配列の値(要素)を処理できる
for (const val of nameList) {
    console.log(val);
}

// for...inは配列のkey(添字)を処理できる
for (const key in nameList) {
    console.log(key);
}

/**
0
1
2
3
4
"dia"
"ruby"
"yohane"
"0"
"1"
"2"
 */
```

### オブジェクトと配列の組み合わせ（連想配列）
#### 配列とオブジェクトのアクセス方法の違い

```js
let array = ['dia', 'ruby'];
console.log(array[0]); // dia
console.log(array[1]); // ruby
// array.0 はできない

let object = {name:'dia', age:'17'};
console.log(object.name); // dia
console.log(object.age);  // 17
// object['name'] はできる
```

#### よく使う連想配列

```js
let ageList2 = {
  dia: '17',
  you: '16',
  ruby: '15'
};

for (const key in ageList2) {
  console.log('name=' + key + ' age=' + ageList2[key]);
}

/**
"name=dia age=17"
"name=you age=16"
"name=ruby age=15"
 */
```

#### オブジェクトの配列

```js
let ageList = [
  { name:'dia', age:'17' },
  { name:'you', age:'16' },
  { name:'ruby', age:'15' },
];

for (const person of ageList) {
  console.log('name=' + person.name + ' age=' + person.age);
}

/**
"name=dia age=17"
"name=you age=16"
"name=ruby age=15"
 */
```

* PHPのように配列の添字を文字列とかに指定するのはできないようだ。添字を指定したい場合はオブジェクトを使う。

参考:
1. [Qiita: 【JavaScript】連想配列の指定した中身を取り出すまとめ](http://qiita.com/glaytomohiko/items/80cca9e5457d868b1ba2)
2. [細かい話: JavaScriptの連想配列（ハッシュ）はArrayオブジェクトでも作成できる！？](http://blog.asial.co.jp/611)

### スプレット演算子 `...`

```js
// 可変長引数（レストパラメータ）
function test1(...list) {
  console.log(list);    // Array ['dia', 'ruby', 'yohane']
  console.log(list[0]); // 'dia'
}
test1('dia', 'ruby', 'yohane'); 

// 配列展開
let list = ['dia', 'ruby', 'yohane'];
console.log(...list); // "dia" "ruby" "yohane"
console.log(list);    // Array ["dia" "ruby" "yohane"]
```

* 馴染みない挙動で非常にわかりづらい。知らないと今後ソースを追えなくなりそう。実装されて新しいものだし、そんなに頻繁に使うものではない･･･と願いたい。

### 変数展開

```js
let name = 'Dia';

// バッククォートで囲み、変数を${}で囲むと展開される
console.log(`Kurosawa ${name}`); // Kurosawa Dia
```

### ふしぎなコードに備える
事前に目を通して置くと、びっくりせず済みそうなパターンが載ってました。
[JavaScriptを読んでて「なにこれ！？」と思うけれど調べられない記法8選。](http://qiita.com/ukiuni@github/items/5f3d8620187905aea3d4)

### その他思ったこと
* 参考にした記事のほとんどではletではなくconstを使っていた。なるべくconstを使ったほうが良いのだろうか。なるべくconstで定義して、代入が必要になったときにletに変えていくスタンスが読みやすいコードになりそう。

## まとめ
今回はひとまず基本的な構文を学んでみた。これでなんとか他人のソースを読んで、最悪流れを追えなくてもどこで何をしているかくらいは理解できるようになったと思う。今後はもっと関数型言語についての知識を深めていく必要があると思われる。

[次回 - 2017年から始めるjavascript勉強ノート2(関数型プログラミング)](http://qiita.com/ne-peer/items/564f485a671b5fedabc6)