在使用、效率或背景技术方面是否有任何区别?
var mc:MovieClip = MovieClip(getChildByName("mc"));
和
var mc:MovieClip = getChildByName("mc") as MovieClip;
这个选择只是惯例、个人偏好,还是有一些情况不能使用其中一个?
在使用、效率或背景技术方面是否有任何区别?
var mc:MovieClip = MovieClip(getChildByName("mc"));
和
var mc:MovieClip = getChildByName("mc") as MovieClip;
这个选择只是惯例、个人偏好,还是有一些情况不能使用其中一个?
这篇文章 很好地描述了两者之间的不同:
在 ActionScript 2 中,当转换失败时会返回 null,而在 ActionScript 3 中,将抛出 TypeError。使用 ActionScript 3 中的
as
操作符时,无论转换是否成功,都会返回数据类型的默认值。
as
还允许你强制转换为 Array
,而以前是不可能的,因为转换函数 Array()
优先级更高。
编辑: 关于性能,各种文章中提到,使用 as
比函数调用式的转换更快:[1] [2] [3]。第一篇引用的文章详细研究了性能差异,并报告了 as
快 4 倍至 4.5 倍。
编辑 2: 不仅在正常情况下使用 as
比其他方式快4到4.5倍,当你将 (cast)
样式转换包装在 try-catch 块中,并且实际上出现错误时,速度可能会更快,甚至是30到230倍。 在AS3中,如果您认为自己要做一些特殊的事情(可能会引发错误),那么清楚地表明您应该先看再跳。除非被API强制要求,否则永远不要使用try/catch,这也意味着永远不要使用(cast)
。即使没有抛出异常,查看try/catch的性能影响也很有启示性。即使在没有问题的情况下,设置try/catch块也会带来性能损失。
as
在AS3中比(cast)
运行时更高效和更快。
http://jacksondunstan.com/articles/830
结合所有其他因素,我认为完全没有理由使用(cast)
,应该完全避免使用。
下面撤回的评论实际上也提醒了我一个好的观点。如果您使用(cast)
,几乎可以肯定会发现自己会陷入必须尝试/捕获的情况中。
try{
SubType(foo).bar();
}catch(e:TypeError){
// Can't cast to SubType
}
这很慢而且难以忍受。唯一的解决方法是先进行is
检查。
if(foo is SubType){
SubType(foo).bar();
}
null
。”(这里就是这种情况)
有很多关于为什么null
是魔鬼的文章,但简而言之:null
不提供任何关于如何处理它的上下文信息。它是坏赋值、转换、未初始化成员等的结果吗?如果您尝试访问成员,AVM也会因此而出错,抛出非常难以追踪的边缘情况通用错误。此外,您会失去任何类型信息,您不知道空对象应该是什么类型。
还有...为什么感觉奇怪呢?(在强制转换之前调用is
) - Creyndersis
/as
的主要原因是因为失败的as
隐式地等于foo is Bar == false
。为什么要测试两次呢?你可以这样做:var foo:Bar = x as Bar;
,然后跟着写上if(foo){}
。我绝不会建议像这样调用成员(foo as Bar).member()
。 - scriptocalypseAS3 Casting one type to another 包含了这个问题的答案:使用 "as" 关键字将一个类型转换为另一个类型时,如果转换失败,则会赋值为 null
,否则会抛出 TypeError
。
在编程中,使用as
关键字是最佳实践。
as
的优点是不会抛出运行时错误(RTE)。例如,假设您有一个无法转换为MovieClip的类Dog
,则以下代码将引发RTE:
var dog:Dog = new Dog();
var mc:MovieClip = MovieClip(Dog);
as
会更安全,因为如果转换失败,它只会返回null,然后您可以自己检查错误,而不使用try
/catch
块:var dog:Dog = new Dog();
var mc:MovieClip = Dog as MovieClip;
if (mc)
//conversion succeeded
else
//conversion failed
在使用as运算符
之前,最好使用强制类型转换。只有在强制类型转换可能失败并且您希望表达式计算为null而不是抛出异常时才使用as运算符。
请这样做:
IUIComponent(child).document
(child as IUIComponent).document
关于启动或不启动 RTE,或返回 null,在处理加载到单独应用程序域中的 swf 中的错误时,存在显着差异。
使用 Loader.uncaughtErrorEvents 处理已加载 swf 的错误;如果我们像 'event.error as Error' 这样进行转换,则生成的错误将具有原始堆栈跟踪(与导致错误的 swf 中捕获的相同),而如果使用 Error(event.error)进行转换,则错误的堆栈跟踪将被当前堆栈跟踪更改(在其中进行了转换)。
示例代码:
if (event && event.error && event.error is Error) {
debug ("Casting with 'as Error'")
debugStackTrace (event.error as Error);
debug ("casting with 'Error (...)'");
debugStackTrace (Error (event.error));
}
示例输出:
Casting with 'as Error'
ReferenceError: Error # 1056
at Player / onEnterFrame ()
casting with 'Error (...)'
Error: ReferenceError: Error # 1056
at package :: HandlerClass / uncaughtErrorHandler ()
at EventInfo / listenerProxy ()
var mc:MovieClip = MovieClip(getChildByName("mc"));
会直接将其设置为movieclip
var mc:MovieClip = getChildByName("mc") as MovieClip;
如果必需的类型相同,将使mc的行为像movieclip一样
as
会更慢,所以一直相信着。你有什么想法吗? - Sunil D.