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

パスワード:


パスワード紛失

新規登録
メインメニュー
メイン
   コーダーズルーム【スクリプト系】
     プロパティの参照がメソッドの実行方法によって出来ない理由
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
旭日ゆうほ
Åê¹ÆNo.25922
投稿日時: 2006-6-5 19:48
Bak@Fla名人
居住地: 心は岡山
投稿: 91
使用環境:
Windows Vista Home Premium
Flash MX2004 v7.2
Flex2 SDK
Flex3 SDK
FlashDevelop3.0.0 Beta7
プロパティの参照がメソッドの実行方法によって出来ない理由
毎度お世話になっています。


class TestClass
{
	private var _func:Function;
	private var _testVar:Number;
	
	// コンストラクタ
	public function TestClass()
	{
		_func = testFunction;
		_testVar = 0;
		
		_func();
		getFunction()();
	}
	
	// テストメソッド
	private function testFunction():Void
	{
		trace(_testVar);
	}
	
	// メソッドを割り当てる変数取得メソッド
	public function getFunction():Function
	{
		return _func;
	}
}

上記のようなクラスを作って「var test:TestClass = new TestClass();」を実行しましたところ、
出力が以下のようになりました。
引用:

出力:
0
undefined

「_func()」で「testFunction()」を呼び出した場合は
「_testVar」の内容を出力できているのに対し、
「getFunction()()」で「testFunction()」を呼び出した場合は
なぜか「_testVar」の内容が出力されていません...。

僕の今までの知識だと「_func()」も「getFunction()()」も
同じ「testFunction()」を実行している処理だと思うのですが、
どうやら同じではないようです...
なぜ「getFunction()()」の場合「_testVar」を参照できないのでしょうか?
理由をお知りの方がおられましたら、教えてください


----------------
旭日ゆうほ
swf置いてます。AM902

野中文雄
Åê¹ÆNo.25923
投稿日時: 2006-6-5 20:17
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: プロパティの参照がメソッドの実行方法によって出来ない理由
funcitonを抽象的に取出しているからではないでしょうか。
引用:
旭日ゆうほさんは書きました:
class TestClass
{
	private var _func:Function;
	private var _testVar:Number;
	
	// コンストラクタ
	public function TestClass()
	{
		_func = testFunction;
		_testVar = 0;
		
		_func();
		getFunction()();
		getFunction().call(this);
	}
	
	// テストメソッド
	private function testFunction():Void
	{
		// trace(_testVar);
		trace([this, _testVar]);
	}
	
	// メソッドを割り当てる変数取得メソッド
	public function getFunction():Function
	{
		return _func;
	}
}

上記のようなクラスを作って「var test:TestClass = new TestClass();」を実行しましたところ、
出力が以下のようになりました。

引用:
出力:
[object Object],0
undefined,undefined
[object Object],0


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

旭日ゆうほ
Åê¹ÆNo.25925
投稿日時: 2006-6-5 22:01
Bak@Fla名人
居住地: 心は岡山
投稿: 91
使用環境:
Windows Vista Home Premium
Flash MX2004 v7.2
Flex2 SDK
Flex3 SDK
FlashDevelop3.0.0 Beta7
Re: プロパティの参照がメソッドの実行方法によって出来ない理由
さっそくのお返事、ありがとうございます

まだメソッドというものの実行について理解が曖昧な状態ですが、おぼろげながら何か見えてきました。
「getFunction()()」でメソッドを実行した場合、
そのメソッドがどこで定義されているのかが不明なため、
「this._testVarl」を参照できないと考えてよろしいでしょうか?

自分なりに考察してみまして、メソッドの他の実行方法も試してみました。
class TestClass
{
    private var _func:Function;
    private var _testVar:Number;

    private var _func2:Function;
    
    // コンストラクタ
    public function TestClass()
    {
        _func = testFunction;
        _testVar = 0;
        
        
        /*
        _func();
        getFunction()();
        getFunction().call(this);
        */
        
       _func2 = getFunction();
       _func2();

       var func:Function = getFunction();
       func();

       func.call(this);
    }
    
    // テストメソッド
    private function testFunction():Void
    {
        // trace(_testVar);
        trace([this, _testVar]);
    }
    
    // メソッドを割り当てる変数取得メソッド
    public function getFunction():Function
    {
        return _func;
    }
}

引用:
出力:
[object Object],0
undefined,undefined
[object Object],0

これらも試してみまして、仮説を立てました。

1. 「this._func()」を実行した場合、
  実行したメソッド内で「this」を参照できる。
2. ローカル変数は「this」で参照できないので、
  上記の「func()」を実行した場合、実行したメソッド内で「this」を参照できない。
3. 「call(this)」は、どこに定義されているのか分からないメソッドに
  「thisの位置ですよ」と教えてあげるために使える。

つまり「getFunction()()」の「getFunction()」はローカル変数と同じ扱いで、
仮説2から「this」を参照できないということでしょうか...?

ちょっとあたまがねじれてきました


----------------
旭日ゆうほ
swf置いてます。AM902

野中文雄
Åê¹ÆNo.25932
投稿日時: 2006-6-6 5:09
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: プロパティの参照がメソッドの実行方法によって出来ない理由
オブジェクト(this)を参照(ターゲットと)してメソッドを呼出せば、functionブロック内でthisが参照できます。
引用:
旭日ゆうほさんは書きました:
1. 「this._func()」を実行した場合、
  実行したメソッド内で「this」を参照できる。

ローカル変数というか、getFunction()がオブジェクトから切離したfunctionだけを返すからでしょう。以下のスクリプトと、同じ結果になるものと考えられます。
    // メソッドを割り当てる変数取得メソッド
    public function getFunction():Function
    {
		// return _func;
		return function ():Void {
			trace([this, _testVar]);
		};
	}

引用:
2. ローカル変数は「this」で参照できないので、
  上記の「func()」を実行した場合、実行したメソッド内で「this」を参照できない。

Functioln.call()メソッドは、this参照を指定して、そのメソッドとして呼出すことができます。
引用:
3. 「call(this)」は、どこに定義されているのか分からないメソッドに
  「thisの位置ですよ」と教えてあげるために使える。

逆にいえば、getFunction()の戻り値を別のオブジェクトに設定して呼出せば、thisはそのオブジェクトを参照するようになります。
// タイムライン: _root
// フレームアクション
function xTest():Void {
	trace(this);
}
function xGetFunction():Function {
	return xTest;
}
xTest();  // 出力: _level0
xGetFunction()();  // 出力: undefined
var obj:Object = new Object();
obj.myFunction = xGetFunction();
obj.toString = function():String  {
	return "this is obj";
};
obj.myFunction();  // 出力: this is obj


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

旭日ゆうほ
Åê¹ÆNo.25940
投稿日時: 2006-6-6 21:37
Bak@Fla名人
居住地: 心は岡山
投稿: 91
使用環境:
Windows Vista Home Premium
Flash MX2004 v7.2
Flex2 SDK
Flex3 SDK
FlashDevelop3.0.0 Beta7
Re: プロパティの参照がメソッドの実行方法によって出来ない理由
お返事ありがとうございます。
大分頭がすっきりしてきました

関数は「this._func()」のように参照ありきで実行されるものだったのですね。
うまく文章にできませんが、理解できました。

引用:
野中文雄さんは書きました:
逆にいえば、getFunction()の戻り値を別のオブジェクトに設定して呼出せば、thisはそのオブジェクトを参照するようになります。
// タイムライン: _root
// フレームアクション
function xTest():Void {
	trace(this);
}
function xGetFunction():Function {
	return xTest;
}
xTest();  // 出力: _level0
xGetFunction()();  // 出力: undefined
var obj:Object = new Object();
obj.myFunction = xGetFunction();
obj.toString = function():String  {
	return "this is obj";
};
obj.myFunction();  // 出力: this is obj

最後に野中先生のスクリプトを参考にもう少し試してみます。
// タイムライン: _root
// フレームアクション
function xTest():Void {
	trace(this);
	this.comFunction();
}

function xGetFunction():Function {
	return xTest;
}

function comFunction():Void
{
	trace([this, "_root.comFunction()"]);
}

xTest();           // 出力: _level0と_level0,_root.comFunction()
xGetFunction()();  // 出力: undefinedのみ

var obj:Object = new Object();
obj.myFunction = xGetFunction();
obj.toString = function():String  {
    return "this is obj";
};

obj.comFunction = function():Void
{
	trace([this, "obj.comFunction()"]);
};

obj.myFunction();              // 出力: this is objとthis is obj,obj.comFunction()
xGetFunction().call(obj);  // 出力: this is objとthis is obj,obj.comFunction()

実際の出力は以下のとおりです。
引用:
出力:
_level0
_level0,_root.comFunction()
undefined
this is obj
this is obj,obj.comFunction()
this is obj
this is obj,obj.comFunction()

同名の関数を作り、「this」の参照をコントロールすることで処理を分岐できました。
何かに使えそうです。

おかげさまで関数に対する理解が深まりました。
長いことお付き合いしていただき、ありがとうございました


----------------
旭日ゆうほ
swf置いてます。AM902

ごんざえもん
Åê¹ÆNo.25941
投稿日時: 2006-6-7 10:25
常連
居住地: 北かんとー
投稿: 123
使用環境:
Windows XP SP3
Windows7
Windows VISTA
MacOSX10.6
FlashMX2004
Flash8 pro
Flash CS6 (体験版…)
Re: プロパティの参照がメソッドの実行方法によって出来ない理由
Delegateを使うとスコープがわかりやすくなります

引用:

旭日ゆうほさんは書きました:
毎度お世話になっています。


class TestClass
{
	private var _func:Function;
	private var _testVar:Number;
	
	// コンストラクタ
	public function TestClass()
	{
		_func = testFunction;
		_testVar = 0;
		
		_func();
		getFunction()();
	}
	
	// テストメソッド
	private function testFunction():Void
	{
		trace(_testVar);
	}
	
	// メソッドを割り当てる変数取得メソッド
	public function getFunction():Function
	{
		return mx.utils.Delegate.create(this, _func);

	}
}

上記のようなクラスを作って「var test:TestClass = new TestClass();」を実行しましたところ、
出力が以下のようになりました。
引用:

出力:
0
undefined //0



----------------
gonzaemon

旭日ゆうほ
Åê¹ÆNo.25951
投稿日時: 2006-6-7 16:41
Bak@Fla名人
居住地: 心は岡山
投稿: 91
使用環境:
Windows Vista Home Premium
Flash MX2004 v7.2
Flex2 SDK
Flex3 SDK
FlashDevelop3.0.0 Beta7
Re: プロパティの参照がメソッドの実行方法によって出来ない理由
お返事ありがとうございます。

Delegate.create(this, _func);

はthis参照と関数をつなげたもの(と表現すればいいでしょうか)を返すのですね。

これを踏まえてもう一つ試してみました。
import mx.utils.Delegate;

class TestClass
{
    private var _func:Function;
    private var _testVar:Number;
    
    // コンストラクタ
    public function TestClass()
    {
        _func = testFunction;
        _testVar = 0;
        
        _func();
        
        Delegate.create(this, getFunction())();
        // getFunction()();
    }
    
    // テストメソッド
    private function testFunction():Void
    {
        trace([this, _testVar]);
    }
    
    // メソッドを割り当てる変数取得メソッド
    public function getFunction():Function
    {
    	return _func;
        // return Delegate.create(this, _func);
    }
}

引用:
出力:
[object Object],0
[object Object],0

おおっ、うまくいきました。
Delegate.create(this, getFunction())();

こうしてもthisを指定して関数が呼び出せますね。

貴重な情報、ありがとうございました。

----
余談なのですが、「Delegate.create()」のヘルプを見ていますと、
引用:
Flash MX 2004 ヘルプ Delegate.create()の項目:
エディション
Flash MX Professional 2004

と書かれています。
僕はMX 2004なのですが、「Delegate.create()」を使用できてしまいました...。
べ、別に気にする必要なんてないですよね。


----------------
旭日ゆうほ
swf置いてます。AM902

スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

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