Un
tipo de datos
define un conjunto de valores. Por ejemplo, el tipo de datos Boolean es el conjunto de dos valores bien definidos:
true
y
false
. Además del tipo de datos Boolean, ActionScript 3.0 define varios tipos de datos utilizados con frecuencia, como String, Number y Array. Un programador puede definir sus propios tipos de datos utilizando clases o interfaces para definir un conjunto de valores personalizado. En ActionScript 3.0 todos los valores, tanto simples como complejos
,
son objetos.
Un
valor simple
es un valor que pertenece a uno de los tipos de datos siguientes: Boolean, int, Number, String y uint. Trabajar con valores simples suele ser más rápido que trabajar con valores complejos, ya que ActionScript almacena los valores simples de una manera especial que permite optimizar la velocidad y el uso de la memoria.
Nota:
para los interesados en los detalles técnicos, ActionScript almacena internamente los valores simples como objetos inmutables. El hecho de que se almacenen como objetos inmutables significa que pasar por referencia es en realidad lo mismo que pasar por valor. Esto reduce el uso de memoria y aumenta la velocidad de ejecución, ya que las referencias ocupan normalmente bastante menos que los valores en sí.
Un
valor complejo
es un valor que no es un valor simple. Entre los tipos de datos que definen conjuntos de valores complejos se encuentran Array, Date, Error, Function, RegExp, XML y XMLList.
Muchos lenguajes de programación distinguen entre los valores simples y los objetos que los contienen. Java, por ejemplo, tiene un valor simple int y la clase java.lang.Integer que lo contiene. Los valores simples de Java no son objetos, pero los objetos que los contienen sí, lo que hace que los valores simples sean útiles para algunas operaciones y los objetos contenedores sean más adecuados para otras operaciones. En ActionScript 3.0, los valores simples y sus objetos contenedores son, para fines prácticos, indistinguibles. Todos los valores, incluso los valores simples, son objetos. El motor de ejecución trata estos tipos simples como casos especiales que se comportan como objetos pero que no requieren la sobrecarga normal asociada a la creación de objetos. Esto significa que las dos líneas de código siguientes son equivalentes:
var someInt:int = 3;
var someInt:int = new int(3);
Todos los tipos de datos simples y complejos antes descritos se definen en las clases principales de ActionScript 3.0. Las clases principales permiten crear objetos utilizando valores literales en lugar de utilizar el operador
new
. Por ejemplo, se puede crear un conjunto utilizando un valor literal o el constructor de la clase Array, de la manera siguiente:
var someArray:Array = [1, 2, 3]; // literal value
var someArray:Array = new Array(1,2,3); // Array constructor
Verificación de tipos
La verificación de tipos puede tener lugar al compilar o en tiempo de ejecución. Los lenguajes con tipos estáticos, como C++ y Java, realizan la verificación de tipos en tiempo de compilación. Los lenguajes con tipos dinámicos, como Smalltalk y Python, realizan la verificación de tipos en tiempo de ejecución. Al ser un lenguaje con tipos dinámicos, ActionScript 3.0 ofrece verificación de tipos en tiempo de ejecución, pero también admite verificación de tipos en tiempo de compilación con un modo de compilador especial denominado
modo estricto
. En modo estricto, la verificación de tipos se realiza en tiempo de compilación y en tiempo de ejecución; en cambio, en modo estándar la verificación de tipos sólo se realiza en tiempo de ejecución.
Los lenguajes con tipos dinámicos ofrecen una gran flexibilidad para estructurar el código, pero a costa de permitir que se produzcan errores de tipo en tiempo de ejecución. Los lenguajes con tipos estáticos notifican los errores de tipo en tiempo de compilación, pero a cambio deben conocer la información de tipos en tiempo de compilación.
Verificación de tipos en tiempo de compilación
La verificación de tipos en tiempo de compilación se suele favorecer en los proyectos grandes ya que, a medida que el tamaño de un proyecto crece, la flexibilidad de los tipos de datos suele ser menos importante que detectar los errores de tipo lo antes posible. Ésta es la razón por la que, de manera predeterminada, el compilador de ActionScript de Flash Professional y Flash Builder está configurado para ejecutarse en modo estricto.
Adobe Flash Builder
Para desactivar el modo estricto en Flash Builder, vaya a la configuración del compilador de ActionScript en el cuadro de diálogo Propiedades del proyecto.
Para poder proporcionar verificación de tipos en tiempo de compilación, el compilador necesita saber cuáles son los tipos de datos de las variables o las expresiones del código. Para declarar explícitamente un tipo de datos para una variable, se debe añadir el operador dos puntos (
:
) seguido del tipo de datos como sufijo del nombre de la variable. Para asociar un tipo de datos a un parámetro, se debe utilizar el operador dos puntos seguido del tipo de datos. Por ejemplo, el código siguiente añade la información de tipo de datos al parámetro
xParam
y declara una variable
myParam
con un tipo de datos explícito:
function runtimeTest(xParam:String)
{
trace(xParam);
}
var myParam:String = "hello";
runtimeTest(myParam);
En modo estricto, el compilador de ActionScript notifica los tipos no coincidentes como errores de compilación. Por ejemplo, el código siguiente declara un parámetro de función
xParam
, de tipo Object, pero después intenta asignar valores de tipo String y Number a ese parámetro. Esto produce un error del compilador en modo estricto.
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);
}
}
Sin embargo, incluso en modo estricto se puede evitar selectivamente la verificación de tipos en tiempo de compilación dejando sin tipo el lado derecho de una sentencia de asignación. También se puede marcar una variable o expresión como variable o expresión sin tipo, omitiendo una anotación de tipo o utilizando la anotación de tipo asterisco (
*
). Por ejemplo, si se modifica el parámetro
xParam
del ejemplo anterior de forma que ya no tenga una anotación de tipo, el código se compilará de modo estricto:
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");
Verificación de tipos en tiempo de ejecución
ActionScript 3.0 realiza la verificación de tipos en tiempo de ejecución tanto si se compila en modo estricto como si se compila en modo estándar. Considérese una situación en la que se pasa el valor 3 como argumento a una función que espera un conjunto. En modo estricto, el compilador generará un error, ya que el valor 3 no es compatible con el tipo de datos Array. Al desactivar el modo estricto y entrar en modo estándar, el compilador no notificará acerca de los tipos no coincidentes, pero la verificación de tipos en tiempo de ejecución realizada por el motor de ejecución dará lugar a un error en tiempo de ejecución.
En el siguiente ejemplo se muestra una función denominada
typeTest()
que espera un argumento de tipo Array pero recibe el valor 3. Esto provoca un error en tiempo de ejecución en modo estándar, ya que el valor 3 no es un miembro del tipo de datos (Array) declarado para el parámetro.
function typeTest(xParam:Array)
{
trace(xParam);
}
var myNum:Number = 3;
typeTest(myNum);
// run-time error in ActionScript 3.0 standard mode
También puede haber situaciones en las que se produzca un error de tipo en tiempo de ejecución aunque se opere en modo estricto. Esto puede suceder si se usa el modo estricto pero se elige no verificar tipos en tiempo de compilación utilizando una variable sin tipo. Si se utiliza una variable sin tipo, no se elimina la verificación de tipos, sino que se aplaza hasta el tiempo de ejecución. Por ejemplo, si la variable
myNum
del ejemplo anterior no tiene un tipo de datos declarado, el compilador no podrá detectar los tipos no coincidentes, pero el código generará un error en tiempo de ejecución al comparar el valor en tiempo de ejecución de
myNum
, que está definido en 3 como resultado de la sentencia de asignación, con el tipo de
xParam
, que está definido como el tipo de datos Array.
function typeTest(xParam:Array)
{
trace(xParam);
}
var myNum = 3;
typeTest(myNum);
// run-time error in ActionScript 3.0
La verificación de tipos en tiempo de ejecución también permite un uso más flexible de la herencia que la verificación en tiempo de compilación. Al aplazar la verificación de tipos al tiempo de ejecución, el modo estándar permite hacer referencia a propiedades de una subclase aunque se realice una
conversión hacia arriba
. Una conversión hacia arriba se produce si se utiliza una clase base para declarar el tipo de una instancia de la clase y una subclase para crear la instancia. Por ejemplo, se puede crear una clase denominada ClassBase ampliable (las clases con el atributo
final
no se pueden ampliar):
class ClassBase
{
}
Posteriormente se puede crear una subclase de ClassBase denominada ClassExtender, con una propiedad denominada
someString
, como se indica a continuación:
class ClassExtender extends ClassBase
{
var someString:String;
}
Se pueden usar ambas clases para crear una instancia de clase que se declara con el tipo de datos de ClassBase, pero se crea con el constructor de ClassExtender. Una conversión hacia arriba se considera una operación segura porque la clase base no contiene ninguna propiedad o método que no esté en la subclase.
var myClass:ClassBase = new ClassExtender();
No obstante, una subclase contiene propiedades o métodos que la clase base no contiene. Por ejemplo, la clase ClassExtender contiene la propiedad
someString
, que no existe en la clase ClassBase. En el modo estándar de ActionScript 3.0 se puede hacer referencia a esta propiedad mediante la instancia de
myClass
sin generar un error de tiempo de compilación, como se muestra en el siguiente ejemplo:
var myClass:ClassBase = new ClassExtender();
myClass.someString = "hello";
// no error in ActionScript 3.0 standard mode
Operador is
El operador
is
permite comprobar si una variable o expresión es un miembro de un tipo de datos determinado. En versiones anteriores de ActionScript el operador
instanceof
proporcionaba esta funcionalidad, pero en ActionScript 3.0 no se debe utilizar el operador
instanceof
para comprobar la pertenencia a un tipo de datos. Para la verificación manual de tipos se debe utilizar el operador
is
en lugar del operador
instanceof
, ya que la expresión
x instanceof y
simplemente comprueba en la cadena de prototipos de
x
si existe
y
(y en ActionScript 3.0, la cadena de prototipos no proporciona una imagen completa de la jerarquía de herencia).
El operador
is
examina la jerarquía de herencia adecuada y se puede utilizar no sólo para verificar si un objeto es una instancia de una clase específica, sino también en el caso de que un objeto sea una instancia de una clase que implementa una interfaz determinada. En el siguiente ejemplo se crea una instancia de la clase Sprite denominada
mySprite
y se utiliza el operador
is
para comprobar si
mySprite
es una instancia de las clases Sprite y DisplayObject, y si implementa la interfaz IEventDispatcher.
var mySprite:Sprite = new Sprite();
trace(mySprite is Sprite); // true
trace(mySprite is DisplayObject);// true
trace(mySprite is IEventDispatcher); // true
El operador
is
comprueba la jerarquía de herencia y notifica que
mySprite
es compatible con las clases Sprite y DisplayObject (la clase Sprite es una subclase de la clase DisplayObject). El operador
is
también comprueba si
mySprite
hereda de alguna clase que implementa la interfaz IEventDispatcher. Como la clase Sprite hereda de la clase EventDispatcher, que implementa la interfaz IEventDispatcher, el operador
is
notifica correctamente que
mySprite
implementa la misma interfaz.
En el siguiente ejemplo se muestran las mismas pruebas del ejemplo anterior, pero con
instanceof
en lugar del operador
is
. El operador
instanceof
identifica correctamente que
mySprite
es una instancia de Sprite o DisplayObject, pero devuelve
false
cuando se usa para comprobar si
mySprite
implementa la interfaz IEventDispatcher.
trace(mySprite instanceof Sprite); // true
trace(mySprite instanceof DisplayObject);// true
trace(mySprite instanceof IEventDispatcher); // false
Operador as
El operador
as
también permite comprobar si una expresión es un miembro de un tipo de datos determinado. Sin embargo, a diferencia del operador
is
, el operador
as
no devuelve un valor booleano. El operador
as
devuelve el valor de la expresión en lugar de
true
y
null
en lugar de
false
. En el siguiente ejemplo se muestran los resultados de utilizar el operador
as
en lugar del operador
is
en el caso sencillo de comprobar si una instancia de Sprite es un miembro de los tipos de datos DisplayObject, IEventDispatcher y 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
Al utilizar el operador
as
, el operando de la derecha debe ser un tipo de datos. Si se intenta utilizar una expresión que no sea un tipo de datos como operando de la derecha se producirá un error.
Clases dinámicas
Una clase
dinámica
define un objeto que se puede modificar en tiempo de ejecución añadiendo o modificando propiedades y métodos. Una clase que no es dinámica, como la clase String, es una clase
cerrada
. No es posible añadir propiedades o métodos a una clase cerrada en tiempo de ejecución.
Para crear clases dinámicas se utiliza el atributo
dynamic
al declarar una clase. Por ejemplo, el código siguiente crea una clase dinámica denominada
Protean
:
dynamic class Protean
{
private var privateGreeting:String = "hi";
public var publicGreeting:String = "hello";
function Protean()
{
trace("Protean instance created");
}
}
Si posteriormente se crea una instancia de la clase
Protean
, se pueden añadir propiedades o métodos fuera de la definición de clase. Por ejemplo, el código siguiente crea una instancia de la clase
Protean
y añade una propiedad denominada
aString
y otra propiedad denominada
aNumber
a la instancia:
var myProtean:Protean = new Protean();
myProtean.aString = "testing";
myProtean.aNumber = 3;
trace(myProtean.aString, myProtean.aNumber); // testing 3
Las propiedades que se añaden a una instancia de una clase dinámica son entidades de tiempo de ejecución, por lo que no se realiza ninguna verificación de tipos en tiempo de ejecución. No se puede añadir una anotación de tipo a una propiedad añadida de esta manera.
También se puede añadir un método a la instancia de
myProtean
definiendo una función y asociando la función a una propiedad de la instancia de
myProtean
. El código siguiente mueve la sentencia trace a un método denominado
traceProtean()
:
var myProtean:Protean = new Protean();
myProtean.aString = "testing";
myProtean.aNumber = 3;
myProtean.traceProtean = function ()
{
trace(this.aString, this.aNumber);
};
myProtean.traceProtean(); // testing 3
Sin embargo, los métodos creados de esta manera no tienen acceso a ninguna propiedad o método privado de la clase Protean. Además, incluso las referencias a las propiedades o métodos públicos de la clase
Protean
deben calificarse con la palabra clave
this
o el nombre de la clase. En el siguiente ejemplo se muestra el intento de acceso del método
traceProtean()
a las variables privadas y las variables públicas de la clase
Protean
.
myProtean.traceProtean = function ()
{
trace(myProtean.privateGreeting); // undefined
trace(myProtean.publicGreeting); // hello
};
myProtean.traceProtean();
Descripción de los tipos de datos
Los tipos de datos simples son Boolean, int, Null, Number, String, uint y void. Las clases principales de ActionScript también definen los tipos de datos complejos siguientes: Object, Array, Date, Error, Function, RegExp, XML y XMLList.
Tipo de datos Boolean
El tipo de datos Boolean incluye dos valores:
true
y
false
. Ningún otro valor es válido para variables de tipo Boolean. El valor predeterminado de una variable booleana declarada pero no inicializada es
false
.
Tipo de datos int
El tipo de datos int se almacena internamente como un entero de 32 bits y consta del conjunto de enteros entre
-2.147.483.648 (-2
31
) a 2.147.483,647 (2
31
- 1), ambos incluidos. Las versiones anteriores de ActionScript sólo ofrecían el tipo de datos Number, que se usaba tanto para enteros como para números de coma flotante. En ActionScript 3.0 se tiene acceso a tipos de bajo nivel para enteros de 32 bits con o sin signo. Si la variable no va a usar números de coma flotante, es más rápido y eficaz utilizar el tipo de datos int en lugar del tipo de datos Number.
Para valores enteros que estén fuera del rango de los valores enteros mínimo y máximo, hay que utilizar el tipo de datos Number, que admite valores entre los valores positivo y negativo de 9.007.199.254.740.992 (valores enteros de 53 bits). El valor predeterminado para variables con tipo de datos int es 0.
Tipo de datos Null
El tipo de datos Null (nulo) tiene un único valor:
null
. Éste es el valor predeterminado para el tipo de datos String y para todas las clases que definen tipos de datos complejos, incluida la clase Object. Ninguno de los demás tipos de datos simples, como Boolean, Number, int y uint, contienen el valor
null
. En tiempo de ejecución, el valor
null
se convierte en el valor predeterminado adecuado si se intenta asignar
null
a las variables de tipo Boolean, Number, int o uint. Este tipo de datos no se puede utilizar como una anotación de tipo.
Tipo de datos Number
En ActionScript 3.0, el tipo de datos Number representa enteros, enteros sin signo y números de coma flotante. Sin embargo, para maximizar el rendimiento se recomienda utilizar el tipo de datos Number únicamente para valores enteros que ocupen más que los 32 bits que pueden almacenar los tipos de datos
int
y
uint
o para números de coma flotante. Para almacenar un número de coma flotante se debe incluir una coma decimal en el número. Si se omite un separador decimal, el número se almacenará como un entero.
El tipo de datos Number utiliza el formato de doble precisión de 64 bits especificado en la norma IEEE para aritmética binaria de coma flotante (IEEE-754). Esta norma especifica cómo se almacenan los números de coma flotante utilizando los 64 bits disponibles. Se utiliza un bit para designar si el número es positivo o negativo. El exponente, que se almacena como un número de base 2, utiliza once bits. Los 52 bits restantes se utilizan para almacenar la
cifra significativa
(también denominada
mantisa
), que es el número que se eleva a la potencia indicada por el exponente.
Al utilizar parte de los bits para almacenar un exponente, el tipo de datos Number puede almacenar números de coma flotante considerablemente más grandes que si se utilizaran todos los bits para la mantisa. Por ejemplo, si el tipo de datos Number utilizara los 64 bits para almacenar la mantisa, podría almacenar números hasta 2
65
-1. Al utilizar 11 bits para almacenar un exponente, el tipo de datos Number puede elevar la mantisa a una potencia de 2
1023
.
Los valores máximo y mínimo que el tipo Number puede representar se almacenan en propiedades estáticas de la clase Number denominadas
Number.MAX_VALUE
y
Number.MIN_VALUE
.
Number.MAX_VALUE == 1.79769313486231e+308
Number.MIN_VALUE == 4.940656458412467e-324
Aunque este rango de números es enorme, se pierde en precisión. El tipo de datos Number utiliza 52 bits para almacenar la mantisa y, como consecuencia, los números que requieren más de 52 bits para una representación precisa, como la fracción 1/3, son sólo aproximaciones. Si la aplicación requiere precisión absoluta con números decimales, hay que utilizar software que implemente aritmética decimal de coma flotante en lugar de aritmética binaria de coma flotante.
Al almacenar valores enteros con el tipo de datos Number, sólo se utilizarán los 52 bits de la mantisa. El tipo de datos Number utiliza estos 52 bits y un bit oculto especial para representar enteros entre -9.007.199.254.740.992 (-2
53
) y 9.007.199.254.740.992 (2
53
).
El valor
NaN
no sólo se utiliza como valor predeterminado para las variables de tipo
Number
, sino también como resultado de cualquier operación que debiera devolver un número y no lo haga. Por ejemplo, si se intenta calcular la raíz cuadrada de un número negativo, el resultado será
NaN
. Otros valores especiales de Number son
infinito positivo
e
infinito negativo
.
Nota:
el resultado de la división por
0
sólo es
NaN
si el divisor también es
0
. La división por
0
produce
infinity
cuando el dividendo es positivo o
-infinity
cuando el dividendo es negativo.
Tipo de datos String
El tipo de datos String representa una secuencia de caracteres de 16 bits. Las cadenas se almacenan internamente como caracteres Unicode empleando el formato UTF-16. Las cadenas son valores inmutables, igual que en el lenguaje de programación Java. Una operación sobre un valor de cadena (String) devuelve una nueva instancia de la cadena. El valor predeterminado de una variable declarada con el tipo de datos String es
null
. El valor
null
no es lo mismo que la cadena vacía (
""
). El valor
null
indica que la variable no tiene ningún valor almacenado, mientras que la cadena vacía significa que la variable tiene un valor que es una cadena sin caracteres.
Tipo de datos uint
El tipo de datos uint se almacena internamente como un entero sin signo de 32 bits y consta del conjunto de enteros entre 0 y 4.294.967.295 (2
32
- 1), ambos incluidos. El tipo de datos uint debe utilizarse en circunstancias especiales que requieran enteros no negativos. Por ejemplo, se debe utilizar el tipo de datos uint para representar valores de colores de píxeles, ya que el tipo de datos int tiene un bit de signo interno que no es apropiado para procesar valores de colores. Para valores enteros más grandes que el valor uint máximo, se debe utilizar el tipo de datos Number, que puede procesar valores enteros de 53 bits. El valor predeterminado para variables con tipo de datos uint es 0.
Tipo de datos Void
El tipo de datos void tiene un único valor:
undefined
. En las versiones anteriores de ActionScript,
undefined
era el valor predeterminado de las instancias de la clase Object. En ActionScript 3.0, el valor predeterminado de las instancias de Object es
null
. Si se intenta asignar el valor
undefined
a una instancia del objeto Object, dicho valor se convierte en
null
. Sólo se puede asignar un valor
undefined
a variables que no tienen tipo. Las variables sin tipo son variables que no tienen anotación de tipo o utilizan el símbolo de asterisco (
*
) como anotación de tipo. Sólo se puede usar
void
como anotación de tipo devuelto.
Tipo de datos Object
El tipo de datos Object (objeto) se define mediante la clase Object. La clase Object constituye la clase base para todas las definiciones de clase en ActionScript. La versión del tipo de datos Object en ActionScript 3.0 difiere de la de versiones anteriores en tres aspectos. En primer lugar, el tipo de datos Object ya no es el tipo de datos predeterminado que se asigna a las variables sin anotación de tipo. En segundo lugar, el tipo de datos Object ya no incluye el valor
undefined
que se utilizaba como valor predeterminado de las instancias de Object. Por último, en ActionScript 3.0, el valor predeterminado de las instancias de la clase Object es
null
.
En versiones anteriores de ActionScript, a una variable sin anotación de tipo se le asignaba automáticamente el tipo de datos Object. Esto ya no es así en ActionScript 3.0, que incluye el concepto de variable sin tipo. Ahora se considera que las variables sin anotación de tipo no tienen tipo. Si se prefiere dejar claro a los lectores del código que la intención es dejar una variable sin tipo, se puede utilizar el símbolo de asterisco (
*
) para la anotación de tipo, que equivale a omitir una anotación de tipo. En el siguiente ejemplo se muestran dos sentencias equivalentes que declaran una variable sin tipo
x
:
var x
var x:*
Sólo las variables sin tipo pueden contener el valor
undefined
. Si se intenta asignar el valor
undefined
a una variable que tiene un tipo de datos, el motor de ejecución convertirá el valor
undefined
en el valor predeterminado de dicho tipo de datos. Para las instancias del tipo de datos Object, el valor predeterminado es
null
, lo que significa que si se intenta asignar
undefined
a una instancia de Object, el valor se convierte en
null
.
Conversiones de tipos
Se dice que se produce una conversión de tipo cuando se transforma un valor en otro valor con un tipo de datos distinto. Las conversiones de tipo pueden ser
implícitas
o
explícitas
. La conversión implícita, también denominada
coerción
, se realiza en ocasiones en tiempo de ejecución. Por ejemplo, si a una variable del tipo de datos Boolean se le asigna el valor 2, este valor se convierte en el valor booleano
true
antes de asignar el valor a la variable. La conversión explícita, también denominada
conversión
, se produce cuando el código ordena al compilador que trate una variable de un tipo de datos como si perteneciera a un tipo de datos distinto. Si se usan valores simples, la conversión convierte realmente los valores de un tipo de datos a otro. Para convertir un objeto a otro tipo, hay que incluir el nombre del objeto entre paréntesis y anteponerle el nombre del nuevo tipo. Por ejemplo, el siguiente código toma un valor booleano y lo convierte en un entero:
var myBoolean:Boolean = true;
var myINT:int = int(myBoolean);
trace(myINT); // 1
Conversiones implícitas
Las conversiones implícitas se realizan en tiempo de ejecución en algunos contextos:
-
En sentencias de asignación
-
Cuando se pasan valores como argumentos de función
-
Cuando se devuelven valores desde funciones
-
En expresiones que utilizan determinados operadores, como el operador suma (
+
)
Para tipos definidos por el usuario, las conversiones implícitas se realizan correctamente cuando el valor que se va a convertir es una instancia de la clase de destino o una clase derivada de la clase de destino. Si una conversión implícita no se realiza correctamente, se producirá un error. Por ejemplo, el código siguiente contiene una conversión implícita correcta y otra incorrecta:
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 tipos simples, las conversiones implícitas se realizan llamando a los mismos algoritmos internos de conversión que utilizan las funciones de conversión explícita.
Conversiones explícitas
Resulta útil usar conversiones explícitas cuando se compila en modo estricto, ya que a veces no se desea que una discordancia de tipos genere un error en tiempo de compilación. Esto puede ocurrir, por ejemplo, cuando se sabe que la coerción convertirá los valores correctamente en tiempo de ejecución. Por ejemplo, al trabajar con datos recibidos desde un formulario, puede ser interesante basarse en la coerción para convertir determinados valores de cadena en valores numéricos. El código siguiente genera un error de tiempo de compilación aunque se ejecuta correctamente en modo estándar:
var quantityField:String = "3";
var quantity:int = quantityField; // compile time error in strict mode
Si se desea seguir utilizando el modo estricto pero se quiere convertir la cadena en un entero, se puede utilizar la conversión explícita de la manera siguiente:
var quantityField:String = "3";
var quantity:int = int(quantityField); // Explicit conversion succeeds.
Conversión a int, uint y Number
Cualquier tipo de datos se puede convertir en uno de los tres tipos numéricos siguientes: int, uint y Number. Si el número no puede convertirse por algún motivo, el valor predeterminado de 0 se asigna para los tipos de datos int y uint y el valor predeterminado de
NaN
se asigna para el tipo de datos Number. Si se convierte un valor booleano a un número,
true
se convierte en el valor 1 y
false
se convierte en el 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
Los valores de cadena que sólo contienen dígitos pueden convertirse correctamente en uno de los tipos numéricos. Los tipos numéricos también pueden convertir cadenas que parecen números negativos o cadenas que representan un valor hexadecimal (por ejemplo,
0x1A
). El proceso de conversión omite los caracteres de espacio en blanco iniciales y finales del valor de cadena. También se puede convertir cadenas que parecen números de coma flotante mediante
Number()
. La inclusión de un separador decimal hace que
uint()
e
int()
devuelvan un entero, truncando el separador decimal y los caracteres que siguen. Por ejemplo, los siguientes valores de cadena pueden convertirse en 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
Los valores de cadena que contienen caracteres no numéricos devuelven 0 cuando se convierten con
int()
o
uint()
, y
NaN
cuando se convierten con
Number()
. El proceso de conversión omite el espacio en blanco inicial y final, pero devuelve 0 o
NaN
si una cadena contiene espacio en blanco separando dos números.
trace(uint("5a")); // 0
trace(uint("ten")); // 0
trace(uint("17 63")); // 0
En ActionScript 3.0 la función
Number()
ya no admite números octales (de base 8). Si se suministra una cadena con un cero inicial a la función
Number()
de ActionScript 2.0, el número se interpreta como un número octal y se convierte en su equivalente decimal. Esto no es así con la función
Number()
de ActionScript 3.0, que omite el cero inicial. Por ejemplo, el código siguiente genera resultados distintos cuando se compila con versiones distintas de ActionScript:
trace(Number("044"));
// ActionScript 3.0 44
// ActionScript 2.0 36
La conversión no es necesaria cuando se asigna un valor de un tipo numérico a una variable de un tipo numérico distinto. Incluso en modo estricto, los tipos numéricos se convierten implícitamente a los otros tipos numéricos. Esto significa que en algunos casos pueden producirse valores inesperados cuando se supera el rango de un tipo. Todos los ejemplos siguientes se compilan en modo estricto, aunque algunos generarán 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
En la tabla siguiente se resumen los resultados de convertir a los tipos de datos Number, int o uint desde otros tipos de datos.
Tipo de datos o valor
|
Resultado de la conversión a Number, int o uint
|
Boolean
|
Si el valor es
true
, 1; de lo contrario, 0.
|
Date
|
Representación interna del objeto Date, que es el número de milisegundos transcurridos desde la medianoche del 1 de enero de 1970, hora universal.
|
null
|
0
|
Object
|
Si la instancia es
null
y se convierte a Number,
NaN
; de lo contrario, 0.
|
String
|
Un número si la cadena se puede convertir en uno; de lo contrario,
NaN
si se convierte en Number o 0 si se convierte en int o uint.
|
undefined
|
Si se convierte a Number,
NaN
; si se convierte a int o uint, 0.
|
Conversión a Boolean
La conversión a Boolean desde cualquiera de los tipos de datos numéricos (uint, int y Number) produce
false
si el valor numérico es 0 y
true
en caso contrario. Para el tipo de datos Number, el valor
NaN
también produce
false
. En el siguiente ejemplo se muestran los resultados de convertir los números -1, 0 y 1:
var myNum:Number;
for (myNum = -1; myNum<2; myNum++)
{
trace("Boolean(" + myNum +") is " + Boolean(myNum));
}
El resultado del ejemplo muestra que de los tres números, sólo 0 devuelve un valor
false
:
Boolean(-1) is true
Boolean(0) is false
Boolean(1) is true
La conversión a Boolean desde un valor String devuelve
false
si la cadena es
null
o una cadena vacía (
""
). De lo contrario, devuelve
true
.
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
La conversión a Boolean desde una instancia de la clase Object devuelve
false
si la instancia es
null
y
true
en caso contrario:
var myObj:Object; // Uninitialized object is null.
trace(Boolean(myObj)); // false
myObj = new Object(); // instantiate
trace(Boolean(myObj)); // true
En modo estricto, las variables Boolean reciben un tratamiento especial en el sentido de que se puede asignar valores de cualquier tipo de datos a una variable Boolean sin realizar una conversión. La coerción implícita desde todos los tipos de datos al tipo de datos Boolean se produce incluso en modo estricto. Es decir, a diferencia de lo que ocurre para casi todos los demás tipos de datos, la conversión a Boolean no es necesaria para evitar errores en modo estricto. Todos los ejemplos siguientes se compilan en modo estricto y se comportan de la manera esperada en tiempo de ejecución:
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
En la tabla siguiente se resumen los resultados de convertir al tipo de datos Boolean desde otros tipos de datos:
Tipo de datos o valor
|
Resultado de la conversión a Boolean
|
String
|
false
si el valor es
null
o la cadena vacía (
""
);
true
en caso contrario.
|
null
|
false
|
Number, int o uint
|
false
si el valor es
NaN
o 0;
true
en caso contrario.
|
Object
|
false
si la instancia es
null
;
true
en caso contrario.
|
Conversión a String
La conversión al tipo de datos String desde cualquiera de los tipos de datos numéricos devuelve una representación del número como una cadena. La conversión al tipo de datos String desde un valor booleano devuelve la cadena
"true"
si el valor es
true
y devuelve la cadena
"false"
si el valor es
false
.
La conversión al tipo de datos String desde una instancia de la clase Object devuelve la cadena
"null"
si la instancia es
null
. De lo contrario, la conversión al tipo String de la clase Object devuelve la cadena
"[object Object]"
.
La conversión a String desde una instancia de la clase Array devuelve una cadena que consta de una lista delimitada por comas de todos los elementos del conjunto. Por ejemplo, la siguiente conversión al tipo de datos String devuelve una cadena que contiene los tres elementos del conjunto:
var myArray:Array = ["primary", "secondary", "tertiary"];
trace(String(myArray)); // primary,secondary,tertiary
La conversión a String desde una instancia de la clase Date devuelve una representación de cadena de la fecha que contiene la instancia. Por ejemplo, el ejemplo siguiente devuelve una representación de cadena de la instancia de la clase Date (la salida muestra el resultado para el horario de verano de la costa del Pacífico de EE.UU.):
var myDate:Date = new Date(2005,6,1);
trace(String(myDate)); // Fri Jul 1 00:00:00 GMT-0700 2005
En la tabla siguiente se resumen los resultados de convertir al tipo de datos String desde otros tipos de datos.
Tipo de datos o valor
|
Resultado de la conversión a String
|
Array
|
Cadena que consta de todos los elementos de conjunto.
|
Boolean
|
"
true
" o "
false
"
|
Date
|
Una representación de cadena del objeto Date.
|
null
|
"null"
|
Number, int o uint
|
Una representación de cadena del número.
|
Object
|
Si la instancia es null,
"null"
; de lo contrario,
"[object Object]".
|
|
|
|