AS3:演员还是“as”?

时间:2013-01-10 22:20:16

标签: actionscript-3 flash casting coding-style conventions

之间是否存在使用,效率或背景技术的差异
var mc:MovieClip = MovieClip(getChildByName("mc"));

var mc:MovieClip = getChildByName("mc") as MovieClip;

选择只是约定,偏好或是否有不能使用的情况?

8 个答案:

答案 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

Coding Conventions

答案 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一样