ほんじゃらねっと

ダイエット中プログラマのブログ

Node.jsがES5とES6(ES2015)に対応してることに今さら気づいて、使ってみたら感動した新要素

Pythonを堪能したのでJavascriptに戻ってきた。

JavascriptでPythonのジェネレータみたいな機能はないのかな、

と調べてみると、ES6(ES2015)で追加され、Node.jsはES6対応済みらしい。

そういえばES5もES6もよく調べたことないな、と思って

調べてみると、便利機能が山ほど追加されててびっくり。

Javascript好き、と言いながら大分遅れたコードを書いてたようだ。

とりあえず今後絶対使おう!と決めた要素を練習がてらまとめておく!

まずはconstとlet

今までvarを使ってた変数宣言にconstとletが使えるようになった。

constは再代入しない定数宣言、letはレキシカルスコープの変数宣言。

const products = [ 
    {name: "item1", price: 10},
    {name: "item2", price: 20},
    {name: "item3", price: 30},
    {name: "item4", price: 40} 
];
for (let i = 0; i < 10; i++) {
    console.log(i);
}

明確になって良い。

アロー関数

これが個人的に一番嬉しかった新要素。

function宣言を簡略化して記述できるようになった。

昨日まではこう書いてた関数を、

var func1 = function (x, y) {
    return x + y;
};

console.log(func1(1, 2));
//3

こう書けるようになった。

const calc1 = (x, y) => {
    return x + y;
};

console.log(calc1(1, 2));
//3

1処理だけなら{}もreturnも省略できる。

const calc2 = (x, y) => x + y;

console.log(calc2(1, 2));
//3

パラメータが1つなら、()も省略できる。

const calc3 = x => x * 2;

console.log(calc3(3));
//6

function書きまくらなくてよくなるのは嬉しい。

forEach、map、filter、reduceでリスト処理

リスト処理関数好きなのに。ES5で既に使えるようになっていたとは…。

ずっとUnderscore.js使ってたよ。

constとletのところで宣言したproductsリストを処理してみる。

アロー関数と組み合わせて書くことで、超シンプルに書ける。

forEachでリストのループ処理

products.forEach(p => console.log(p.price));
// 10〜40が表示される

map処理

const productNames = products.map(p => p.name);
console.log(productNames);
// [ 'item1', 'item2', 'item3', 'item4' ]

filter処理

const highProducts = products.filter(p => p.price > 25);
console.log(highProducts);
// [ { name: 'item3', price: 30 }, { name: 'item4', price: 40 } ]

reduce処理

const priceTotal = products.reduce((total, product) => total + product.price, 0);
console.log(priceTotal);
// priceの合計値(=100)が表示される

もう1つ、リストをオブジェクトに変換する処理も書いてみた。

const userNames = [
    "yamada",
    "tanaka",
    "okada"
];

const userMap = userNames.reduce((m, user, i) => {
    m["user" + i] = user;
    return m;
}, {});
console.log(userMap);
// { user0: 'yamada', user1: 'tanaka', user2: 'okada' }

昨日までのコードとちがいすぎて、まるで別の言語で書いているようだ。

ジェネレータ

ジェネレータも作れるようになってた。

「function*」で関数宣言し、yieldで値を返す。

ES2015にもrange関数がないようなので、

Underscore.jsのrange関数を参考にジェネレータを使って書いてみた。

module.exports = { 
    range: function* (start, stop, step) {
        if (stop == null) {
            stop = start || 0;
            start = 0;
        }
        step = step || 1;

        const length = Math.max(Math.ceil((stop - start) / step), 0); 

        for (let idx = 0; idx < length; idx++, start += step) {
            yield start;
        }   
    }   
};

下記のようにしてループ処理できる。

for (let i of range(10)) {
    console.log(i);
}
// 0〜9が表示される

文字列のリピート

文字列の繰り返しを指定できる関数が増えた。

ちょっとうれしい。

console.log("*".repeat(10));
// **********

おわり

他にも関数のパラメータをリストでまとめて受け取れたり、

引数のデフォルト値が指定できるようになったり、

PythonにあってJavascriptにもあったら良いのにな、

と思うような要素が色々追加されていた。

BabelのEC2015紹介ページがサンプルコード付きで分かりやすい。

https://babeljs.io/docs/learn-es2015/babeljs.io

あと、Underscore.jsを使った書き方との比較サイトがあって、

個人的に大変参考になった。

You Might Not Need Underscore | Reindex

WEB+DB PRESS Vol.87

WEB+DB PRESS Vol.87

  • 作者: 佐藤鉄平,小林明大,石村真吾,坂上卓史,上原誠,鳥居英,佐藤歩,泉水翔吾,うさみけんた,伊藤直也,高橋侑久,佐藤太一,hayajo,橋本翔,西尾泰和,中島聡,はまちや2,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2015/06/24
  • メディア: 大型本
  • この商品を含むブログ (2件) を見る