TestClass的程式碼
package tw.right929
{
public class TestClass
{
private var _name:String;
private var _showNameF:Function;
public function TestClass(name:String)
{
_name = name;
}
public function showName():void
{
_showNameF(this);
}
public function set showNameF(v:Function):void
{
_showNameF = v;
}
public function get showNameF():Function
{
return _showNameF;
}
}
}
測試TestFunction傳入Function後,呼叫Function的This會是那個物件?
<?xml version="1.0" encoding="utf-8"?>
<s:Application creationComplete="init()" xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768">
<fx:Script>
<![CDATA[
import tw.right929.TestClass;
private var tc1:TestClass = new TestClass("one");
private var tc2:TestClass = new TestClass("two");
private function init():void
{
trace("主執行檔是"+this.toString());
//主執行檔是TestFunction
tc1.showNameF = showName1;
tc2.showNameF = showName2;
tc1.showName();
tc2.showName();
}
private function showName1(self:*):void
{
trace("showName1 的this是"+this.toString());
//showName1 的this是TestFunction
}
private function showName2(self:*):void
{
trace("showName2 的this是"+this.toString());
//showName2 的this是TestFunction
}
]]>
</fx:Script>
</s:Application>
由上面的結果,可以知道,傳入的Function的this會是建立這個Function的物件。這裡還可以注意到showName1和showName2是private的,
但若是自已把參照傳出去的話,則其他的類別是可以呼叫的。
修改TestClass.showName()
public function showName():void
{
//_showNameF(this);
_showNameF.call(this , this);
}
執行後結果同上。使用Function.apply結果亦同。
接下來修改TestFunction
//*
private var showName1:Function =
function (self:*):void
{
trace("showName1 的this是"+this.toString());
trace("showName1 的self是"+self);
};
private var showName2:Function =
function (self:*):void
{
trace("showName1 的this是"+this.toString());
trace("showName1 的self是"+self);
};
/*/
private function showName1(self:*):void
{
trace("showName1 的this是"+this.toString());
//showName1 的this是[object TestClass]
trace("showName1 的self是"+self);
//showName1 的self是[object TestClass]
}
private function showName2(self:*):void
{
trace("showName2 的this是"+this.toString());
trace("showName1 的self是"+self);
trace(toString());
}
//*/
執行後,結果有了變化,this變成[object TestClass],也就是叫呼這個Function的物件實體。
由這個結果可知,若是直接在Class中定義function,
則這個Function會和Class產生很強的關聯,
使用Function.call時,this不會被傳入的參數所影響。
但若是用var的方式產生Function,
則這個Function就不會和特定的Class產生關聯,
全視呼叫時傳入的參數而定。
再來試試存取private的變數。
修改TestFunction
private var showName1:Function =
function (self:*):void
{
trace("showName1 的this是"+this.toString());
trace("showName1 的_name是"+this._name);
};
執行…噹噹…發生錯誤,找不到private的變數。
把_name改成public後,就可以正常執行。
這是因為Function是個Object的關係。
TestClass可以進一步簡化成
package tw.right929
{
public class TestClass
{
public var _name:String;
private var _showName:Function;
public function TestClass(name:String)
{
_name = name;
}
public function set showName(v:Function):void
{
_showName = v;
}
public function get showName():Function
{
return _showName;
}
}
}
因為Function.call(this),等價於Function()
故若想於執行期動態的改變Class的方法,
可使用var的方法宣告、傳入,但存取private變數時要注意一下。
測試動態產生的function
修改TestFunction
private function init():void
{
trace("主執行檔是"+this.toString());
//tc1.showName = showName1;
//tc2.showName = showName2;
tc1.showName = getF("i am one");
tc2.showName = getF("i am two");
tc1.showName();//i am one
tc2.showName();//i am two
}
private function getF(v:String):Function
{
return function ():void
{
trace(v);
};
}
從輸出結果可知,每一個function宣告所產生出來的Function都是獨立的個體。
沒有留言:
張貼留言