两者在使用、效率或背景技术上有什么不同吗?
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;
?
选择只是惯例、偏好问题,还是在某些情况下您不能使用?
本文很好地描述了这些差异:
强制转换和 as 运算符之间的一个关键区别是失败时的行为。当 ActionScript 2 中的强制转换失败时,将返回 null。当 ActionScript 3 中的强制转换失败时,会引发 TypeError。使用 ActionScript 3 中的 as 运算符,只要转换失败,就会返回数据类型的默认值。
as
还允许您转换为Array
,这在以前是不可能的,因为转换函数Array()
优先。
编辑:关于性能,as
据报道使用比各种文章中的函数调用样式转换更快:[ 1 ][ 2 ][ 3 ]。引用的第一篇文章深入研究了性能差异,并报告说速度提高了as
4 到 4.5 倍。
编辑 2:在正常的最佳情况下,不仅as
速度快 4x-4.5x,而且当您将(cast)
样式转换包装在 try-catch 块中时,实际上最终抛出了一个错误,它更像是 30x - 230x 快。在 AS3 中,如果您认为您将要做一些特殊的事情(因为它可能会引发错误),那么很明显您应该始终在跳跃之前查看。除非 API 强制,否则永远不要使用 try/catch,实际上这意味着永远不要使用 try/catch(cast)
的性能影响,即使没有引发异常也是如此。即使在没有任何问题的情况下,设置 try/catch 块也会降低性能。
由于没有人直接回答性能方面的问题,而且在您的问题中,它as
在运行时比(cast)
在 AS3 中的效率和速度要快得多。
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();
}
这似乎是错误和浪费的。
AS3 将一种类型转换为另一种类型也包含回答此问题的答案:“as”关键字null
在转换失败时分配,否则它会抛出TypeError
.
最佳做法是使用as
关键字。
as
具有不引发 RTE(运行时错误)的优点。例如,假设您有一个Dog
无法转换为 MovieClip 的类;此代码将引发 RTE:
var dog:Dog = new Dog();
var mc:MovieClip = MovieClip(Dog);
TypeError:错误 #1034:类型强制失败:无法将 Dog 转换为 MovieClip。
为了使此代码“安全”,您必须将强制转换包含在try
/catch
块中。
另一方面,as
会更安全,因为如果转换失败,它只会返回 null ,然后您可以自己检查错误,而无需使用try
/catch
块:
var dog:Dog = new Dog();
var mc:MovieClip = Dog as MovieClip;
if (mc)
//conversion succeeded
else
//conversion failed
更喜欢使用强制转换而不是使用as operator
. 仅当强制可能失败并且您希望表达式计算为 null 而不是引发异常时,才使用 as 运算符。
做这个:
IUIComponent(child).document
不是这个:
(child as IUIComponent).document
(cast) 和 "as" 是两个完全不同的东西。虽然“as”只是告诉编译器将对象解释为给定类型(仅适用于相同或子类或数字/字符串转换),但 (cast) 尝试使用目标类的静态转换函数. 这可能会失败(抛出错误)或返回目标类的新实例(不再是同一个对象)。这不仅解释了速度差异,还解释了错误事件的行为,如 Alejandro PS 所述
含义很清楚:如果编码器知道对象的类但编译器不知道对象的类,则使用“as”(因为被只命名超类或“*”的接口混淆了)。如果假定的类型(或与自动强制兼容的类型)不能 100% 确定,则建议在之前进行“is”检查或之后(更快)进行空检查。
如果必须将对象实际转换为另一个类(如果可能的话),将使用 (cast)。
进一步启动或不启动 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"));
将直接设置为电影剪辑
var mc:MovieClip = getChildByName("mc") as MovieClip;
将使 mc 像电影剪辑一样,如果需要的类型相同