javascriptの関数リテラルではインスタンス変数にアクセスできない
関数リテラルではローカル変数には自由にアクセスできるので、
ついインスタンスメソッド等にもアクセス出来ると思ってしまいましたが、違うようです。
以下のように、コールバックとして自分のインスタンスメソッドを呼び出す関数を渡した場合、
実行時にエラーになります。
(coffeescriptで書いていますがjavascriptと同じ結果です)
class Test
hello: (num) ->
console.log "hello " + num
call: (test2) ->
@hello(1)
test2.call( ->
@hello(2)
)
class Test2
call: (callback) ->
callback()
関数リテラルはそれを作ったオブジェクトとは別のオブジェクトから呼び出されるらしく、
またその時のthis(coffeescriptなので@hello(2)はthis.hello(2)と等価です)は、
そのオブジェクトになり、メソッドがないため失敗するようです。
以下のように、一度thisを待避させることで呼び出すことが出来ます。
class Test
hello: (num) ->
console.log "hello " + num
call: (test2) ->
@hello(1)
self = this
test2.call( ->
self.hello(2)
)
class Test2
call: (callback) ->
callback()
完全なコードはこちら
class Test
hello: (num) ->
console.log "hello " + num
call: (test2) ->
@test = "test"
@hello(1)
self = this
test2.call( ->
# ここで@hello(2) はエラー
self.hello(2)
# Test2オブジェクトでもないので、これもエラー
# @world()
)
class Test2
call: (callback) ->
callback()
world: ->
console.log "world"
test = new Test
test2 = new Test2
test.call(test2)