Home > Flash development, Flex development > AS3 casting String to Number?

AS3 casting String to Number?

Converting FlashVars parameters to properties is an example where you are forced to deal with strings and sometimes these values need to be numbers. I have been annoyed with with my own inconsistencies with how I test to see if the FlashVar casts correctly or should be rejected (because it had a character other than a number in the string). I was discovering that some techniques were giving false negatives. So I spent some time of trying to establish a best practice.

I considered these four techniques for casting a string to a Number:

  1. parseInt("1234");
  2. new Number("1234");
  3. "1234" as Number;
  4. Number("1234");

Below is the AS3 code and the trace results which I used to base my conclusions here.

Results:
Using "as Number" to cast a string to a Number looks like bad news to me. All other techniques preformed as expected. Casting a string such as "foo" using "as Number" to cast is to a strongly typed variable results with a false value when isNaN() is applied to it. This is the false negative I mentioned before. Even casting the string "1337" using "as Number" results in the value 0 which not only fails the falsies ternary test but is wrong.

Conclusions

  • don't use "as Number" to cast a string to a Number.
  • Using a "falsies ternary test" is not a great approach for string to number validation since "0" is a valid number and will correctly fail this test. Maybe that works well for your logic anyhow.

Discussion
Casting is perhaps the wrong term since I am converting a primitive to an object which isn't true polymorphism, but perhaps string is being treated as an object.

I talked to Ryan Frishberg at the recent 360|Flex in Indianapolis about this. Ryan works on the Flex SDK team at Adobe. He said that "new Number('foo')" make use of conversion methods that are not available to the technique "'foo' as Number" which will evaluate to null since this casting is not possible. String can't be a Number. Ok, that is the d'oh moment for me. Should know better.

It's problematic though, because it fails to report a run-time or compile-time error.

Actionscript:
  1. var n1a:Number = parseInt("foo");
  2. var n2a:Number = new Number("foo");
  3. var n3a:Number = "foo" as Number;
  4. var n4a:Number = Number("foo");
  5.  
  6. var n1b = parseInt("foo");
  7. var n2b = new Number("foo");
  8. var n3b = "foo" as Number;
  9. var n4b = Number("foo");
  10.  
  11. var n1c:Number = parseInt("1337");
  12. var n2c:Number = new Number("1337");
  13. var n3c:Number = "1337" as Number;
  14. var n4c:Number = Number("1337");
  15.  
  16. trace (".............. strong typed 'foo'");
  17. trace ("n1a: " + n1a);
  18. trace ("n2a: " + n2a);
  19. trace ("n3a: " + n3a);
  20. trace ("n4a: " + n4a);
  21. trace (".............. not strong typed 'foo'");
  22. trace ("n1b: " + n1b);
  23. trace ("n2b: " + n2b);
  24. trace ("n3b: " + n3b);
  25. trace ("n4b: " + n4b);
  26. trace (".............. Strong typed '1337'");
  27. trace ("n1c: " + n1c);
  28. trace ("n2c: " + n2c);
  29. trace ("n3c: " + n3c);
  30. trace ("n4c: " + n4c);
  31. trace (".............. isNaN n1");
  32. trace ("n1a: " + isNaN(n1a));
  33. trace ("n1b: " + isNaN(n1b));
  34. trace ("n1c: " + isNaN(n1c));
  35.  
  36. trace (".............. isNaN n2");
  37. trace ("n2a: " + isNaN(n2a));
  38. trace ("n2b: " + isNaN(n2b));
  39. trace ("n2c: " + isNaN(n2c));
  40.  
  41. trace (".............. isNaN n3");
  42. trace ("n3a: " + isNaN(n3a));
  43. trace ("n3b: " + isNaN(n3b));
  44. trace ("n3c: " + isNaN(n3c));
  45.  
  46. trace (".............. isNaN n4");
  47. trace ("n4a: " + isNaN(n4a));
  48. trace ("n4b: " + isNaN(n4b));
  49. trace ("n4c: " + isNaN(n4c));
  50.  
  51. trace (".............. falsies ternary test");
  52. (n1a)?trace("n1a: true"):trace("n1a: false");
  53. (n2a)?trace("n2a: true"):trace("n2a: false");
  54. (n3a)?trace("n3a: true"):trace("n3a: false");
  55. (n4a)?trace("n4a: true"):trace("n4a: false");
  56.  
  57. (n1b)?trace("n1b: true"):trace("n1b: false");
  58. (n2b)?trace("n2b: true"):trace("n2b: false");
  59. (n3b)?trace("n3b: true"):trace("n3b: false");
  60. (n4b)?trace("n4b: true"):trace("n4b: false");
  61.  
  62. (n1c)?trace("n1c: true"):trace("n1c: false");
  63. (n2c)?trace("n2c: true"):trace("n2c: false");
  64. (n3c)?trace("n3c: true"):trace("n3c: false");
  65. (n4c)?trace("n4c: true"):trace("n4c: false");

CODE:
  1. .............. strong typed 'foo'
  2. n1a: NaN
  3. n2a: NaN
  4. n3a: 0         //unexpected
  5. n4a: NaN
  6. .............. not strong typed 'foo'
  7. n1b: NaN
  8. n2b: NaN
  9. n3b: null    //unexpected
  10. n4b: NaN
  11. .............. Strong typed '1337'
  12. n1c: 1337
  13. n2c: 1337
  14. n3c: 0        //unexpected
  15. n4c: 1337
  16. .............. isNaN test
  17. n1a: true
  18. n2a: true
  19. n3a: false    //unexpected
  20. n4a: true
  21. n1b: true
  22. n2b: true
  23. n3b: false    //unexpected
  24. n4b: true
  25. n1c: false
  26. n2c: false
  27. n3c: false
  28. n4c: false
  29. .............. falsies ternary test
  30. n1a: false
  31. n2a: false
  32. n3a: false
  33. n4a: false
  34. n1b: false
  35. n2b: false
  36. n3b: false
  37. n4b: false
  38. n1c: true
  39. n2c: true
  40. n3c: false    //unexpected
  41. n4c: true

Categories: Flash development, Flex development Tags:
  1. July 6th, 2009 at 15:18 | #1

    the "as" operator isn't a conversion function like the others. It checks to see if the value used with as is of the type supplied. If so, that value is returned. If not, null is returned. If null is returned, the actual resulting variable value can differ depending on its type since, for example, Number-typed variables cannot be null, only numeric values and NaN (likely null would be converted to 0).

  1. July 6th, 2009 at 14:44 | #1