Vue.jsのガイドのサンプルコードで使われているJavaScriptの文法 - はじめに

# はじめに
最近、Vue.jsに入門しました。
私はPythonやJavaなどのプログラミング言語はそれなり触ったことがありますが、JavaScriptはあまり触ったことがありませんでした。
Vue.jsは優れたフレームワークなので、JavaScriptに対する何となくの知識でも、フレームワークをそれなりに扱うことは可能だと思います。
しかし、せっかくなので、JavaScriptの文法にも真面目に学んでみようと思い、[はじめに - Vue.js](https://jp.vuejs.org/v2/guide/index.html) のJavaScriptのサンプルコードについて、JavaScriptの文法でどう説明されるのかを調べてまとめました。
あくまで、JavaScriptの文法に焦点を当てており、この記事ではVue.jsについての説明はほとんどないです。
他のプログラミング言語はやったことあるけど、JavaScriptはあまりやったことがない、という人向けの内容です。

以降のセクションは、[はじめに - Vue.js](https://jp.vuejs.org/v2/guide/index.html)のセクションに対応しています。

# 宣言的レンダリング
[はじめに - Vue.js 宣言的レンダリング](https://jp.vuejs.org/v2/guide/#宣言的レンダリング) 

```javascript
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})
```

先頭から読み解いてみます。

## 変数宣言
```javascript
var app = 
```

`app` という変数を宣言し、 `=` の右辺の値で初期化するという意味です。

* `var` で宣言した変数はグローバル変数となります
    * [var - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/var)
* ちなみに、変数を宣言する方法は他にもあります
  * [let - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/let): ローカル変数の宣言
  * [const - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/const): 定数の宣言

## 型からオブジェクト生成
```javascript
new Vue(
)
```
`Vue` という名前の型のオブジェクトを生成するという意味です。
`Vue` という名前の型は（当然ですが） `Vue.js` で定義されています。
括弧の中はコンストラクタの引数を指定します。今回だと、オブジェクト（後述）が指定されています。

* [new - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/new)

## オブジェクトリテラル表記法でオブジェクト生成
```javascript
{
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
}
```

`{}` はオブジェクト（連想配列）を生成する構文です。 **オブジェクトリテラル表記法** と呼ばれます。
JSONでも馴染みは深いと思います（文法は少し異なります）。
今回だと、 `el` キーに `#app` という文字列が、 `data` というキーに `{message: 'Hello Vue!'}` という
オブジェクト（オブジェクトがネストされていますね）がマッピングされているオブジェクトです。

* [Object - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object)
* JavaScriptでは、文字列を `'#app'` とも `"#app"` 書けます。どちらの表現にも差はないようです
    * [String - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String)
* [オブジェクトリテラル表記法とJSONの違い](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Object_initializer#オブジェクトリテラル表記法_vs_JSON)

## Vueインスタンス生成のまとめ
* `app` というグローバル変数を宣言し、その値にVueという名前の型のオブジェクトを代入している
* Vue型のオブジェクトは以下のオブジェクト（連想配列）を引数としてコンストラクトされる
    * キー名: `el`, 値: 文字列 `#app`
    * キー名: `data`, 値: オブジェクト `{message: 'Hello Vue!'}`

# 条件分岐とループ
[はじめに - Vue.js 条件分岐とループ](https://jp.vuejs.org/v2/guide/index.html#条件分岐とループ)

条件分岐

```javascript
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})
```

ループ

```javascript
var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: 'Learn JavaScript' },
      { text: 'Learn Vue' },
      { text: 'Build something awesome' }
    ]
  }
})
```


使用されているJavaScriptの文法は、宣言的レンダリングとほぼ同じです。
以下のみ説明します。

* 真偽値: 条件分岐のコードの `seen` キーにマッピングされている値です
* 配列: ループのコードの `todos` キーにマッピングされている値です

## 真偽値
```javascript
true
```

真偽値とは、（多くの他のプログラミング言語と同じで、）真を表す `true` か偽を表す `false` の値のみ取れる論理データ型です。
`if` 文や `for` などのループの継続条件の判定式に用いられます。
Vue.jsでは、HTMLタグの属性 `v-if` の値に真偽値を指定することで、要素を挿入するか否かを決定するのに使えます。

* [Boolean - 用語集 | MDN](https://developer.mozilla.org/ja/docs/Glossary/Boolean)

## 配列
```javascript
[
  { text: 'Learn JavaScript' },
  { text: 'Learn Vue' },
  { text: 'Build something awesome' }
]
```
配列とは、リスト構造のコレクションです。配列のインデックスは0から始まります。オブジェクト同様、JSONでも馴染みが深いと思います。
ちなみに空の配列は `[]` で作成できます。

* [Array - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array)

# ユーザー入力の制御
[はじめに - Vue.js ユーザー入力の制御](https://jp.vuejs.org/v2/guide/index.html#ユーザー入力の制御)

```javascript
var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
```

以下について説明します。

* 関数: `reverseMessage` キーにマッピングされている値です
* 関数の `this` キーワード: 関数内の `this.messsage` の `this` です

## 関数
```javascript
function () {
}
```

関数とは、JavaScriptの文の集まりです。純粋である必要はありません。
構文的に関数を定義する方法と関数式によって関数を定義する方法があります。
今回は関数式により定義されています。
関数式は式により関数を定義できるので、オブジェクトの値に関数を指定することの多いVue.jsでは頻繁にお目にかかります。

もちろん、他の言語と同様に、関数は引数を受け取ることも可能です。
以下は二つの引数 `x`, `y` を受け取り、それらの和を返す関数です（関数は値を返すこともでき、それには `return` 文を用います）。

```javascript
function (x, y) {
  return x + y
}
```

* [関数 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Functions)

## 関数の `this` キーワード
```javascript
this.message = this.message.split('').reverse().join('')
```

`this` キーワードはいろいろと複雑なのですが、オブジェクトが持つ関数においては、その関数を持つオブジェクトを指すキーワードとなります。
つまり、 `Vue` インスタンスのインスタンスメソッドおいては、（Javaなどと同様に）自身の `Vue` インスタンスを指すキーワードと思えばよいです。
今回、 `Vue` インスタンスは `app5` なので、 関数内の `this.message` はグローバルな視点から見ると、 `app5.message` を表していることになります。

* [this - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/this)
    * とくに、[オブジェクトのメソッドとして](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/this#オブジェクトのメソッドとして)が参考になります
* ちなみに、 `split`　はStringのメソッド、 `reverse`, `join` はArrayのメソッドです
    * [String.prototype.split() | JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split)
    * [Array.prototype.reverse() | JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)
    * [Array.prototype.join() | JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/join)

# コンポーネントによる構成
[はじめに - Vue.js コンポーネントによる構成](https://jp.vuejs.org/v2/guide/#コンポーネントによる構成)

```javascript
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

var app7 = new Vue({
  el: '#app-7',
  data: {
    groceryList: [
      { id: 0, text: 'Vegetables' },
      { id: 1, text: 'Cheese' },
      { id: 2, text: 'Whatever else humans are supposed to eat' }
    ]
  }
})
```

これまでに紹介した文法のみで構成されています。

# おわりに
`this` キーワードが少し難しいですが、それほど複雑な文法は出てきていないですね。
次回は、[Vueインスタンス - Vue.js](https://jp.vuejs.org/v2/guide/instance.html)のJavaScriptコードについても、まとめようと思います。