ECMAScriptで提案されている arrow function について
2012/04/03 BBCがレスポンシブデザインを採用 - 本日のHTML5とか最新情報 - IT-Walker on hatenaECMAScript6では、functionの代わりに=>を使えるようになる
http://css.dzone.com/articles/exciting-future-javascript-0
ES6、だいぶドラスティックな変更に傾きつつあるよう。ES4の二の舞にならないといいのですが・・
HTML5のMLにECMAScript全快な話を広げるのはアレな気がしたので、こちらでヒッソリと書こうと思う。
まず、本当に『ES4の二の舞にならない』ことを願う。
んで、arrow functionこと=>
に関して、まだECMASCript6thに入ることが決まっているわけではないと思う。記事でも ECMAscript, 6th edition might bring us fat arrow notation
とmightが入っている。
また、元々記事の Douglas Crockford さんの方(What is the meaning of this? » Yahoo! User Interface Blog (YUIBlog))では言及されていますが、function を単純に => に置き換えられるわけではなく、少し注意が必要(というか今まで払っていた注意をしなくて良くなる?)。
通常のfunctionとarrow functionの違いは以下2点
this
が何を指すか- new できない
this
が何を指すか
var o = { foo: function (list) { var self = this; list.forEach(function(item){ self.hoge(item); }); }, hoge: function (item) { ... } }
のforEach
内のthis
は、この場合はグロバールオブジェクトを指してしまう(Strictモードではundefined
)。これを回避するためにvar self = this
みたいのを入れたりしていたわけだが*1、それが不要になるはず。
var o = { foo: function (list) { list.forEach(item => this.hoge(item)) }, hoge: function (item) { ... } }
通常、this
は実行時にそれが決まるが、arrow functionでは固定化される。
(x) => x * x == function(x){ return x * x; }.bind(this);
だと思えば理解しやすいかも。しかし、最初からbindされた状態だと、callやapplyメソッドどうするの...という疑問が出てくる。この辺りの議論はメーリングリスト上でもまだ終わってない感じがする。
より、ES.nextっぽくする
また、こちらは既にドラフト版にも挙がっているが、オブジェクトリテラル中での関数定義にもfunctionキーワードは不要になる。
var o = { foo (list) { list.forEach(item => this.hoge(item)) }, hoge (item) { ... } }
だいぶすっきりした記述になるね!
new できない
arrow functionで作ったfunctionオブジェクトは、[[Construct]]
内部メソッドを持たない。よって、new しようとすると、コンストラクタがないよって旨の例外が出るはず。
たとえば、new Date.now()
をすると、TypeError: Date.now is not a constructorみたいにね。
注意
arrow functionはまだ議論真っ最中の提案であり、ここに書いたことは明日にも陳腐化するかもしれない。あくまで、2012-04-03時点で、こんな事になっているよってことで。
あと、議論の全部は全然読めていないので、間違いがあるかも。もしあったらコメント等をヨロシク
*1:forEachの場合は、第3引数にthisを渡してあげれば良いけどね