Tipos de dados

Um tipo de dados define um conjunto de valores. Por exemplo, o tipo de dados Boolean é o conjunto de exatamente dois valores: true e false. Além do tipo de dados Boolean, o ActionScript 3.0 define vários tipos de dados mais comumente usados, como String, Number e Array. Você pode escolher seus próprios tipos de dados usando classes ou interfaces para definir um conjunto de valores personalizado. Todos os valores no ActionScript 3.0, sejam primitivos ou complexos, são objetos.

Um valor primitivo é aquele que pertence a um dos seguintes tipos de dados: Boolean, int, Number, String e uint. Trabalhar com valores primitivos, em geral, é mais rápido do que trabalhar com valores complexos, porque o ActionScript armazena valores primitivos de uma forma especial que torna as otimizações de memória e velocidade possíveis.

Nota: Para os leitores interessados nos detalhes técnicos, o ActionScript armazena valores primitivos internamente como objetos imutáveis. O fato de serem armazenados como objetos imutáveis significa que transmitir por referência, na prática, é o mesmo que transmitir por valor. Isso reduz o uso de memória e aumenta a velocidade de execução, porque as referências são significativamente menores do que os valores em si.

Um valor complexo é um valor que não é primitivo. Os tipos de dados que definem conjuntos de valores complexos incluem Array, Date, Error, Function, RegExp, XML e XMLList.

Muitas linguagens de programação distinguem os valores primitivos dos objetos delimitadores. Java, por exemplo, tem um primitivo int e a classe java.lang.Integer que o delimita. Os primitivos Java não são objetos, mas seus delimitadores são, o que torna os primitivos úteis para algumas operações e os objetos delimitadores mais adequados para outras operações. No ActionScript 3.0, os valores primitivos e seus objetos delimitadores são, na prática, indistinguíveis. Todos os valores, mesmo os primitivos, são objetos. O tempo de execução trata esses tipos primitivos como casos especiais que se comportam como objetos, mas não exige a sobrecarga normal associada à criação de objetos. Isso significa que as duas linhas de código a seguir são equivalentes:

var someInt:int = 3; 
var someInt:int = new int(3);

Todos os tipos de dados primitivos e complexos listados acima são definidos pelas classes centrais do ActionScript 3.0. As classes centrais permitem criar objetos usando os valores literais em vez do operador new. Por exemplo, você pode criar uma matriz usando um valor literal ou o construtor de classe Array, como a seguir:

var someArray:Array = [1, 2, 3]; // literal value 
var someArray:Array = new Array(1,2,3); // Array constructor

Verificação de tipos

A verificação de tipos pode ocorrer em tempo de compilação ou de execução. Linguagens tipificadas estatisticamente, como C++ e Java, executam a verificação de tipos em tempo de compilação. Linguagens tipificadas dinamicamente, como Smalltalk e Python, manipulam a verificação de tipos em tempo de execução. Como uma linguagem tipificada dinamicamente, o ActionScript 3.0 tem uma verificação de tipos em tempo de execução, mas também oferece suporte à verificação de tipos em tempo de compilação com um modo de compilador especial chamado modo estrito. No modo estrito, a verificação de tipos ocorre em tempo de compilação e de execução, mas no modo padrão, ela ocorre apenas em tempo de execução.

Linguagens tipificadas dinamicamente oferecem grande flexibilidade na estruturação do código, mas às custas de permitir que erros de tipo se manifestem em tempo de execução. Linguagens tipificadas estatisticamente relatam erros de tipo em tempo de compilação, mas exigem que as informações de tipo sejam conhecidas em tempo de compilação.

Verificação de tipos em tempo de compilação

A verificação de tipos em tempo de compilação é mais vantajosa em projetos grandes porque, conforme o tamanho de um projeto aumenta, a flexibilidade do tipo de dados se torna menos importante do que a rápida detecção de erros de tipo. É por isso que, por padrão, o compilador do ActionScript no Flash Professional e no Flash Builder é definido para ser executado no modo restrito.

Adobe Flash Builder

Você pode desabilitar o modo restrito no Flash Builder com as configurações do compilador do ActionScript na caixa de diálogo Propriedades do projeto.

Para fornecer a verificação de tipos em tempo de compilação, o compilador precisa conhecer as informações de tipo de dados para as variáveis ou expressões no seu código. Para declarar explicitamente um tipo de dados para uma variável, adicione o operador dois-pontos (:) seguido do tipo de dados como um sufixo para o nome da variável. Para associar um tipo de dados a um parâmetro, use o operador dois-pontos seguido do tipo de dados. Por exemplo, o seguinte código adiciona informações de tipo de dados ao parâmetro xParam e declara uma variável myParam com um tipo de dados explícito:

function runtimeTest(xParam:String) 
{ 
    trace(xParam); 
} 
var myParam:String = "hello"; 
runtimeTest(myParam);

No modo estrito, o compilador do ActionScript relata incompatibilidades de tipos como erros do compilador. Por exemplo, o código a seguir declara um parâmetro de função xParam, do tipo Object, mas depois tenta atribuir valores do tipo String e Number ao parâmetro. Isso gera um erro do compilador no modo estrito.

function dynamicTest(xParam:Object) 
{ 
    if (xParam is String) 
    { 
        var myStr:String = xParam; // compiler error in strict mode 
        trace("String: " + myStr); 
    } 
    else if (xParam is Number) 
    { 
        var myNum:Number = xParam; // compiler error in strict mode 
        trace("Number: " + myNum); 
    } 
}

Mesmo no modo estrito, porém, é possível optar seletivamente pela verificação de tipos em tempo de compilação deixando o lado direito de uma instrução de atribuição sem tipos. Você pode marcar uma variável ou expressão como sem tipo omitindo uma anotação de tipo ou usando a anotação de tipo especial de asterisco (*). Por exemplo, se o parâmetro xParam no exemplo anterior for modificado de forma que não tenha mais uma anotação de tipo, o código é compilado no modo estrito:

function dynamicTest(xParam) 
{ 
    if (xParam is String) 
    { 
        var myStr:String = xParam; 
        trace("String: " + myStr); 
    } 
    else if (xParam is Number) 
    { 
        var myNum:Number = xParam; 
        trace("Number: " + myNum); 
    } 
} 
dynamicTest(100) 
dynamicTest("one hundred");

Verificação de tipos em tempo de execução

A verificação de tipos em tempo de execução ocorrerá no ActionScript 3.0 se você compilar em modo restrito ou em modo de padrão. Considere uma situação em que o valor 3 é transmitido como um argumento para uma função que espera uma matriz. No modo estrito, o compilador irá gerar um erro, porque o valor 3 não é compatível com o tipo de dados Array. Se você desabilitar o modo estrito e executar no modo padrão, o compilador não reclamará sobre incompatibilidade de tipos, mas a verificação em tempo de execução resulta em um erro em tempo de execução.

O exemplo a seguir mostra uma função chamada typeTest() que espera um argumento Array mas tem um valor transmitido de 3. Isso gera um erro em tempo de execução no modo padrão, porque o valor 3 não é um membro do tipo de dados (Array) declarado do parâmetro.

function typeTest(xParam:Array) 
{ 
    trace(xParam); 
} 
var myNum:Number = 3; 
typeTest(myNum);  
// run-time error in ActionScript 3.0 standard mode

Também pode haver situações em que há um erro de tipo em tempo de execução mesmo durante a operação no modo estrito. Isso é possível se você usar o modo estrito, mas optar pela verificação de tipos em tempo de compilação, usando uma variável sem tipo. O uso de uma variável sem tipo não elimina a verificação de tipos, mas a suspende até o tempo de execução. Por exemplo, se a variável myNum do exemplo anterior não tiver um tipo de dados declarado, o compilador não pode detectar a incompatibilidade de tipos, mas o código vai gerar um erro de tempo de execução porque compara o valor do tempo de execução de myNum, que está definido como 3 como resultado da instrução de atribuição, com o tipo de xParam, que é definido com o tipo de dados Array.

function typeTest(xParam:Array) 
{ 
    trace(xParam); 
} 
var myNum = 3; 
typeTest(myNum);  
// run-time error in ActionScript 3.0

A verificação de tipos em tempo de execução também permite um uso mais flexível de herança que a verificação em tempo de compilação. Com a suspensão da verificação de tipos para o tempo de execução, o modo padrão permite referenciar as propriedades de uma subclasse mesmo que você a eleve. Uma elevação ocorrerá quando você usar uma classe base para declarar o tipo de uma ocorrência de classe, mas usar uma subclasse para instanciá-la. Por exemplo, você pode criar uma classe chamada ClassBase que pode ser estendida (classes com o atributo final não podem ser estendidas):

class ClassBase 
{ 
}

Depois, você pode criar uma subclasse de uma ClassBase chamada ClassExtender, que tem uma propriedade chamada someString, como a seguir:

class ClassExtender extends ClassBase 
{ 
    var someString:String; 
}

Usando as duas classes, é possível criar uma ocorrência de classe que é declarada usando o tipo de dados ClassBase, mas instanciada usando o construtor ClassExtender. Uma elevação é considerada uma operação segura, porque a classe base não contém nenhuma propriedade ou método que não esteja na subclasse.

var myClass:ClassBase = new ClassExtender();

Uma subclasse, porém, contém propriedades ou métodos que sua classe base não contém. Por exemplo, a classe ClassExtender contém a propriedade someString, que não existe na classe ClassBase. No modo padrão do ActionScript 3.0, é possível referenciar essa propriedade usando a ocorrência myClass sem gerar um erro de tempo de compilação, como mostra o seguinte exemplo:

var myClass:ClassBase = new ClassExtender(); 
myClass.someString = "hello"; 
// no error in ActionScript 3.0 standard mode

O operador is

O operador is permite testar se uma variável ou expressão é um membro de um determinado tipo de dados. Nas versões anteriores do ActionScript, o operador instanceof fornecia essa funcionalidade, mas, no ActionScript 3.0, o operador instanceof não deve ser usado para testar a associação de tipo de dados. O operador is deve ser usado no lugar do operador instanceof para verificação de tipos manual, porque a expressão x instanceof y apenas verifica a existência de x na cadeia de protótipos y (e, no ActionScript 3.0, a cadeia de protótipos não fornece um retrato completo da hierarquia de herança).

O operador is examina a hierarquia de herança apropriada e pode ser usado para verificar não apenas se um objeto é uma ocorrência de uma classe específica, mas também de uma classe que implementa uma determinada interface. O exemplo a seguir cria uma ocorrência da classe Sprite, chamada mySprite e usa o operador is para testar se mySprite é uma ocorrência das classes Sprite e DisplayObject e se implementa a interface IEventDispatcher:

var mySprite:Sprite = new Sprite(); 
trace(mySprite is Sprite); // true 
trace(mySprite is DisplayObject);// true 
trace(mySprite is IEventDispatcher); // true

O operador is verifica a hierarquia de herança e relata adequadamente que mySprite é compatível com as classes Sprite e DisplayObject (a classe Sprite é uma subclasse da classe DisplayObject). O operador is também verifica se mySprite é herdada de alguma classe que implementa a interface IEventDispatcher. Como a classe Sprite é herdada da classe EventDispatcher, que implementa a interface IEventDispatcher, o operador is relata corretamente que mySprite implementa a mesma interface.

O exemplo a seguir mostra os mesmos testes do exemplo anterior, mas com instanceof em vez do operador is. O operador instanceof identificará corretamente que mySprite é uma ocorrência de Sprite ou DisplayObject, mas retornará false quando usado para testar se mySprite implementa a interface IEventDispatcher.

trace(mySprite instanceof Sprite); // true 
trace(mySprite instanceof DisplayObject);// true 
trace(mySprite instanceof IEventDispatcher); // false

O operador as

O operador as também permite verificar se uma expressão é um membro de um determinado tipo de dados. Diferentemente do operador is, porém, o operador as não retorna um valor booleano. Em vez disso, o operador as retorna o valor da expressão em vez de true e null em vez de false. O exemplo a seguir mostra os resultados do uso do operador as em vez de is no caso simples de verificar se uma ocorrência de Sprite é um membro dos tipos de dados DisplayObject, IEventDispatcher e Number.

var mySprite:Sprite = new Sprite(); 
trace(mySprite as Sprite);                 // [object Sprite] 
trace(mySprite as DisplayObject);                 // [object Sprite] 
trace(mySprite as IEventDispatcher);                 // [object Sprite] 
trace(mySprite as Number);                                       // null

Durante o uso do operador as, o operando à direita deve ser um tipo de dados. Uma tentativa de usar uma expressão diferente de um tipo de dados como operando à direita resultará em um erro.

Classes dinâmicas

Uma classe dynamic define um objeto que pode ser alterado em tempo de execução adicionando ou alterando propriedades e métodos. Uma classe que não é dinâmica, como a classe String, é uma classe selada. Não é possível adicionar propriedades ou métodos a uma classe selada em tempo de execução.

As classes dinâmicas são criadas com o uso do atributo dynamic ao declarar uma classe. Por exemplo, o código a seguir cria uma classe dinâmica chamada Protean:

dynamic class Protean 
{ 
    private var privateGreeting:String = "hi"; 
    public var publicGreeting:String = "hello"; 
    function Protean() 
    { 
        trace("Protean instance created"); 
    } 
}

Se, posteriormente, você instanciar uma ocorrência da classe Protean, você pode adicionar propriedades ou métodos a ela fora da definição da classe. Por exemplo, o código a seguir cria uma ocorrência da classe Protean e adiciona uma propriedade chamada aString e outra chamada aNumber à ocorrência:

var myProtean:Protean = new Protean(); 
myProtean.aString = "testing"; 
myProtean.aNumber = 3; 
trace(myProtean.aString, myProtean.aNumber); // testing 3

As propriedades adicionadas a uma ocorrência de uma classe dinâmica são entidades de tempo de execução, por isso qualquer tipo de verificação é feito em tempo de execução. Não é possível adicionar uma anotação de tipo a uma propriedade adicionada dessa forma.

Você também pode adicionar um método à ocorrência myProtean definindo uma função e anexando-a a uma propriedade da ocorrência myProtean. O código a seguir move a instrução de rastreamento para um método chamado traceProtean():

var myProtean:Protean = new Protean(); 
myProtean.aString = "testing"; 
myProtean.aNumber = 3; 
myProtean.traceProtean = function () 
{ 
    trace(this.aString, this.aNumber); 
}; 
myProtean.traceProtean(); // testing 3

Os métodos criados dessa forma, entretanto, não têm acesso a qualquer propriedade ou método particular da classe Protean. Além disso, mesmo as referências às propriedades ou métodos públicos da classe Protean devem ser qualificados com a palavra-chave this ou o nome da classe. O exemplo a seguir mostra a tentativa do método traceProtean() de acessar as variáveis particulares e públicas da classe Protean.

myProtean.traceProtean = function () 
{ 
    trace(myProtean.privateGreeting); // undefined 
    trace(myProtean.publicGreeting); // hello 
}; 
myProtean.traceProtean();

Descrições de tipos de dados

Os tipos nativos primitivos incluem Boolean, int, Null, Number, String, uint e void. As classes base do ActionScript também definem os seguintes tipos de dados complexos: Object, Array, Date, Error, Function, RegExp, XML e XMLList.

Tipo de dados Boolean

O tipo de dados Boolean inclui dois valores: true e false. Nenhum outro valor é válido para variáveis do tipo Boolean. O valor padrão de uma variável Boolean que foi declarada mas não inicializada é false.

Tipo de dados int

O tipo de dados int é armazenado internamente como um inteiro de 32 bits e inclui o conjunto de inteiros de

-2.147.483.648 (-231) a 2.147.483.647 (231 - 1), inclusive. As versões anteriores do ActionScript ofereciam apenas o tipo de dados Number, que era usado para números inteiros e de ponto flutuante. No ActionScript 3.0, agora você tem acesso a tipos de computador de nível baixo para inteiros de 32 bits assinados e não assinados. Se a sua variável não tiver números de ponto flutuante, o uso do tipo de dados int em vez do tipo de dados Number é mais rápido e eficiente.

Para valores inteiros fora do intervalo dos valores int mínimo e máximo, use o tipo de dados Number, que pode manipular valores entre positivo e negativo 9.007.199.254.740.992 (valores inteiros de 53 bits). O valor padrão para variáveis do tipo de dados int é 0.

Tipo de dados Null

O tipo de dados Null contém apenas um valor, null. É o valor padrão para o tipo de dados String e todas as classes que definem tipos de dados complexos, inclusive a classe Object. Nenhum outro tipo de dados primitivo, como Boolean, Number, int e uint, contém o valor null. No tempo de execução, o valor null é convertido para o valor padrão apropriado se tentar atribuir null às variáveis do tipo Boolean, Number, int ou uint. Você não pode usar esse tipo de dados como uma anotação de tipo.

Tipo de dados Number

No ActionScript 3.0, o tipo de dados Number pode representar inteiros, inteiros não assinados e números de ponto flutuante. Entretanto, para maximizar o desempenho, você deve usar o tipo de dados Number somente para valores inteiros maiores do que os tipos int e uintde 32 bits podem armazenar ou para números de ponto flutuante. Para armazenar um número de ponto flutuante, inclua um ponto decimal no número. Se você omitir um ponto decimal, o número é armazenado como um inteiro.

O tipo de dados Number usa o formato de precisão dupla de 64 bits conforme especificado pelo Padrão IEEE para Aritmética de Ponto Flutuante Binário (IEEE-754). Esse padrão determina como os números de ponto flutuante são armazenados usando os 64 bits disponíveis. Um bit é usado para designar se o número é positivo ou negativo. Onze bits são usados para o expoente, que é armazenado como base 2. Os 52 bits restantes são usados para armazenar o significando (também chamado de mantissa), que é o número elevado à potência indicada pelo expoente.

Com o uso de alguns bits para armazenar um expoente, o tipo de dados Number pode armazenar números de ponto flutuante significativamente maiores do que se usasse todos os bits para o significando. Por exemplo, se o tipo de dados Number usasse os 64 bits para armazenar o significando, ele armazenaria um número tão grande quanto 265 - 1. Com o uso de 11 bits para armazenar um expoente, o tipo de dados Number pode elevar seu significando à potência de 21023.

Os valores máximo e mínimo que o tipo Number pode representar são armazenados em propriedades estáticas da classe Number chamadas Number.MAX_VALUE e Number.MIN_VALUE.

Number.MAX_VALUE == 1.79769313486231e+308 
Number.MIN_VALUE == 4.940656458412467e-324

Embora esse intervalo de números seja enorme, seu custo é a precisão. O tipo de dados Number usa 52 bits para armazenar o significando, por isso os números que exigem mais de 52 bits para fazer uma representação precisa, como a fração 1/3, são apenas aproximações. Se o seu aplicativo exibir precisão absoluta com números decimais, será necessário usar um software que implemente a aritmética de ponto flutuante decimal em vez da aritmética de ponto flutuante binário.

Durante o armazenamento de valore inteiros com o tipo de dados Number, somente os 52 bits do significando são usados. O tipo de dados Number usa esses 52 bits e um bit oculto especial para representar inteiros de -9.007.199.254.740.992 (-253) a 9.007.199.254.740.992 (253).

O valor NaN é usado não apenas como o valor padrão para variáveis do tipo Number, mas também como resultado de qualquer operação que deve retornar um número e não retorna. Por exemplo, se você tentar calcular a raiz quadrada de um número negativo, o resultado é NaN. Outros valores Number especiais incluem infinito positivo e infinito negativo.

Nota: O resultado da divisão por 0 será apenas NaN se o divisor também for 0. A divisão por 0 produzirá infinity quando o dividendo for positivo ou -infinity quando o dividendo for negativo.

Tipo de dados String

O tipo de dados String representa uma seqüência de caracteres de 16 bits. Os Strings são armazenados internamente como caracteres Unicode, usando o formato UTF-16, Eles são valores imutáveis, assim como na linguagem de programação Java. Uma operação sobre um valor String retorna uma nova ocorrência da seqüência de caracteres. O valor padrão para uma variável declarada com o tipo de dados String é null. O valor null não é igual ao string vazio (""). O valor null significa que a variável não tem valor armazenado nela, enquanto a sequência vazia de caracteres indica que a variável tem um valor que é um String que não contém caracteres.

Tipo de dados uint

O tipo de dados int é armazenado internamente como um inteiro não assinado de 32 bits e inclui o conjunto de inteiros de 0 a 4.294.967.295 (232 - 1), inclusive. Use o tipo de dados uint para circunstâncias especiais que exigem inteiros não negativos. Por exemplo, você deve usar o tipo de dados uint para representar os valores de cor de pixel, porque o tipo de dados int tem um bit de sinal interno que não é apropriado para manipular valores de cor. Para valores inteiros maiores do que o valor uint máximo, use o tipo de dados Number, que pode manipular valores inteiros de 53 bits. O valor padrão para variáveis do tipo de dados uint é 0.

Tipo de dados void

O tipo de dados void contém apenas um valor, undefined. Nas versões anteriores do ActionScript, undefined era o valor padrão para ocorrências da classe Object. No ActionScript 3.0, o valor padrão para ocorrências de Object é null. Se você tentar atribuir um valor undefined a uma ocorrência da classe Object, o valor é convertido para null. É possível atribuir apenas um valor de undefined a variáveis sem tipo. Variáveis sem tipo são aquelas que não possuem nenhuma anotação de tipo ou usam o símbolo asterisco (*) para a anotação de tipo. Você pode usar void apenas como uma anotação de tipo de retorno.

Tipo de dados Object

O tipo de dados Object é definido pela classe Object. A classe Object serve de classe base para todas as definições de classe no ActionScript. A versão do ActionScript 3.0 do tipo de dados Object difere das versões anteriores de três formas. Primeiro, o tipo de dados Object não é mais o tipo de dados padrão atribuído a variáveis sem nenhuma anotação de tipo. Em segundo lugar, o tipo de dados Object não inclui mais o valor undefined, que costumava ser o valor padrão das ocorrências Object. Em terceiro lugar, no ActionScript 3.0, o valor padrão para ocorrências da classe Object é null.

Nas versões anteriores do ActionScript, uma variável sem nenhuma anotação de tipo era automaticamente atribuída ao tipo de dados Object. Isso não acontece mais no ActionScript 3.0, que agora inclui a idéia de uma variável realmente sem tipo. As variáveis sem nenhuma anotação de tipo agora são consideradas sem tipo. Se preferir deixar mais claro para os leitores do código que sua intenção é deixar uma variável sem tipo, você pode usar o símbolo de asterisco (*) para a anotação de tipo, que é equivalente a omitir uma anotação de tipo. O exemplo a seguir mostra duas instruções equivalentes, que declaram uma variável sem tipo x:

var x 
var x:*

Somente variáveis sem tipo podem manter o valor undefined. Se você tentar atribuir o valor undefined a uma variável que possui um tipo de dados, o tempo de execução converte o valor undefined no valor padrão desse tipo de dados. Para as ocorrências do tipo de dados Object, o valor padrão é null, que significa que, se você tentar atribuir undefined a uma ocorrência de Object, o valor é convertido para null.

Conversões de tipo

Uma conversão de tipo ocorre quando um valor é transformado em um valor de um tipo de dados diferente. As conversões de tipo podem ser implícitas ou explícitas. A conversão implícita, que também é chamada de coerção, é realizada às vezes em tempo de execução. Por exemplo, se o valor 2 for atribuído a uma variável do tipo de dados Boolean, o valor 2 é convertido para o valor booleano true antes de atribuir o valor à variável. A conversão explícita, também chamada de projeção, ocorrerá quando o código instruir o compilador a tratar uma variável de um tipo de dados como se pertencesse a um tipo de dados diferente. Quando os valores primitivos estão envolvidos, a projeção realmente converte os valores de um tipo de dados para outro. Para projetar um objeto em um tipo diferente, use parênteses para delimitar o nome do objeto e preceda-o com o nome do novo tipo. Por exemplo, o seguinte código usa um valor booleano e projeta-o em um inteiro:

var myBoolean:Boolean = true; 
var myINT:int = int(myBoolean); 
trace(myINT); // 1

Conversões implícitas

As conversões implícitas acontecem em tempo de execução em diversos contextos:

  • Em instruções de atribuição

  • Quando os valores são transmitidos como argumentos de função

  • Quando os valores são retornados de funções

  • Em expressões que usam determinados operadores, como o operador de adição (+)

    Para tipos definidos pelo usuário, as conversões implícitas são bem-sucedidas quando o valor a ser convertido é uma ocorrência da classe de destino ou de uma classe derivada dela. Se uma conversão implícita não for bem-sucedida, ocorrerá um erro. Por exemplo, o seguinte código contém uma conversão implícita bem-sucedida e outra malsucedida:

    class A {} 
    class B extends A {} 
     
    var objA:A = new A(); 
    var objB:B = new B(); 
    var arr:Array = new Array(); 
     
    objA = objB; // Conversion succeeds. 
    objB = arr; // Conversion fails.

    Para os tipos primitivos, as conversões implícitas são tratadas chamando os mesmos algoritmos de conversão internos que são chamados pelas funções de conversão explícitas.

Conversões explícitas

É útil usar conversões explícitas, ou projeção, ao compilar no modo estrito, porque pode haver situações em que você não deseja que uma incompatibilidade de tipos gere um erro em tempo de compilação. Pode ser o caso de quando você sabe que a coerção converterá os valores corretamente em tempo de execução. Por exemplo, ao trabalhar com dados recebidos de um formulário, você pode querer contar com a coerção para converter determinados valores de seqüência de caracteres em valores numéricos. O código a seguir gera um erro em tempo de compilação, muito embora o código seja executado corretamente no modo padrão:

var quantityField:String = "3"; 
var quantity:int = quantityField; // compile time error in strict mode

Se quiser continuar a usar o modo estrito, mas preferir converter a seqüência de caracteres em um inteiro, você pode usar a conversão explícita da seguinte forma:

var quantityField:String = "3"; 
var quantity:int = int(quantityField); // Explicit conversion succeeds.

Projeção para int, uint e Number

É possível projetar qualquer tipo de dados em um dos três tipos de números: int, uint e Number. Se o número não puder ser convertido por alguma razão, o valor padrão de 0 é atribuído para os tipos de dados int e uint, e o valor padrão de NaN é atribuído para o tipo de dados Number. Se você converter um valor Boolean em um número, true se tornará o valor 1 e false se tornará o valor 0.

var myBoolean:Boolean = true; 
var myUINT:uint = uint(myBoolean); 
var myINT:int = int(myBoolean); 
var myNum:Number = Number(myBoolean); 
trace(myUINT, myINT, myNum); // 1 1 1 
myBoolean = false; 
myUINT = uint(myBoolean); 
myINT = int(myBoolean); 
myNum = Number(myBoolean); 
trace(myUINT, myINT, myNum); // 0 0 0

Os valores String que contêm apenas dígitos pode ser convertidos com êxito em um dos tipos de número. Os tipos de número também podem converter seqüências de caracteres que parecem números negativos ou que representam um valor hexadecimal (por exemplo, 0x1A). O processo de conversão ignora os caracteres de espaço em branco à esquerda e à direita no valor da seqüência de caracteres. Também é possível projetar seqüências de caracteres que se parecem com números de ponto flutuante usando Number(). A inclusão de um ponto decimal faz com que uint() e int() retornem um inteiro, truncando o decimal e os caracteres seguintes. Por exemplo, os seguintes valores de seqüência de caracteres podem ser projetados em números:

trace(uint("5")); // 5 
trace(uint("-5")); // 4294967291. It wraps around from MAX_VALUE 
trace(uint(" 27 ")); // 27 
trace(uint("3.7")); // 3 
trace(int("3.7")); // 3 
trace(int("0x1A")); // 26 
trace(Number("3.7")); // 3.7

Os valores String que contêm caracteres não numéricos retornarão 0 quando projetados com int() ou uint() e NaN quando projetados com Number(). O processo de conversão ignorará espaço em branco à esquerda e à direita, mas retornará 0 ou NaN se uma seqüência de caracteres tiver espaço em branco separando dois números.

trace(uint("5a")); // 0 
trace(uint("ten")); // 0 
trace(uint("17 63")); // 0

No ActionScript 3.0, a função Number() não suporta mais números octais ou de base 8. Se você fornecer uma seqüência de caracteres com um zero à esquerda para a função Number() do ActionScript 2.0, o número será interpretado como um número octal e convertido em seu equivalente decimal. Isso não acontece com a função Number() no ActionScript 3.0, que em vez disso ignora o zero à esquerda. Por exemplo, o seguinte código gera uma saída diferente quando compilado usando versões diferentes do ActionScript:

trace(Number("044"));  
// ActionScript 3.0 44 
// ActionScript 2.0 36

A projeção não é necessária quando um valor de um tipo numérico é atribuído a uma variável de um tipo numérico diferente. Mesmo no modo estrito, os tipos numéricos são implicitamente convertidos em outros tipos numéricos. Isso significa que, em alguns casos, quando o intervalo de um tipo for excedido, o resultado poderá gerar valores inesperados. Os seguintes exemplos compilam no modo estrito, embora alguns gerem valores inesperados:

var myUInt:uint = -3; // Assign int/Number value to uint variable 
trace(myUInt); // 4294967293 
 
var myNum:Number = sampleUINT; // Assign int/uint value to Number variable 
trace(myNum) // 4294967293 
 
var myInt:int = uint.MAX_VALUE + 1; // Assign Number value to uint variable 
trace(myInt); // 0 
 
myInt = int.MAX_VALUE + 1; // Assign uint/Number value to int variable 
trace(myInt); // -2147483648

A tabela a seguir resume os resultados da projeção para os tipos de dados Number, int ou uint a partir de outros tipos de dados.

Tipo de dados ou valor

Resultado da conversão em Number, int ou uint

Booleano

Se o valor for true, 1; caso contrário, 0.

Date

A representação interna do objeto Date, que é o número de milésimos de segundo desde a meia-noite de 1º de janeiro de 1970, hora universal.

null

0

Objeto

Se a ocorrência for null e convertida para Number, NaN; caso contrário, 0.

String

Um número se a sequência de caracteres puder ser convertido para número; do contrário, NaN se convertido para Number, ou 0, se convertido para int ou uint.

undefined

Se convertido em Number, NaN; se convertido em int ou uint, 0.

Projeção para Boolean

A projeção para Boolean a partir de qualquer tipo de dados numérico (uint, int e Number) resultará em false se o valor numérico for 0 e em true se não for. Para o tipo de dados Number, o valor NaN também resulta em false. O exemplo a seguir mostra os resultados da projeção dos números em -1, 0 e 1:

var myNum:Number; 
for (myNum = -1; myNum<2; myNum++) 
{ 
    trace("Boolean(" + myNum +") is " + Boolean(myNum)); 
}

A saída do exemplo mostra que, dos três números, somente 0 retorna um valor false:

Boolean(-1) is true 
Boolean(0) is false 
Boolean(1) is true

A projeção para Boolean de um valor String retornará false se a seqüência de caracteres for null ou vazia (""). Do contrário, retornará null.

var str1:String; // Uninitialized string is null. 
trace(Boolean(str1)); // false 
 
var str2:String = ""; // empty string 
trace(Boolean(str2)); // false 
 
var str3:String = " "; // white space only 
trace(Boolean(str3)); // true

A projeção para Boolean de uma ocorrência da classe Object retornará false se a ocorrência for null; do contrário, retornará true:

var myObj:Object; // Uninitialized object is null. 
trace(Boolean(myObj)); // false 
 
myObj = new Object(); // instantiate  
trace(Boolean(myObj)); // true

As variáveis Boolean obtém tratamento especial no modo estrito no que se refere a atribuir valores de qualquer tipo de dados a uma variável Boolean sem projeção. A coerção implícita de todos os tipos de dados para o tipo de dados Boolean ocorre mesmo no modo estrito. Em outras palavras, diferentemente de quase todos os outros tipos de dados, a projeção para Boolean não é necessária para evitar erros no modo estrito. Os seguintes exemplos compilam no modo estrito e se comportam conforme o esperado em tempo de execução:

var myObj:Object = new Object(); // instantiate  
var bool:Boolean = myObj; 
trace(bool); // true 
bool = "random string"; 
trace(bool); // true 
bool = new Array(); 
trace(bool); // true 
bool = NaN; 
trace(bool); // false

A tabela a seguir resume os resultados da projeção para o tipo de dados Boolean a partir de outros tipos de dados:

Tipo de dados ou valor

Resultado da conversão em Boolean

String

false se o valor for null ou uma seqüência de caracteres vazia (""); caso contrário, true.

null

false

Number, int ou uint

false se o valor for NaN ou 0; caso contrário, true.

Objeto

false se a ocorrência for null; caso contrário, true.

Projeção para String

A projeção para o tipo de dados String de qualquer tipo de dados numérico retorna uma representação de seqüência de caracteres do número. A projeção para o tipo de dados String de um valor Boolean retornará a seqüência de caracteres "true" se o valor for true e retornará a seqüência de caracteres "false" se o valor for false.

A projeção para String de uma ocorrência da classe Object retornará a seqüência de caracteres "null" se a ocorrência for null. Caso contrário, a projeção para o tipo String da classe Object retornará a seqüência de caracteres "[object Object]" .

A projeção para String de uma ocorrência da classe Array retorna uma sequência de caracteres composta por uma lista delimitada por vírgula de todos os elementos da matriz. Por exemplo, a seguinte projeção para o tipo de dados String retorna uma seqüência de caracteres contendo os três elementos da matriz:

var myArray:Array = ["primary", "secondary", "tertiary"]; 
trace(String(myArray)); // primary,secondary,tertiary

A projeção para String de uma ocorrência da classe Date retorna uma representação da seqüência de caracteres da data que a ocorrência contém. Por exemplo, o seguinte exemplo retorna uma representação da seqüência de caracteres da ocorrência da classe Date (a saída mostra o resultado para o Horário de Verão do Pacífico):

var myDate:Date = new Date(2005,6,1); 
trace(String(myDate)); // Fri Jul 1 00:00:00 GMT-0700 2005

A tabela a seguir resume os resultados da projeção para o tipo de dados String a partir de outros tipos de dados:

Tipo de dados ou valor

Resultado da conversão em String

Matriz

Uma sequência de caracteres composta por todos os elementos da matriz.

Booleano

"true" ou "false"

Date

Uma representação da seqüência de caracteres do objeto Date.

null

"null"

Number, int ou uint

Uma representação da seqüência de caracteres do número.

Objeto

Se a ocorrência for null, "null"; caso contrário, "[object Object]".