ややこしいのはthisではない:JS
続いて元記事JavaScriptのthisではまった - No Programming, No Lifeの方も。
JavaScriptのthisではまったのでメモしておきます。
とあるのですが、さきほどのid:katzchang氏も
元記事に対して「どのオブジェクト上で走るかの話で、javaのthisも同じっちゃ同じ。 」ってブクマコメントを残した
と指摘されているようにthisは関係ないように思います。
thisの意味はそんなに変わらなくて、どちらもメソッドの持ち主がthisです。jsの場合メソッド(関数)が代入可能で、このJavaにはない「メソッドを代入する」事がハマったポイントではないかと思いました。
<html> <head> <title>thisのテスト</title> <script type="text/javascript"> var someObj = { name : 'SomeObject', whoAmI : function() { alert('I am ' + this.name + '.') } } function init() { var button1 = document.getElementById('button1') var button2 = document.getElementById('button2') button1.onclick = someObj.whoAmI button2.onclick = function(){ someObj.whoAmI() } } </script> </head> <body onLoad="init()"> <button id="button1" name="ぼたん1">押してね1</button><br> <button id="button2" name="ぼたん2">押してね2</button><br> </body> </html>
とやるとボタン1では「I am ぼたん1」と出て、ボタン2では「I am someObject」と出るという話です。
javascriptのオブジェクトがマップであり、メソッドもそのマップに関数を入れている事を思い出して、ちょっとMapらしく書き換えてみます。
<script type="text/javascript"> var someObj = {} someObj['name'] = 'SomeObject' someObj['whoAmI'] = function() { alert('I am ' + this.name + '.') } function init() { var button1 = document.getElementById('button1') var button2 = document.getElementById('button2') button1['onclick'] = someObj['whoAmI'] button2['onclick'] = function(){ someObj.whoAmI() } } </script>
someObj['whoAmI']
はfunction() { alert('I am ' + this.name + '.') }
なので、button1['onclick']
もfunction() { alert('I am ' + this.name + '.') }
になります。
<script type="text/javascript"> var someObj = {} someObj['name'] = 'SomeObject' someObj['whoAmI'] = function() { alert('I am ' + this.name + '.') } function init() { var button1 = document.getElementById('button1') var button2 = document.getElementById('button2') button1['onclick'] = function(){ alert('I am ' + this.name + '.') } button2['onclick'] = function(){ someObj.whoAmI() } } </script>
button1.onclick()を呼び出せば、this.nameは「ぼたん1」となるわけです。
var someObj = { name : 'SomeObject', whoAmI : function() { alert('I am ' + this.name + '.') } }
とあって、
button1.onclick = someObj.whoAmI
と書いたときに、それが
button1.onclick = function(){ someObj.whoAmI() }
ではなく
button1.onclick = function() { alert('I am ' + this.name + '.') }
という意味だ、というのがポイントなんだと思います。
function() { alert('I am ' + this.name + '.') }という関数オブジェクトは、「その時のオーナー(this)のnameというフィールドを使ってアラートする」という処理が行われるということです。
というのはそうなんですが、その時々のthisの意味に注目するよりも、メソッドにメソッドを代入する、という事がどういう事なのか、に注目した方が良いのではないかと思います。
「オーナー(this)」というのはメソッドの持ち主のことで、それはJavaと変わりない。
ある関数の中でthisはオーナー(呼び出し主)を指している。
の「呼び出し主」がセンダー(メソッドの呼び出し元)の意味なら誤りで、「オーナー」に当たるのはJavaのthisと同じ、そのメソッドの持ち主なわけです。