之间是否存在使用,效率或背景技术的差异
var mc:MovieClip = MovieClip(getChildByName("mc"));
和
var mc:MovieClip = getChildByName("mc") as MovieClip;
选择只是约定,偏好或是否有不能使用的情况?
答案 0 :(得分:21)
This article很好地描述了这些差异:
cast和as运算符之间的关键区别在于行为 失败了。在ActionScript 2中强制转换时,返回null。 在ActionScript 3中转换失败时,将引发TypeError。随着 作为ActionScript 3中的运算符,只要转换失败了默认值 返回数据类型。
as
还允许您转换为Array
,这在转换函数Array()
优先之前是不可能的。
编辑关于效果,报告使用as
比各种文章中的函数调用样式转换更快:[1] [2] [3]。引用的第一篇文章着眼于深度的性能差异,并报告as
的速度提高了4倍-4.5倍。
编辑2:在正常的最佳情况下,as
不仅快4x-4.5x,而且在try-catch块中包装(cast)
样式转换时并且错误实际上最终会被抛出,它更像是30x - 230x更快。在AS3中,如果你认为你要做一些特别的事情(因为它可能会引发错误),那么很明显你应该在跳跃之前先看一下。除非被API强制使用,否则永远不要使用try / catch,这实际上意味着永远不会(cast)
即使没有抛出异常,查看try / catch的性能影响也是有益的。即使在没有出错的情况下,设置try / catch块也会有性能损失。
答案 1 :(得分:4)
由于没有人直接回答性能问题,而且问题在于,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();
}
这似乎是错误和浪费。
答案 2 :(得分:2)
AS3 Casting one type to another包含的答案也是如此:转化失败时,“as”关键字会指定null
,否则会抛出TypeError
。
答案 3 :(得分:1)
最佳做法是使用as
关键字。
as
的优点是不会抛出RTE(运行时错误)。例如,假设您有一个无法转换为MovieClip的类Dog
;这段代码将抛出一个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
答案 4 :(得分:1)
喜欢使用强制转换来使用as operator
。仅当强制可能失败并且您希望表达式计算为null而不是抛出异常时,才使用as运算符。
这样做:
IUIComponent(child).document
不是这个:
(child as IUIComponent).document
答案 5 :(得分:1)
(演员)和“as”是两个完全不同的东西。虽然'as'只是告诉编译器将对象解释为给定类型(仅适用于相同或子类或数字/字符串转换),但(强制转换)尝试使用目标类的静态转换函数。这可能会失败(抛出错误)或返回目标类的新实例(不再是同一个对象)。这不仅解释了速度差异,还解释了Error事件的行为,如Alejandro P.S。所述。
含义很明显: 如果对象的类是编码器已知的而不是编译器已知的话,则使用'as'(因为由仅指定超类或'*'的接口进行混淆)。如果假定的类型(或与自动强制兼容的类型)不能100%保证,则建议使用之前的'is'检查或之后的空检查(更快)。
如果必须将对象实际转换为另一个类(如果可能的话),则使用(强制转换)。
答案 6 :(得分:0)
进一步启动或不启动RTE,或者返回null,当我们管理加载到单独应用程序域的swf中的错误时,存在显着差异。
使用Loader.uncaughtErrorEvents来处理加载的swf的错误;如果我们将' event.error转换为错误',则生成的错误将具有原始堆栈跟踪(与导致错误的swf中捕获的相同),而如果使用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 ()
答案 7 :(得分:0)
var mc:MovieClip = MovieClip(getChildByName("mc"));
将直接将其设置为movieclip
var mc:MovieClip = getChildByName("mc") as MovieClip;
会使mc像movieclip一样