トップへ戻るニュースフォーラムFLASH-ML 過去ログBak@Flaダウンロードよくある質問と答
ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
メインメニュー
メイン
   ActionScript 3.0 特設会議室
     関数クロージャ内のthis参照について
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
imajuk
Åê¹ÆNo.38515
投稿日時: 2008-4-22 14:43
新米
居住地: Tokyo
投稿: 6
使用環境:
MacOSX10.6.6
Flash CS4
FDT 4.2
関数クロージャ内のthis参照について
関数クロージャ内のthis参照について質問があります。

以下のようなコードがあったとき、
package
{
	public class
	{
		private function methodA():void
		{
		}
		private function test():void
		{
    			var f:Function = 	function()
		        					{
		        						trace(this);
		        					}
		        f();
        	}
	}
}


メソッド'test'を実行すると以下のような出力が得られます。
[object global]


このケースで、関数クロージャ内でのthisが何を指しているのかがよくわかりません。
自分の理解を総動員して2つの仮説を立ててみました。

●仮説A
このthisは関数クロージャのアクティベーションオブジェクトを指している。
アクティベーションオブジェクトをtraceするとobject global と出力されるのかもしれない。

●仮説B
このthisはトップレベルのグローバルを指している。
アクティベーションオブジェクトはthisを解決しないのかもしれない。
よって、
[関数クロージャのアクティベーションオブジェクト]

[メソッド'test'のアクティベーションオブジェクト]

[グローバルオブジェクト]
の順番でスコープチェーンをたどりグローバルオブジェクトに達している



自分としては仮説Bかなとも思うのですが、
そうすると、グローバルオブジェクトの前に
メソッド'test'のスコープでthisが解決されるはずです。

どちらの仮説も間違っているかもしれません。
本当のところはどうなんでしょうか?

ニノミヤ カズノリ
Åê¹ÆNo.38516
投稿日時: 2008-4-22 15:37
職人
居住地: 東京
投稿: 430
使用環境:
CS4
.4.11, .5.7
XP Pro(sp3)
Flash Player 10,0,22,87,
AIR 1.5.1,
IE 5.5 & 6 & 7 & 8,
Firefox 2.0.0.20 & 3.0.11 & 3.5,
Opera 9.64,
Safari 4,
Google Chrome 2.0.172.31,
Netscape 7.1
Re: 関数クロージャ内のthis参照について
こちらをご覧ください。
関数クロージャのthis参照について

引用:
野中文雄さんは書きました:
ローカルに定義された関数を呼出した場合には、クロージャは生成されません。[object global]というのは、特定のオブジェクトが参照されていないことを示します。

それにしても、タイトルが似てますね
imajuk
Åê¹ÆNo.38517
投稿日時: 2008-4-22 16:12
新米
居住地: Tokyo
投稿: 6
使用環境:
MacOSX10.6.6
Flash CS4
FDT 4.2
Re: 関数クロージャ内のthis参照について
ニノミヤさん、ありがとうございます。
教えていただいたトピックをみてみました。
(質問意図が伝わってないと思いましたので、この投稿は、投稿した後一度編集しています。)

引用:
ローカルに定義された関数を呼出した場合には、クロージャは生成されません。[object global]というのは、特定のオブジェクトが参照されていないことを示します。


引用中の「クロージャは生成されません」というときの「クロージャ」とは
メソッドクロージャのことですよね?
メソッドクロージャとは別のコンテクストで、関数クロージャのthisが解決されるということは理解しています。
私の疑問は「関数クロージャが実行された時のthisの参照(の解決方法)」です。

残念ながら、教えていただいたトピックでは
「関数クロージャ内のthisとはそういうものだ」ということ以上のことは書かれていないように読めました。
私が知りたかったのは、関数クロージャ内でthis参照したとき、
どういうメカニズムでthisが解決され、その結果[object global]という出力が得られるのか?
そして、その[object global]とはいったい何を指しているのか?
(グローバルオブジェクトなのか、アクティベーションオブジェクトなのか)
です。



ニノミヤ カズノリ
Åê¹ÆNo.38519
投稿日時: 2008-4-22 20:43
職人
居住地: 東京
投稿: 430
使用環境:
CS4
.4.11, .5.7
XP Pro(sp3)
Flash Player 10,0,22,87,
AIR 1.5.1,
IE 5.5 & 6 & 7 & 8,
Firefox 2.0.0.20 & 3.0.11 & 3.5,
Opera 9.64,
Safari 4,
Google Chrome 2.0.172.31,
Netscape 7.1
Re: 関数クロージャ内のthis参照について
ああ。。
変な事書いてしまいましたね。

この場で、このご質問の完璧な答えが返ってくる気がしません。
また、自分もよく分かりません。
global が返ってくるんだと記憶しておけば良いかと思いますので。

とりあえず分かっている事。
そもそもアクティベーションオブジェクト自身を参照する事は出来ません。
これはヘルプのスコープチェーンの項にて書かれています。
この事から、[object global] はアクティベーションオブジェクトを指さないと思います。

では何か。
私は名前の通りグローバルオブジェクトだと考えます。
JavaScript で同じ事をした場合、グローバルオブジェクトである window オブジェクトが返ってくる事と同じではないでしょうか。

ちなみにこの global オブジェクトはドキュメントクラスを持っており、
このクラスはフレームに変数や、関数を定義すると追加されていく様です。
(describeType で中身を見てみました。)
野中文雄
Åê¹ÆNo.38520
投稿日時: 2008-4-22 22:07
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: 関数クロージャ内のthis参照について
まず、「クロージャ」という言葉の意味には、幅があるようです。また、「メソッドクロージャ」「関数クロージャ」という用語は、私自身はActionScript 3.0の[ヘルプ]以外では、目にしたことがありません。

一般には、「クロージャ」は、関数に関数の定義された環境(関数の定義されたオブジェクトや関数外のActivationオブジェクトなど)を一体として扱うデータ構造というような意味に解されていると思われます。

参考:はてなダイアリー「クロージャ
Wikipedia「クロージャ
ITmediaエンタープライズ「クロージャとオブジェクトの微妙な関係
Martin Fowler's Bliki in Japanese「Closure

ニノミヤ カズノリさんのいわれるとおり、thisがActivationオブジェクトを参照することはありません。関数内のthisは、関数の定義または設定されたオブジェクトを参照します。

名前のない関数は、オブジェクトから切離して参照されます(「関数クロージャ」)。その関数の参照が新たに別のオブジェクトに設定されれば、関数内のthisはそのオブジェクトを参照します。特定のオブジェクトに設定されていない場合に、thisの参照先となるのがグローバルオブジェクトであり、文字列表現として[object global]と表示されます。

参考:「関数・メソッドとthis
引用:
imajukさんは書きました:
引用中の「クロージャは生成されません」というときの「クロージャ」とは
メソッドクロージャのことですよね?
...[中略]...
私の疑問は「関数クロージャが実行された時のthisの参照(の解決方法)」です。

...[中略]...
私が知りたかったのは、関数クロージャ内でthis参照したとき、
どういうメカニズムでthisが解決され、その結果[object global]という出力が得られるのか?


----------------
 

imajuk
Åê¹ÆNo.38521
投稿日時: 2008-4-22 22:40
新米
居住地: Tokyo
投稿: 6
使用環境:
MacOSX10.6.6
Flash CS4
FDT 4.2
Re: 関数クロージャ内のthis参照について
ニノミヤさん。
野中さん。
どうもありがとうございました。
理解できたような気がします。


確かにリファレンスにも「アクティベーションオブジェクトに直接アクセスは出来ない」と書いてありました。何度も読んで理解したつもりだったのですが、そもそもアクセスできないものはtraceもできませんよね。

また、スコープチェーンによる識別子の解決と、thisの値の話が自分の中でごっちゃになっていたようです。野中さんがおっしゃるように、thisの値はスコープチェーンとは別の仕組みで決定されるのですね。


もやもやしていた部分がずいぶんすっきりしました。
ありがとうございました。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 
Copyright (C) 2003 FLASH-japan. All rights reserved.
Powered by Xoops