4 de enero de 2011

Cuidado con for...var en ActionScript (es diferente que en Java)

Una aplicación que hicimos con Flex, usando ActionScript 3, tenía un error. La causa fue que el ámbito (scope) de las variables en ActionScript es diferente que en Java. Al ser programadores que provenimos de Java, dimos por sentado que eran iguales.

El código en cuestión era semejante a lo siguiente:

function f () {
   for (...; ...; ...) {
      for (var j:int; ...; ...) {
         // Creíamos que j tenía un valor de cero cada vez
         // que se ejecutaba el ciclo anidado.
      }
   }
}

El compilador de ActionScript declara e inicializa sólo una vez la variable j dentro de la función f. Esto implica que, la segunda vez que se ejecuta el ciclo anidado, conserva el valor con el que terminó la ejecución anterior.

El error lo arreglamos inicializando explícitamente la variable.

function f () {
   for (...; ...; ...) {
      for (var j:int = 0; ...; ...) {
         // Ahora, j siempre inicia con un valor de cero.
      }
   }
}

Este comportamiento está descrito claramente en la documentación de ActionScript 3:

ActionScript 3.0, variables are always assigned the scope of the function or class in which they are declared. [...] ActionScript variables, unlike variables in C++ and Java, do not have block-level scope. [...] If you declare a variable inside a block of code, that variable will be available not only in that block of code, but also in any other parts of the function to which the code block belongs. —Adobe. Programming ActionScript 3.0 / ActionScript language and syntax / Variables. URL: http://livedocs.adobe.com/flex/3/html/03_Language_and_Syntax_07.html#118946. Accedido: 2011-01-04. (Archivado por WebCite®)

De hecho, el compilador mueve las declaraciones de variables el inicio de la función (a esto se le llama hoisting —subimiento, levantamiento o alzamiento), haciéndolas disponibles para todo el cuerpo de la función.

Creo que seré más cuidadoso en no presuponer cómo funciona el lenguaje en el que estoy programando.

No hay comentarios.:

Publicar un comentario