109
50

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScriptとElmを比べてみた〜後編・Vue.jsとも比べてみた〜

Last updated at Posted at 2019-06-27

※前編はこちらやで。

ハスケル子「引き続き、JavaScriptElm・・・」
ハスケル子「そしてVue.jsもちょこっと比べてみましょう」

オブジェクト(のようなもの)

JavaScriptのオブジェクト

const takashi = {
    displayName: "たかし",
    age: 36,
    height: 173,
    weight: 73
};

ワイ「displayNameとかageとかが、プロパティいうやつやな」
ワイ「takashi.ageとかすると、プロパティの値にアクセスできんねん」

Elmのレコード

takashi =
    { displayName = "たかし"
    , age = 36
    , height = 173
    , weight = 73
    }

ワイ「Elmではレコードいうねんな」
ワイ「JSのオブジェクトとけっこう似てるな」
ワイ「displayNameとかageとかのことは」
ワイ「フィールドっていうんやな」
ワイ「JSと同じくtakashi.ageって書けばフィールドの値にアクセスできんねん」

オブジェクトのプロパティを更新

JavaScriptのオブジェクト

takashi.age = 37;
takashi.weight = 83;

ワイ「constで宣言した再代入不可なオブジェクトでも、プロパティは変更できてまうんやな」

Elmのレコード

newTakashi =
    { takashi | age = 37, weight = 83 }

ワイ「Elmでは全ての値が不変やからtakashi.age = 37みたいな上書きはできひんねん
ワイ「せやから、1つ歳をとって10Kg太ったnewTakashiという新しいレコードを作る形になる」
ワイ「元々のtakashiは36歳のまま、別に存在すんねん」

ドキュメントの書き方

JavaScript (JSDoc)

/**
 * @param  {Number} num
 * @param  {String} str
 * @return {String}
 */
function displayNumber (num, str) {
    return num + str;
}

ワイ「関数の使い方が分かりやすいように」
ワイ「引数や戻り値の型をコメントで書いたりすんねんな」
ワイ「まぁ、実装とズレてても動くから、努力目標やけどな・・・」

Elmの場合は型で表現

displayNumber : Int -> String -> String
displayNumber num str =
    String.fromInt num ++ str

ワイ「displayNumber : Int -> String -> Stringいうのは」
ワイ「このdisplayNumberいう関数は」
ワイ「引数としてInt型の値とString型の値を受け取って」
ワイ「戻り値としてString型の値を返す」
ワイ「そんな関数ですよ〜っていう」
ワイ「型注釈いうやつや」

ワイ「しかも、この型注釈で書いた通りに実装せえへんと」
ワイ「ちゃんとコンパイルエラーが出て教えてくれんねん」
ワイ「**TYPE MISMATCH(型の不一致)**です〜、言うてな」

ワイ「つまり、強制力のある注釈や!」

ビューの書き方

Vue.jsの場合(単一ファイルコンポーネント)

<template>
  <div class="container">
    <button>増やす</button>
    <input type="text">
    <button>減らす</button>
  </div>
</template>

ワイ「ほぼhtmlやな」
ワイ「読みやすいな」

Elmの場合

view model =
    div [ class "container" ]
        [ button [] [ text "増やす" ]
        , input [ type_ "text" ] []
        , button [] [ text "減らす" ]
        ]

ワイ「このdivとかbuttonていうのがタグ名やね・・・?」

ハスケル子「まあそうなんですけど」
ハスケル子「タグ名というより、れっきとしたElmの関数です」
ハスケル子「関数なので───」

joinButton =
    button [] [ text "参加する" ]

ハスケル子「───こんな感じで変数に格納すれば」
ハスケル子「それだけでコンポーネントみたいに使えますし」

commonButton buttonText =
    button [] [ text buttonText ]

ハスケル子「↑こう、引数としてテキストを受け取る関数にすれば」
ハスケル子「propsを受け取って表示するタイプのコンポーネントもサクッと作れます」

ワイ「おお」
ワイ「コンポーネントも関数そのものやから、コードの中で自然に使えるな」

ハスケル子「そうなんです」
ハスケル子「リスト1の分だけ回してli要素を生成したい、なんて場合も簡単です」

イベントリスナ登録(のようなもの)

Vue.jsの場合

<button @click="incrementFunc">増やす</button>
<input type="text">
<button @click="decrementFunc">減らす</button>

ワイ「見たままやな」
ワイ「ボタンをクリックするとincrementFuncdecrementFuncという」
ワイ「関数が実行されんねんな」
ワイ「関数はmethodsの中に書いとけばええんや」

Elmの場合

button [ onClick Increment ] [ text "増やす" ]
, input [ type "text" ] []
, button [ onClick Decrement ] [ text "減らす" ]

ワイ「こう書いておけば、このボタンをクリックした時に・・・?」

ハスケル子「IncrementまたはDecrementというメッセージが生み出されます」

ワイ「メッセージ・・・?」
ワイ「そのメッセージはどこで受け取るん?」

ハスケル子「状態の更新内容を定義するupdateっていう関数で受け取ります」

update msg model =
    case msg of
        Increment ->
            { model | int = model.int + 1 }
        Decrement ->
            { model | int = model.int - 1 }

ハスケル子「Incrementというメッセージが来たら」
ハスケル子「model・・・つまりVuexでいうstorestateみたいなもんですね」
ハスケル子「要はmodelイコール状態です」
ハスケル子「そのmodelの中のint1増加させます」
ハスケル子「メッセージがDecrementだった場合は1減らす感じですね」
ハスケル子「そして、それによって生成された新しいmodelを戻り値として返すって感じです」

ワイ「ほえ〜、新しいmodel、つまり新しい状態を返すと」
ワイ「それがリアクティブにビューに反映されるっていうこと?」

ハスケル子「そうです」

ワイ「そうなんやね〜」
ワイ「Elmって、VueとかReactみたいに仮想DOMを内蔵してたんやね」
ワイ「あとVuexやRedux相当の機能もか」

ハスケル子「そうです」
ハスケル子「っていうかVuexReduxも、Elmの影響を受けてます」
ハスケル子「Elmというか、今みたいなThe Elm Architectureというパターンの影響ですね」
ハスケル子「しかもElmはとってもシンプルなので」
ハスケル子「学習コストが低くて、やめ太郎さんにピッタリです」

ワイ「どういう意味やねん

ハスケル子「オンラインエディタでさっきのカウンタのサンプルコードを色々いじってみると」
ハスケル子「更に分かると思いますよ」

ワイ「やってみるわ」
ワイ「おおきにやで、ハスケル子ちゃん」

ハスケル子「Vue勉強しててもReact勉強してても」
ハスケル子「副作用を起こさないように、とか」
ハスケル子「外部の状態に依存しない純粋な関数・・・つまり参照透過的な関数を書こう、とか」
ハスケル子「色んなドキュメントに書いてあるんですよ」
ハスケル子「じゃあ、そういう風にしか書けないElmやりゃあいいんですよ

ワイ「お、おう・・・」
ワイ「前向きに検討するわ・・・
ワイ「っていうか、今回JSやVueと比較したおかげでElmの文法がかなり分かったから」
ワイ「普通に読み書きできそうやな・・・」
ワイ「やってみるで!

〜おしまい〜

  1. 配列みたいなやつやで。

109
50
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
109
50

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?