JS.next

JavaScriptの最新実装情報を追うブログ

アロー関数が実装された

概要

ES2015を象徴する機能である、アロー関数構文の実装がついにV8で始まった。


無名関数を短く書ける   [3.28.31]

アロー関数は無名関数の省略記法である。
今までこう書いていたのが、

var fn = function (a, b) { }

こうスッキリ書ける。

var fn = (a, b) => { }

「=>」が矢のように見えることから「アロー」関数と言う。


更に短くできる

これが、

[1, 2, 3].map( function (v) { return v * v } )  // [1, 4, 9]

アロー関数だとこうなるが、

[1, 2, 3].map( (v) => { return v * v } )  // [1, 4, 9]

引数が一つの時には「()」を省略できるので、こう書ける。

[1, 2, 3].map( v => { return v * v } )  // [1, 4, 9]

さらに、関数bodyが1つのreturn文の時はブロックと「return」を省略できる。

[1, 2, 3].map( v => v * v )  // [1, 4, 9]

20文字ほども削減することができた。


thisの参照が関数定義時に決まる   [4.4.56]

アロー関数は無名関数の省略記法と書いたが、一つ大きな特徴がある。
それは、「this」が関数呼び出し時に決まるのではないということ。
「this」は関数が定義されたスコープでのthisをそのまま指す。
つまり、

self = this
function () { ~~ self ~~ }

() => { ~~ this ~~ }

と書ける。


要素のクリックログを出すクラスを作ったとする。

function LogClick(target) {
  this.reset()
  target.addEventListener('click', function () {
    console.log(++this.count, target)  // ※
  })
}
LogClick.prototype.reset = function () { this.count = 0 }

※ここでのthisはtarget要素になってしまうので失敗する。
よって正しくはこうする。

function LogClick(target) {
  this.reset()
  var self = this
  target.addEventListener('click', function () {
    console.log(++self.count, target)
  })
}
LogClick.prototype.reset = function () { this.count = 0 }

アロー関数を使うと

function LogClick(target) {
  this.reset()
  target.addEventListener('click', () => {
    console.log(++this.count, target)  // ※
  })
LogClick.prototype.reset = function () { this.count = 0 }

※アロー関数内のthisは、targetなど他の変数がそうであるように、関数外のthisをそのまま指す。
(分かりにくければアロー関数をブロック文のように見るといいらしい)


argumentsオブジェクトを持たない   [4.4.19]

var arguments = 123

var fn = () => arguments

fn(456)  // 123


コンストラクタではない   [3.28.31]

コンストラクタとして振る舞うことはできない。
"prototype"プロパティも持たない。

var fn = () => {}

fn.prototype  // undefined

new fn  // TypeError

実装されるバージョン

V8 3.28.31(基本部分) 4.4.19(argumentsの適切な参照) 4.4.56(thisの適切な参照) 4.5.69(デフォルト有効)