その他
    ES6を使う
     

    ES6を使う

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    Ruby on Rails のフロントエンドでは 未だにJavaScript は CoffeeScript + jQuery を使うのが一般的です。 しかし、Rubo on Rails 5.1 より jQueryは非公開になり WebPackerが導入されました。 今回は、ES6やそれをとりまく技術としてモダンなJSプログラミングを試してみます。

    ES6ってなに?

    ECMAScript2015 などと呼ばれるECMAScript(JavaScript)の6番目の規格です。
    最近(といっても結構前)のchromeやfirefox、opera、edgeが一部対応しています。
    JavaScriptでイマイチだった、オブジェクト指向や非同期コールバックの処理がすっきりしています。
    class、アロー関数、Promiseが導入されています。

    FirefoxのES6への対応状況

    なお、CoffeeScriptは、Version 2からECMAScript2015への対応が発表されています。

    CoffeeScript Version 2

    ES6っぽい開発をする

    ES6に対応してきているブラウザも多いですが、互換性が面倒。でも、古い規格はもうごめんだ。
    というために、便利なツールがたくさんあります。
    その中で有名なのが、 npm, webpack, babel です。 nodejsも使います。

    • npmyarn でパッケージ管理
    • webpack で依存関係などのバンドル管理
    • babelでトランスパイル

    重要そうな機能のまとめ

    試してみたい

    ChromeやFireFoxの開発者ツールで使えます。

    変数と定数

    varのほかに、letconstが追加されました。

    varは今まで通り。

    var foo1 = 1;
    var foo1 = 2;
    foo1 // 2
    

    let は varと同じく変数の定義ですが、再定義がエラーになります。

    let foo2 = 1;
    let foo2 = 2; // SyntaxError
    

    const は定数。再定義、再代入がエラーになります。

    const FOO = 1;
    const FOO = 2; // SyntaxError
    

    class

    prototypeを使うより直感的に使えるようになりました。

    class Book {
      constructor(title)  {
         this.title = title;
      }
      genre() {
        console.log("unknown");
      }
      static bar() {
      }
      static foo() {
         this.bar();
      }
    }
    class Dictionary extends Book {
       genre() {
         console.log("dictionary");
       }
    } 
    var dict = new Dictionary("広辞苑");
    console.log(dict.title);  // 広辞苑
    dict.genre(); // dictionary
    

    アロー関数

    (arg) => は function(arg) と同じ。次項のPromiseを使うときなどに見やすくかけるようになります。

    var func = foo => console.log(foo);
    func("hoge"); // hoge
    var func2 = (foo,bar) => console.log(foo + bar);
    func2("hoge", "hare"); // hogehare
    var func3 = (all, e) => {
        var plus = all + e;
        console.log("plus = " + plus);
    };
    

    Promise

    非同期処理を扱います。とてもシンプルな仕組みなのですがなれるまで少し時間がかかるかもしれません。
    Promiseは非同期処理が必要なユースケースで多用されます。fetch() などの、I/Oやネットワークアクセスがあるものや、サービスワーカとの通信などで多用されています。
    jQueryにも Deferred Objectが導入されていますが、それとほぼ同等のものです。
    以下の例のように、fetch()の処理が完了したらthen内のコールバックが呼ばれます。
    fetch()でエラーが発生したら catch内のコールバックが呼ばれます。

    fetch("./foo.json").then((response)=> {
    }).then((body) => {
    }).catch((err) => {
    });
    

    Promiseは、処理中の状態と2つの結果の状態 resolve と reject にが存在します。
    既存の処理をPromiseオブジェクトにラップすることで非同期処理にすることができます。
    ラップにはコンストラクタを使用します。Promiseコンストラクタには resolve, rejectという関数オブジェクトが渡されます。

    new Promise(function(resolve, reject) {
        // 時間がかかる処理
        if (成功したら) {
            resolve("thenに渡すコールバックの引数");
         } else {
            reject("catchに渡すコールバックの引数");
        }  
    });
    

    戻り値は Promiseオブジェクトがすぐに返ります。コールバック内で resolveかrejectが呼ばれたら処理が完了したのでthenまたはcatchメソッドで値を取得することができます。

    常に成功するものをPromiseにしたい場合は Promise.resolve("thenに渡すコールバックの引数") とできます。
    必ず “thenに渡すコールバックの引数” でresolvedしたPromiseを取得できます。
    また、 Promise.reject("catchに渡すコールバックの引数")でrejectedしたPromiseを取得できます。

    enter image description here