この記事はアピリッツの技術ブログ「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が導入されています。
なお、CoffeeScriptは、Version 2からECMAScript2015への対応が発表されています。
ES6っぽい開発をする
ES6に対応してきているブラウザも多いですが、互換性が面倒。でも、古い規格はもうごめんだ。
というために、便利なツールがたくさんあります。
その中で有名なのが、 npm, webpack, babel です。 nodejsも使います。
重要そうな機能のまとめ
試してみたい
ChromeやFireFoxの開発者ツールで使えます。
変数と定数
var
のほかに、let
, const
が追加されました。
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を取得できます。