モダンなJSフレームワークは宣言型プログラミングを選ぶ 

モダンなJSフレームワークである`Vue.js`や`React`などは宣言的という特性を取り柄としている。

Reactの公式サイトによると、宣言的なViewを

> アプリケーションの各状態に対応するシンプルな View を設計するだけで、React はデータの変更を検知し、関連するコンポーネントだけを効率的に更新、描画します。

> 宣言的な View を用いてアプリケーションを構築することで、コードはより見通しが立ちやすく、デバッグのしやすいものになります。

と解釈している。

この記事では、宣言的方式なとそうではない方式との違いを理解した上で、なぜモダンなJSフレームワークは皆宣言的方式を選ぶのかについて考える。

## 宣言的プログラミングと命令的プログラミング

Wikipediaにあるわかりやすい定義によると、宣言的プログラミング（Declarative programming）は「何を得たい」というWhatの部分を記述し、命令的プログラミングは（Imperative programming）　は「どうやって得るか」つまりHowの部分を記述する。


具体例を挙げる。

文字列の表示をコントロールするボタンを作るとする。

命令的方式では、DOM（Document Object Model）に対して、文字列やボタンなどのHTML要素の生成と表示/隠すロジックの実装を逐一記述することが必要。最終的にDOMがどういう風になるのかはコードからでは分からない。

```javascript
const ctn = document.getElementById("container");

const txt = document.createElement("p");
txt.className = "text";
txt.id = "text-to-toggle";
txt.innerHTML = "This is sample text.";

const btn = document.createElement("button");
btn.innerHTML = "toggle text";
btn.onclick = function (event) {
  const txt = document.getElementById("text-to-toggle");
  txt.classList.toggle("hidden")
};

ctn.appendChild(txt);
ctn.appendChild(btn);
```

動く実例は以下を参照。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="JjJPMMo" data-user="shiiyan" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/shiiyan/pen/JjJPMMo">
  Imperative Sample</a> by shiiyan (<a href="https://codepen.io/shiiyan">@shiiyan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


一方で、`Vue.js`を使った宣言的方式では、構築したいDOMを最初から宣言することになる。

```html
<div id="container">
  <p v-show="isVisible">This is sample text.</p>
  <button @click="toggle">toggle text</button>
</div>
```

`v-show`はVueが提供するディレクティブの一つで、`isVisible`という変数が真の場合に対象要素`<p>`を表示し、偽の場合に表示しないという意味を持つ。

どういうことを実装したいのかはHTMLのテンプレートを見るだけでわかる。JavaScriptでやるのはボタンをクリックすると文字列の表示をコントロールする変数の値が逆転する関数を定義すること。実際のDOM操作はフレームワークがやってくれる。

```javascript
var app = new Vue({
  el: "#container",
  data: {
    isVisible: true
  },
  methods: {
    toggle() {
      this.isVisible = !this.isVisible;
    }
  }
});
```

動く実例は以下を参照。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ExXYoOa" data-user="shiiyan" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/shiiyan/pen/ExXYoOa">
  Declarative sample</a> by shiiyan (<a href="https://codepen.io/shiiyan">@shiiyan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## 感想

宣言的方式とインタラクティブUIとの相性がいい。上記のような簡単な例では大差ないが、宣言的方式は明示的に状態管理の変数が存在し、複雑なインタラクティブUIを実装する時に、直接DOMをいじることより、状態変数をいじった方がやりやすい。

宣言的に方式はコード全体の見通しが良い。特に最初から実現したいHTMLテンプレートを記述することによって、HTMLからコンポーネントの設計が可能となり、高度なデザインを実装する難易度を下げられる。また、後からスタイルや表示内容の修正箇所の特定にも貢献する。

宣言的に方式により、画面表示と状態管理が別々のコンポーネントで定義することも可能となり、良い設計の起点となるかも。

## 参考

https://jp.vuejs.org/v2/guide/index.html#%E5%AE%A3%E8%A8%80%E7%9A%84%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0

https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2

https://ja.reactjs.org/

https://ja.wikipedia.org/wiki/%E5%AE%A3%E8%A8%80%E5%9E%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0