(0, obj.method) は this の参照を obj から外せるらしい
Hyperapp を始めようとしたら Parcel という Webpack がシンプルになったようなツールがあるのを知り、バンドルされたコードを見てみたら
var _hyperapp = require("hyperapp"); (0, _hyperapp.app)({ view: function view(state) { return (0, _hyperapp.h)('div'); } });
という表現があり、初見では (0, _hyperapp.app)
どう評価されるのかが分からなかったので少しだけ試したり調べたりしました。
挙動は多少わかった気がしますが、この表現が必要な理由までは読み解けませんでした。
,
オペレータ
node の REPL で確認したところ ,
はどうやら最後の値を返すようです。
(0, 1) // => 1 (0, 1, 2, 3) // => 3 ('this', 'is', 'a', 'pen') // => 'pen'
つまり
(0, _hyperapp.app) // => _hyperapp.app
ということですね。これだけだと何の意味もないワンクッションに見えるのですが、これにより this
の参照が変わるみたいなのです。
のコメントを見なければ気づけませんでした。
- Comma Operator - MDN
- Comma Operator - ECMA Script
- 全然読めなかったので読めるようになりたいです
オブジェクトのメンバとしての関数の呼び出し方
とりあえず知っていることをおさらいしておくと、JavaScript ではオブジェクトが関数フィールドを持つ場合、その呼び出し方によって this
の参照先が変わるという話があります。
単純な例として this
を返す関数を持つオブジェクトがあって
const obj = { method() { return this } }
この obj.method
の参照する関数をふた通りの方法で呼び出すことを考えてみると
// A obj.method() // => global // B const method = obj.method method() // => obj
obj.method
も method
も同じ関数を参照しているのに返ってくる this
の値が異なりますね。
ハンドラとして obj.method
形式で関数を渡したのに this
云々なエラーが返ってきて、理由もわからないまま .bind(obj)
でとりあえず想定通りの動きになった、というのは初心者によくあるパターンです。
で
StackOverflow のコメントを見るに、this
の参照を obj
から外したい場合に
const method = obj.method
method()
と書く代わりに
(0, obj.method)() // => global
と書くことができて楽、ということなのでしょうか。
Parcel が何のためにこういうことをしているのか読み解くのが先ですね。今日はここまでにします。
追記
AST Explorer で確認してみたところ SequenceExpression
という評価式らしいです。しかし ECMA Script Specification にはこの表現は見つかりませんでした。