![](/img/trans.png)
[英]Is there a way, in As3, to modify a class variable within a function, if you have a it passed as a parameter?
[英]Can you require a function parameter to be a static constant of the function's Class?
假設我有一個自定義事件類,並且它在靜態常量中存儲了幾種事件類型:
package customEvents
{
public class
{
public static const DISAPPEAR_COMPLETELY:String = "disappearCompletely";
public static const SIT_DOWN:String = "sitDown";
public static const STAND_UP:String = "standUp";
public static const SAIL_TO_THE_MOON:String = "sailToTheMoon";
public static const GO_TO_SLEEP:String = "goToSleep";
public static const GO_SLOWLY:String = "goSlowly";
public function MyCustomEvent(type:String)
{
super(type);
}
}
}
有沒有一種簡便的方法可以驗證傳遞給構造函數的type
是否是類的靜態常量之一,而不必對照每個值進行檢查?
為了擴展Dan R的答案,您可以創建一個嚴格的事件(如您枚舉的方式)類,如下所示:
import flash.utils.Dictionary;
import flash.utils.describeType;
import flash.utils.getQualifiedClassName;
public class StrictEvent
{
private static var VALID_EVENTS:Dictionary = new Dictionary();
public static function initEvents(inType:*):void {
var events:Object = {};
var description:XML = describeType(inType);
var constants:XMLList = description.constant;
for each(var constant:XML in constants) {
events[inType[constant.@name]] = true;
}
VALID_EVENTS[getQualifiedClassName(inType)] = events;
}
public function StrictEvent(type:String)
{
var className:String = getQualifiedClassName(this);
if(VALID_EVENTS[className][type]) {
// init
} else {
throw new Error("Error! " + type);
}
}
}
然后,您可以通過擴展strict事件類並在靜態初始化程序中調用initEvents來定義您的自定義事件類。 這是使用此方法的示例:
public class CustomEvent extends StrictEvent
{
public static const DISAPPEAR_COMPLETELY:String = "disappearCompletely";
public static const SIT_DOWN:String = "sitDown";
public static const STAND_UP:String = "standUp";
public static const SAIL_TO_THE_MOON:String = "sailToTheMoon";
public static const GO_TO_SLEEP:String = "goToSleep";
public static const GO_SLOWLY:String = "goSlowly";
public function CustomEvent(type:String) {
super(type);
}
{
initEvents(CustomEvent);
}
}
現在,每次創建事件時,只需查找事件對象,然后查看該對象中是否包含類型。 這也意味着您不必在初始化程序中手動添加所有常量。
盡管這兩個答案都提供了驗證字符串值的不同解決方案,但它們並沒有回答有關必須檢查值的問題。 之所以必須這樣做,至少是因為常量的值本身就是Strings。
因此,答案是否定的-無論如何,如果您要擴展Event,則不會。 由於該初始參數必須是一個String(在擴展Event時不多),因此,無論使用多少間接級別,您都將最終根據一系列有效值檢查參數。 傳遞除String之外的任何內容都會引發運行時錯誤。
克里斯蒂安(Christian)是正確的-這個問題包含了一個含糊不清的用語。 當您檢查事件“類型”時,它們不是數據類型,即類對象,它們只是將事件的特定“風味”傳遞給偵聽對象的字符串值。
就我個人而言,我認為您不需要事件類型的運行時驗證。 如果您的代碼嘗試使用不存在的事件常量,例如
obj.addEventListener(CustomEvent.TYPE_WHICH_DOES_NOT_EXIST, handlerMethod);
...您將在代碼運行之前收到編譯器錯誤。 如果您將原始字符串值用於事件類型,那么您將無法達到始終使用事件常量的目的。
如果要將每個靜態常量都設置為大寫常量名稱的小寫字符串,則可以執行以下操作:
if( class.hasOwnProperty( type.toUpperCase() ) )
{
// Do something
}
else
{
// Failure
}
您可以通過以下幾種方法進行攻擊:
您的代碼示例似乎是一個事件類。 如果是這種情況,則不能使用第一個選項,因為如果不需要,您將不想更改構造函數的簽名。
package customEvents
{
public class
{
private static var typeList:ArrayCollection;
public static const DISAPPEAR_COMPLETELY:String = "disappearCompletely";
public static const SIT_DOWN:String = "sitDown";
<... lines deleted ...>
public static const GO_SLOWLY:String = "goSlowly";
// static constructor
{
typeList = new ArrayCollection();
typeList.addItem(DISAPPEAR_COMPLETELY);
typeList.addItem(SIT_DOWN);
<... lines deleted ...>
typeList.addItem(GO_SLOWLY);
public function MyCustomEvent(type:String)
{
if (typeList.contains(type)
super(type);
else
throw new Error("Invalid type");
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.