SlideShare uma empresa Scribd logo
1 de 61
Baixar para ler offline
JavaScript Puzzlers: Puzzles to Make You Think (and write fewer bugs)
       Charles Bihis | Computer Scientist




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   1
Who am I?




        Charles Bihis
              Computer Scientist
              Adobe Identity Team



              Blog: blogs.adobe.com/charles
              Twitter: @charlesbihis
              GitHub: github.com/charlesbihis


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   2
What can I expect?

        What are we going to talk about?                                            What are we NOT going to talk about?
              Puzzlers!                                                                 3rd- party libraries or frameworks
                   Maximus the Confused!                                                    e.g. jQuery, Node.js, etc.
                   Block Party!
                   That’s Odd!                                                          Bugs
                   Let’s Print Some ZIP-Codes!
                   Say What?!
                   Loopty Loop!
                   A Case of Mistaken Identity
                   Why Are We Bankrupt?!


              Will deal with only pure JavaScript
                   (i.e. no libraries!)


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   3
What is a Puzzler?




         A Puzzler is a very simple programming puzzle that demonstrates or exploits
         weird behaviours and quirky edge-cases of a given programming language.




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   4
How does this work?


  1.         Code – I introduce the code.

  2.         Question – I pose a multiple-choice question and you guess what the
                       answer is…think hard!

  3.         Walkthrough – I walk through a reasonable explanation.

  4.         Answer – I tell you the real answer.

  5.         Moral – How can you avoid making mistakes like this in your own code.

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   5
JavaScript Puzzler – Maximus the Confused!


var commodusRule = 'thumbsUp';
alert('Maximus the ' + (commodusRule === 'thumbsUp') ? 'Gladiator' : 'Merciful');




      What does this print?

      a) Maximus the Gladiator                                                    c) Error


      b) Maximus the Merciful                                                     d) None of the above

                                                                                   prints only "Gladiator"

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   6
But why?


        Order of operations dictates that the binary “+” operator takes precedence over the conditional “?”
         operator.


      'Maximus the ' + (commodusRule === 'thumbsUp') ? 'Gladiator' : 'Merciful';




      *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                        7
But why?


        Order of operations dictates that the binary “+” operator takes precedence over the conditional “?”
         operator.


                                                       'Maximus the true' ? 'Gladiator' : 'Merciful';




      *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                        8
But why?


        Order of operations dictates that the binary “+” operator takes precedence over the conditional “?”
         operator.


                                                                                     'Gladiator';




      *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                        9
But why?


        Order of operations dictates that the binary “+” operator takes precedence over the conditional “?”
         operator.


                                                                                     'Gladiator';



        According to the MDN (Mozilla Developer Network), the binary “+” operator has a precedence of 6
         while the conditional “?” operator has a precedence of 15.


              Note: This is below MOST commonly used operators (i.e. “*”, “/”, “%”, “<“, “>>” “!=”, “===“, etc).




      *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                        10
JavaScript Puzzler – Maximus the Confused…FIXED!


var commodusRule = 'thumbsUp';
alert('Maximus the ' + (commodusRule === 'thumbsUp') ? 'Gladiator' : 'Merciful');




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   11
JavaScript Puzzler – Maximus the Confused…FIXED!


var commodusRule = 'thumbsUp';
alert('Maximus the ' + (commodusRule === 'thumbsUp' ? 'Gladiator' : 'Merciful'));




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   12
Moral

        Be aware of order-of-operations!




        Be explicit and place parenthesis accordingly to ensure correct
         and predictable order of execution.




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   13
JavaScript Puzzler – Block Party!

  // global var
  var name = "World!";
                                                                                   What does this print?

  (function() {
                            // check if "name" defined                             a) “Hello, World!”
                            if (typeof name === "undefined") {
                                                      // local "shadow" var        b) “Hello, Mr. Bond.”
                                                      var name = "Mr. Bond.";
                                                      alert("Hello, " + name);
                                                                                   c) “Hello, ”
                            } else {
                                                      alert("Hello, " + name);
                            }                                                      d) None of the above

  })();

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   14
But why?

  1.         No block scope!

                                                 for (var i = 0; i < MAX; i++)
                                                 {
                                                       // do something
                                                 }
                                                 alert(i);   // Note: "i" exists here!


  2.         “Hoisting”

                                                 alert(i);   // Note: "i" exists here too!
                                                 for (var i = 0; i < MAX; i++)
                                                 {
                                                       // do something
                                                 }

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   15
But why?

  1.         No block scope!

                                                 for (var i = 0; i < MAX; i++)
                                                 {
                                                       // do something
                                                 }
                                                 alert(i);   // Note: "i" exists here!


  2.         “Hoisting”
                                                 var i;
                                                 alert(i); // Note: "i" exists here too!
                                                 for (i = 0; i < MAX; i++)
                                                 {
                                                       // do something
                                                 }
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   16
JavaScript Puzzler – Block Party…FIXED!

  // global var
  var name = "World!";


  (function() {
                            // check if "name" defined
                            if (typeof name === "undefined") {
                                                      // local "shadow" var
                                                      var name = "Mr. Bond.";
                                                      alert("Hello, " + name);
                            } else {
                                                      alert("Hello, " + name);
                            }
  })();

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   17
JavaScript Puzzler – Block Party…FIXED!

  // global var
  var name = "World!";

  (function() {
         var name;                     // declaration hoisted here
         // check if "name" defined
         if (typeof name === "undefined") {
                // local "shadow" var
                name = "Mr. Bond.";    // assignment remains here
                alert("Hello, " + name);
         } else {
                alert("Hello, " + name);
         }
  })();

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   18
JavaScript Puzzler – Block Party…FIXED!

  // global var
  var name = "World!";


  (function() {
                            var name = "Mr. Bond.";
                            // check if "name" defined
                            if (typeof name === "undefined") {
                                                      alert("Hello, " + name);
                            } else {
                                                      alert("Hello, " + name);
                            }
  })();


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   19
Moral

        There is no block-level scoping in JavaScript




        Declare ALL of your variables at the top of your function




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   20
JavaScript Puzzler – That’s Odd!

  (function(){
                            var values = [7, 4, '13', Infinity, -9];
                                                                                                  What does this print?
                            for (var i = 0; i < values.length; i++) {
                                                      if (isOdd(values[i])) {
                                                                              alert(values[i]);   a) 7, 13
                                                      }
                            }                                                                     b) 7, 13, Infinity, -9
  })();

                                                                                                  c) 7, -9
  function isOdd(num) {
                            return num % 2 == 1;
  }                                                                                               d) 7, 13, -9



© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                  21
But why?


        Let’s take a closer look…


                            7 % 2        =                                    1     //   displays
                            4 % 2        =                                    2     //   does NOT display
                            13 % 2       =                                    1     //   displays
                            Infinity % 2 =                                    NaN   //   does NOT display
                            -9 % 2       =                                    -1    //   does NOT display




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                22
But why?

        -9 % 2 = -1? Really?



        JavaScript shares the same behavior as the Java implementation of the modulus (%) operator.
         That is, it must satisfy the following identity function for all integer values a and non-zero integer
         values b.


                                                                              (a / b) * b + (a % b) == a



        A side-implication of this behavior is that the result will have the same sign as the left operand!




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.               23
JavaScript Puzzler – That’s Odd…FIXED!

  (function(){
                            var values = [7, 4, '13', Infinity, -9];
                            for (var i = 0; i < values.length; i++) {
                                                      if (isOdd(values[i])) {
                                                                              alert(values[i]);
                                                      }
                            }
  })();


  function isOdd(num) {
                            return num % 2 == 1;
  }


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                  24
JavaScript Puzzler – That’s Odd…FIXED!

  (function(){
                            var values = [7, 4, '13', Infinity, -9];
                            for (var i = 0; i < values.length; i++) {
                                                      if (isOdd(values[i])) {
                                                                              alert(values[i]);
                                                      }
                            }
  })();


  function isOdd(num) {
                            return num % 2 != 0;
  }


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                  25
Moral



        Be careful about the signs of operands when using the modulus
         operator.




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   26
JavaScript Puzzler – Let’s Print Some ZIP Codes!
  // array of 5 valid zip-codes
  var zipCodes = new Array("93021",                                                What does this print?
                           "02392",
                           "20341",                                                a) 93021
                           "08163",                                                   19
                                                                                                   Firefox
                                                                                      20341
                           "32959");                                                  32959

  // let's do something with each zip-code                                         b) 93021
  // for now, display them                                                            2392
                                                                                      20341        Chrome
  for (var i = 0; i < zipCodes.length; i++) {
                                                                                      8163
                                                                                      32959
                       // sanity check
                       if (!isNaN(parseInt(zipCodes[i])) &&                        c) 93021
                                   parseInt(zipCodes[i]) > 0) {                       20341
                             alert(parseInt(zipCodes[i]));                            32959
                       }
                                                                                   d) It varies

  }
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   27
But why?

        Syntax


                            var num = parseInt(string, radix);                                            // "radix" is optional


        When you omit the optional “radix” parameter, the following behavior takes place:
                   If the input string begins with “0x” or “0X”, radix of 16 is used (i.e. hexadecimal)
                   If the input string begins with “0”, radix 8 is used (i.e. octal) OR radix 10 is used (i.e. decimal)
                   If the input string begins with any other values, radix 10 is used (i.e. decimal)


        Particularly when dealing with string values with leading 0’s, Mozilla had this to say…

                            Exactly which radix is chosen is implementation-dependent.
                            For this reason ALWAYS SPECIFY A RADIX WHEN USING parseInt.

      *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                          28
But why?

        Another important note about the parseInt() API…

                            If parseInt encounters a character that is not a numeral in the
                            specified radix, it ignores it and all succeeding characters
                            and returns the integer value parsed up to that point.



        A closer look…


                  parseInt("93021")                                           =   93021                    //   displays
                  parseInt("02392")                                           =   (2 * 8) + (3 * 1) = 19   //   displays
                  parseInt("20341")                                           =   20341                    //   displays
                  parseInt("08163")                                           =   0                        //   does NOT display
                  parseInt("32959")                                           =   32959                    //   displays

      *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                          29
JavaScript Puzzler – Let’s Print Some ZIP Codes…FIXED!
  // array of 5 valid zip-codes
  var zipCodes = new Array("93021",
                           "02392",
                           "20341",
                           "08163",
                           "32959");

  // let's do something with each zip-code
  // for now, display them
  for (var i = 0; i < zipCodes.length; i++) {

                       // sanity check
                       if (!isNaN(parseInt(zipCodes[i])) &&
                                   parseInt(zipCodes[i]) > 0) {
                             alert(parseInt(zipCodes[i]));
                       }

  }
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   30
JavaScript Puzzler – Let’s Print Some ZIP Codes…FIXED!
  // array of 5 valid zip-codes
  var zipCodes = new Array("93021",
                           "02392",
                           "20341",
                           "08163",
                           "32959");

  // let's do something with each zip-code
  // for now, display them
  for (var i = 0; i < zipCodes.length; i++) {

                       // sanity check
                       if (!isNaN(parseInt(zipCodes[i], 10)) &&                    // radix value added
                                   parseInt(zipCodes[i], 10) > 0) {                      // here too
                             alert(parseInt(zipCodes[i], 10));                           // and here too
                       }

  }
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   31
Moral

        parseInt() takes an optional radix parameter.



        Omitting this optional parameter will cause unpredictable
         behavior across browsers.



        Be explicit and ALWAYS include the radix parameter.


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   32
JavaScript Puzzler – Say What?!


     function sayHello(name) {
           alert('Hello, ' + name);
     }

     sayHello('</script><script>alert("BOOM!");</script>');



                      What does this print?

                      a) alert("BOOM!“);

                      b) Hello, </script><script>alert("BOOM!");</script>

                      c) BOOM!

                      d) Error


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   33
But why?

        Let’s take a look at the code again…


                                                  function sayHello(name) {
                                                        alert('Hello, ' + name);
                                                  }

                                                  sayHello('</script><script>alert("BOOM!");</script>');




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   34
But why?

        Let’s take a look at the code again…

                             <script>
                                   function sayHello(name) {
                                         alert('Hello, ' + name);
                                   }

                                   sayHello('</script><script>alert("BOOM!");</script>');
                             </script>



        When a browser renders a page, first the HTML parser will parse the page and tokenize out all of
         the tags.
        Only after this is done, will it then allow the JavaScript parser to tokenize and execute whatever
         tokens the HTML parser believes are JavaScript scripts!

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   35
But why?

        Let’s take a look at the code again…

                             <script>
                                   function sayHello(name) {
                                         alert('Hello, ' + name);
                                   }

                                   sayHello('</script><script>alert("BOOM!");</script>');
                             </script>



        Armed with this knowledge, we can see that the HTML parser will send 2 scripts to the JavaScript
         parser to tokenize and execute…
              <script>function sayHello(name) { alert('Hello, ' + name); } sayHello('</script>
              <script>alert("BOOM!");</script>


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   36
A closer look

        Again, the HTML parser will send these two script tags to the JavaScript parser…
              <script>function sayHello(name) { alert('Hello, ' + name); } sayHello('</script>
              <script>alert("BOOM!");</script>




        If that name parameter is user-controlled, perhaps taken as input from the browser, or pulled from
         a datasource, whatever, then this is an open invitation for XSS attacks!



        Errors like this can expose huge security holes which may allow an attacker to potentially take
         over a user’s browser!




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   37
JavaScript Puzzler – Say What?!...FIXED!

        In this particular case, the fix must be done on the server-side.


        We want to eliminate the <script></script> tags from appearing in the source in the first place.


        Suggested solution is to use the OWASP ESAPI APIs…
              Stands for “The Open Web Application Security Project” “Enterprise Security API”
              https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API
              Have API bindings in all major languages including…
                   Java
                   Dot NET
                   PHP
                   JavaScript
                   Python
                   PHP

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   38
JavaScript Puzzler – Say What?!...FIXED!

        For this particular Puzzler, we want to use ESAPI.encoder().encodeForJavaScript()


        Doing this on the server to JavaScript-encode the user-inputted variable, name, we get what we
         expect…




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   39
Moral

        NEVER . TRUST . THE . USER



        Validate your input.



        Encode your output appropriately.
          i.e. HTML-encode for HTML
                URL-encode for URLs
                JavaScript-encode for JavaScript
                etc.



        Use standard libraries (i.e. don’t reinvent the wheel).


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   40
JavaScript Puzzler – Loopty Loop!




                                                                                                      What does this print?
  var END = 9007199254740992;                                                 // Math.pow(2, 53)
                                                                                                      a) 0
  var START = END - 100;

  var count = 0;                                                                                      b) 100
  for (var i = START; i <= END; i++) {
        count++;
                                                                                                      c) 101
  }
  alert(count);
                                                                                                      d) None of the above
                                                                                                    enters infinite loop



© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.           41
But why?

        9007199254740992 is a special number. Particularly, it is 2^53.




        Why is this special?




        First, we need to know something about how JavaScript represents numbers.




      *Reference: http://ecma262-5.com/ELS5_HTML.htm#Section_8.5
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   42
But why?

        JavaScript numbers abide by the IEEE Standard for Floating-Point Arithmetic (IEEE 754).


        As such, all numbers in JavaScript are represented by double-precision 64-bit floating point
         values…
                                                                                                          exponent

                                                                                                              -4
                                                                              1.2345 = 12345 x 10

                                                                                             mantissa


        In binary…                                                       63 62              53 52                     0

                                                                          1    11...111          11111111111...111

                                                                     sign         exponent                  mantissa
      *Reference: http://ecma262-5.com/ELS5_HTML.htm#Section_8.5
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.                          43
But why?

        2^53 is the largest exact integral value that can be represented in JavaScript!


        From the ECMA specification…

                      Note that all the positive and negative integers whose magnitude
                      is no greater than 2^53 are representable in the Number type.



        What does this mean?

                                      var numA = Math.pow(2, 53);
                                      var numB = numA + 1;
                                      alert(numA === numB);   // true!


      *Reference: http://ecma262-5.com/ELS5_HTML.htm#Section_8.5
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   44
JavaScript Puzzler – Loopty Loop…FIXED!




  var END = 9007199254740992;                                                 // Math.pow(2, 53)
  var START = END - 100;

  var count = 0;
  for (var i = START; i <= END; i++) {
        count++;
  }
  alert(count);




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.          45
JavaScript Puzzler – Loopty Loop…FIXED!




  var START = 0;
  var END = 100;

  var count = 0;
  for (var i = START; i <= END; i++) {
        count++;
  }
  alert(count);




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   46
Moral

        Be aware of your number representations and number ranges!




        There are REAL limitations imposed by your computer. When
         dealing with large (or important) numbers, know them!




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   47
JavaScript Puzzler – A Case of Mistaken Identity!

  function showCase(value) {
           switch(value) {
                    case "A":                                                      What does this print?
                             alert("Case A was selected.");
                             break;
                    case "B":                                                      a) Case A was selected.
                             alert("Case B here!");
                             break;
                    case "C":                                                      b) This is Case C.
                             alert("This is Case C.");
                             break;
                    default:
                                                                                   c) Error
                             alert("Don't know what happened.");
                             break;
           }
  }                                                                                d) Don’t know what
                                                                                      happened.
  showCase(new String("A"));

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   48
But why?

        The switch statement in JavaScript internally uses the strict equality operator (i.e. ===) as opposed
         to the non-strict equality operator (i.e. ==).


        The strict equality operator behaves exactly as the non-strict version, except that no type-
         conversions are done.


        So, when the switch statement evaluates equality, it checks that the following are true…
              Their types are equal
              Their uncast values are equal


        Notice, we invoked showCase() with a new String object.

                            alert(typeof "A");                                     // "string"
                            alert(typeof new String("A"));                         // "object"

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   49
JavaScript Puzzler – A Case of Mistaken Identity…FIXED!

  function showCase(value) {
           switch(value) {
                    case "A":
                             alert("Case A was selected.");
                             break;
                    case "B":
                             alert("Case B here!");
                             break;
                    case "C":
                             alert("This is Case C.");
                             break;
                    default:
                             alert("Don't know what happened.");
                             break;
           }
  }

  showCase(new String("A"));

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   50
JavaScript Puzzler – A Case of Mistaken Identity…FIXED!

  function showCase(value) {
           switch(value) {
                    case "A":
                             alert("Case A was selected.");
                             break;
                    case "B":
                             alert("Case B here!");
                             break;
                    case "C":
                             alert("This is Case C.");
                             break;
                    default:
                             alert("Don't know what happened.");
                             break;
           }
  }

  showCase("A");

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   51
Moral

        Get used to using the strict equality operator when possible. It will make you more aware of type
         conversions and true equalities.



        From Douglas Crockford’s book “JavaScript: The Good Parts”…


                           JavaScript has two sets of equality operators: === and !==, and their evil twins == and !=.
                           The good ones work the way you would expect. The evil twins do the right thing when the
                           operands are of the same type, but if they are of different types, they attempt to coerce the
                           values, the rules by which they do that are complicated and unmemorable.




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   52
JavaScript Puzzler – Why Are We Bankrupt?!




                                                                                              What does this print?
  var costOfCandy = 0.60;                                                     // 60 cents     a) 0

  function calculateChange(cost, paid) {
        return paid - cost;                                                                   b) 0.2
  }
                                                                                              c) 0.20
  // pay for candy with 80 cents
  alert(calculateChange(costOfCandy, 0.80));
                                                                                              d) None of the above

                                                                                             0.20000000000000007



© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.          53
But why?

        As we learned from a previous Puzzler, all JavaScript numbers use the IEEE 754 floating-point
         arithmetic specification.



        Because of this, values are not represented exactly, but rather as a fraction.



        Some non-integer values simply CANNOT be expressed exactly in this way. They must be
         approximated.


                            Example:
                            123.45 =                                   12345 * 10^-2              // exact
                            1 / 3   =                                  0.333333333333333 * 10^0   // approximation!


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.             54
JavaScript Puzzler – Why Are We Bankrupt?!...FIXED!




  var costOfCandy = 0.60;                                                     // 60 cents

  function calculateChange(cost, paid) {
        return paid - cost;
  }

  // pay for candy with 80 cents
  alert(calculateChange(costOfCandy, 0.80));




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.          55
JavaScript Puzzler – Why Are We Bankrupt?!...FIXED!

  // Use only integer math when dealing with money! To do this,
  // represent your money in terms of cents to begin with!
  //
  //    e.g. use 1599 instead of 15.99 to represent $15.99

  var costOfCandy = 60;                                                       // 60 cents

  function calculateChange(cost, paid) {
        return paid - cost;
  }

  // pay for candy with 80 cents
  alert(calculateChange(costOfCandy, 80));




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.          56
Moral

        Floating-point arithmetic can be inaccurate when representing fractions.


        When dealing with money, deal in terms of cents! This makes all of your calculations integer-
         calculations, which are exact!


        Not completely exact, though…


        Remember from our last Puzzler, it is exact only up until the largest representable integer value…
              9007199254740992 (i.e. 2^52)


        So, as long as you are dealing with less than $9 quintillion, you’re fine using integer arithmetic in
         JavaScript :)


      *Reference: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.        57
That’s it!




                                                                              Questions?




© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.       58
Any favorites?

                                                                Puzzlers!
                                                                  Maximus the Confused!

                                                                  Block Party!

                                                                  That’s Odd!

                                                                  Let’s Print Some ZIP-Codes!

                                                                  Say What?!

                                                                  Loopty Loop!

                                                                  A Case of Mistaken Identity

                                                                  Why Are We Bankrupt?!

© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.      59
Thanks for coming!




        Charles Bihis
              Computer Scientist
              Adobe Identity Team



              Blog: blogs.adobe.com/charles
              Twitter: @charlesbihis
              GitHub: github.com/charlesbihis


© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.   60
© 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.

Mais conteúdo relacionado

Mais procurados

Bajaj Auto Financial Analysis
Bajaj Auto Financial AnalysisBajaj Auto Financial Analysis
Bajaj Auto Financial Analysisyush313
 
SWOT_Analysis_of_2_wheeler_automobile_industry_in_india, A_seminar_by_Mohan_K...
SWOT_Analysis_of_2_wheeler_automobile_industry_in_india, A_seminar_by_Mohan_K...SWOT_Analysis_of_2_wheeler_automobile_industry_in_india, A_seminar_by_Mohan_K...
SWOT_Analysis_of_2_wheeler_automobile_industry_in_india, A_seminar_by_Mohan_K...Mohan Kumar G
 
Revisionismo del holocausto
Revisionismo del holocaustoRevisionismo del holocausto
Revisionismo del holocaustoRamón Copa
 
Bajaj Auto Co Introduction
Bajaj Auto Co IntroductionBajaj Auto Co Introduction
Bajaj Auto Co IntroductionPraful Metange
 
Mahindra xuv 500 pricing strategy
Mahindra xuv 500 pricing strategyMahindra xuv 500 pricing strategy
Mahindra xuv 500 pricing strategyNikhil Bhagat
 
A project report on analysis of the pre owned car market in hublli of true value
A project report on analysis of the pre owned car market in hublli of true valueA project report on analysis of the pre owned car market in hublli of true value
A project report on analysis of the pre owned car market in hublli of true valueBabasab Patil
 
Maruti suzuki ppt
Maruti suzuki pptMaruti suzuki ppt
Maruti suzuki pptSwati Garg
 
A project report of international business enviornment on comparative study o...
A project report of international business enviornment on comparative study o...A project report of international business enviornment on comparative study o...
A project report of international business enviornment on comparative study o...Projects Kart
 
Tata Ace Marketing concept
Tata Ace Marketing conceptTata Ace Marketing concept
Tata Ace Marketing conceptRiturajhans
 
Hero honda project by robin & group.
Hero honda project  by robin & group.Hero honda project  by robin & group.
Hero honda project by robin & group.mvskrishna
 
The New Role of Marketing in a Networked Global Economy
The New Role of Marketing in a Networked Global EconomyThe New Role of Marketing in a Networked Global Economy
The New Role of Marketing in a Networked Global EconomyNexo Corporation Srl
 
Maruti udyog limited bcg matrix
Maruti udyog limited  bcg matrixMaruti udyog limited  bcg matrix
Maruti udyog limited bcg matrixKonok Mondal
 
Porter' s five forces of maruti suzuki
Porter' s five forces of maruti suzukiPorter' s five forces of maruti suzuki
Porter' s five forces of maruti suzukiHaripriya Ramesh
 
A study on brand awarness of cbr 250 r in jsp honda pvt.ltd
A study on brand awarness of cbr 250 r in jsp honda pvt.ltdA study on brand awarness of cbr 250 r in jsp honda pvt.ltd
A study on brand awarness of cbr 250 r in jsp honda pvt.ltdPrasath Panneer
 
Automobile sector in India
Automobile sector in IndiaAutomobile sector in India
Automobile sector in IndiaSandip Kadam
 
Maruti Suzuki 2017 (WHITE PAPER PRESENTATION)
Maruti Suzuki 2017 (WHITE PAPER PRESENTATION)Maruti Suzuki 2017 (WHITE PAPER PRESENTATION)
Maruti Suzuki 2017 (WHITE PAPER PRESENTATION)PAUL issac
 
Comparative analysis on customer satisfaction b/w hero an bajaj
Comparative analysis on customer satisfaction b/w hero an bajajComparative analysis on customer satisfaction b/w hero an bajaj
Comparative analysis on customer satisfaction b/w hero an bajajDaksh Goyal
 
KTM, READY TO RACE.
KTM, READY TO RACE. KTM, READY TO RACE.
KTM, READY TO RACE. Navin Rai
 

Mais procurados (20)

Rubber Internal Mixer Selection Questionnaire
Rubber Internal Mixer Selection QuestionnaireRubber Internal Mixer Selection Questionnaire
Rubber Internal Mixer Selection Questionnaire
 
Bajaj Auto Financial Analysis
Bajaj Auto Financial AnalysisBajaj Auto Financial Analysis
Bajaj Auto Financial Analysis
 
SWOT_Analysis_of_2_wheeler_automobile_industry_in_india, A_seminar_by_Mohan_K...
SWOT_Analysis_of_2_wheeler_automobile_industry_in_india, A_seminar_by_Mohan_K...SWOT_Analysis_of_2_wheeler_automobile_industry_in_india, A_seminar_by_Mohan_K...
SWOT_Analysis_of_2_wheeler_automobile_industry_in_india, A_seminar_by_Mohan_K...
 
Revisionismo del holocausto
Revisionismo del holocaustoRevisionismo del holocausto
Revisionismo del holocausto
 
Bajaj Auto Co Introduction
Bajaj Auto Co IntroductionBajaj Auto Co Introduction
Bajaj Auto Co Introduction
 
Mahindra xuv 500 pricing strategy
Mahindra xuv 500 pricing strategyMahindra xuv 500 pricing strategy
Mahindra xuv 500 pricing strategy
 
A project report on analysis of the pre owned car market in hublli of true value
A project report on analysis of the pre owned car market in hublli of true valueA project report on analysis of the pre owned car market in hublli of true value
A project report on analysis of the pre owned car market in hublli of true value
 
Maruti suzuki ppt
Maruti suzuki pptMaruti suzuki ppt
Maruti suzuki ppt
 
A project report of international business enviornment on comparative study o...
A project report of international business enviornment on comparative study o...A project report of international business enviornment on comparative study o...
A project report of international business enviornment on comparative study o...
 
Tata Ace Marketing concept
Tata Ace Marketing conceptTata Ace Marketing concept
Tata Ace Marketing concept
 
Hero honda project by robin & group.
Hero honda project  by robin & group.Hero honda project  by robin & group.
Hero honda project by robin & group.
 
The New Role of Marketing in a Networked Global Economy
The New Role of Marketing in a Networked Global EconomyThe New Role of Marketing in a Networked Global Economy
The New Role of Marketing in a Networked Global Economy
 
Maruti udyog limited bcg matrix
Maruti udyog limited  bcg matrixMaruti udyog limited  bcg matrix
Maruti udyog limited bcg matrix
 
Porter' s five forces of maruti suzuki
Porter' s five forces of maruti suzukiPorter' s five forces of maruti suzuki
Porter' s five forces of maruti suzuki
 
A study on brand awarness of cbr 250 r in jsp honda pvt.ltd
A study on brand awarness of cbr 250 r in jsp honda pvt.ltdA study on brand awarness of cbr 250 r in jsp honda pvt.ltd
A study on brand awarness of cbr 250 r in jsp honda pvt.ltd
 
Maruti ppt
Maruti pptMaruti ppt
Maruti ppt
 
Automobile sector in India
Automobile sector in IndiaAutomobile sector in India
Automobile sector in India
 
Maruti Suzuki 2017 (WHITE PAPER PRESENTATION)
Maruti Suzuki 2017 (WHITE PAPER PRESENTATION)Maruti Suzuki 2017 (WHITE PAPER PRESENTATION)
Maruti Suzuki 2017 (WHITE PAPER PRESENTATION)
 
Comparative analysis on customer satisfaction b/w hero an bajaj
Comparative analysis on customer satisfaction b/w hero an bajajComparative analysis on customer satisfaction b/w hero an bajaj
Comparative analysis on customer satisfaction b/w hero an bajaj
 
KTM, READY TO RACE.
KTM, READY TO RACE. KTM, READY TO RACE.
KTM, READY TO RACE.
 

Semelhante a JavaScript Puzzlers!

JavaScript Puzzlers!
JavaScript Puzzlers!JavaScript Puzzlers!
JavaScript Puzzlers!Charles Bihis
 
Priming Java for Speed at Market Open
Priming Java for Speed at Market OpenPriming Java for Speed at Market Open
Priming Java for Speed at Market OpenAzul Systems Inc.
 
Joxean Koret - Database Security Paradise [Rooted CON 2011]
Joxean Koret - Database Security Paradise [Rooted CON 2011]Joxean Koret - Database Security Paradise [Rooted CON 2011]
Joxean Koret - Database Security Paradise [Rooted CON 2011]RootedCON
 
Creating Custom Dojo Widgets Using WTP
Creating Custom Dojo Widgets Using WTPCreating Custom Dojo Widgets Using WTP
Creating Custom Dojo Widgets Using WTPnsandonato
 
I thought you were my friend - Malicious Markup
I thought you were my friend - Malicious MarkupI thought you were my friend - Malicious Markup
I thought you were my friend - Malicious MarkupMario Heiderich
 
Raising the Bar on Robotics Code Quality
Raising the Bar on Robotics Code QualityRaising the Bar on Robotics Code Quality
Raising the Bar on Robotics Code QualityThomas Moulard
 
Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​ Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​ Luciano Mammino
 
[ServerlessDays Zurich 2019] Solving complex business use cases in a serverle...
[ServerlessDays Zurich 2019] Solving complex business use cases in a serverle...[ServerlessDays Zurich 2019] Solving complex business use cases in a serverle...
[ServerlessDays Zurich 2019] Solving complex business use cases in a serverle...duypnguyen
 
Managing JavaScript Complexity
Managing JavaScript ComplexityManaging JavaScript Complexity
Managing JavaScript ComplexityJarrod Overson
 
MongoDB World 2019: Don't Panic - The Hitchhiker's Guide to the MongoDB Galaxy
MongoDB World 2019: Don't Panic - The Hitchhiker's Guide to the MongoDB GalaxyMongoDB World 2019: Don't Panic - The Hitchhiker's Guide to the MongoDB Galaxy
MongoDB World 2019: Don't Panic - The Hitchhiker's Guide to the MongoDB GalaxyMongoDB
 
XSS Without Browser
XSS Without BrowserXSS Without Browser
XSS Without Browserkosborn
 
NanoSec Conference 2019: Code Execution Analysis in Mobile Apps - Abdullah Jo...
NanoSec Conference 2019: Code Execution Analysis in Mobile Apps - Abdullah Jo...NanoSec Conference 2019: Code Execution Analysis in Mobile Apps - Abdullah Jo...
NanoSec Conference 2019: Code Execution Analysis in Mobile Apps - Abdullah Jo...Hafez Kamal
 
Developing cross platform desktop application with Ruby
Developing cross platform desktop application with RubyDeveloping cross platform desktop application with Ruby
Developing cross platform desktop application with RubyAnis Ahmad
 
Guidelines! sorry guys you have to!
Guidelines! sorry guys you have to!Guidelines! sorry guys you have to!
Guidelines! sorry guys you have to!Davide Di Pumpo
 
LISA Qooxdoo Tutorial Handouts
LISA Qooxdoo Tutorial HandoutsLISA Qooxdoo Tutorial Handouts
LISA Qooxdoo Tutorial HandoutsTobias Oetiker
 
Questioning the status quo
Questioning the status quoQuestioning the status quo
Questioning the status quoIvano Pagano
 
node.js - Eventful JavaScript on the Server
node.js - Eventful JavaScript on the Servernode.js - Eventful JavaScript on the Server
node.js - Eventful JavaScript on the ServerDavid Ruiz
 
A Practitioner’s guide to Hardened JavaScript
A Practitioner’s guide to Hardened JavaScriptA Practitioner’s guide to Hardened JavaScript
A Practitioner’s guide to Hardened JavaScriptTom Van Cutsem
 
Jailbreak Detector Detector
Jailbreak Detector DetectorJailbreak Detector Detector
Jailbreak Detector DetectorNick Mooney
 

Semelhante a JavaScript Puzzlers! (20)

JavaScript Puzzlers!
JavaScript Puzzlers!JavaScript Puzzlers!
JavaScript Puzzlers!
 
Priming Java for Speed at Market Open
Priming Java for Speed at Market OpenPriming Java for Speed at Market Open
Priming Java for Speed at Market Open
 
Joxean Koret - Database Security Paradise [Rooted CON 2011]
Joxean Koret - Database Security Paradise [Rooted CON 2011]Joxean Koret - Database Security Paradise [Rooted CON 2011]
Joxean Koret - Database Security Paradise [Rooted CON 2011]
 
Creating Custom Dojo Widgets Using WTP
Creating Custom Dojo Widgets Using WTPCreating Custom Dojo Widgets Using WTP
Creating Custom Dojo Widgets Using WTP
 
I thought you were my friend - Malicious Markup
I thought you were my friend - Malicious MarkupI thought you were my friend - Malicious Markup
I thought you were my friend - Malicious Markup
 
Sjug aug 2010_cloud
Sjug aug 2010_cloudSjug aug 2010_cloud
Sjug aug 2010_cloud
 
Raising the Bar on Robotics Code Quality
Raising the Bar on Robotics Code QualityRaising the Bar on Robotics Code Quality
Raising the Bar on Robotics Code Quality
 
Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​ Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​
 
[ServerlessDays Zurich 2019] Solving complex business use cases in a serverle...
[ServerlessDays Zurich 2019] Solving complex business use cases in a serverle...[ServerlessDays Zurich 2019] Solving complex business use cases in a serverle...
[ServerlessDays Zurich 2019] Solving complex business use cases in a serverle...
 
Managing JavaScript Complexity
Managing JavaScript ComplexityManaging JavaScript Complexity
Managing JavaScript Complexity
 
MongoDB World 2019: Don't Panic - The Hitchhiker's Guide to the MongoDB Galaxy
MongoDB World 2019: Don't Panic - The Hitchhiker's Guide to the MongoDB GalaxyMongoDB World 2019: Don't Panic - The Hitchhiker's Guide to the MongoDB Galaxy
MongoDB World 2019: Don't Panic - The Hitchhiker's Guide to the MongoDB Galaxy
 
XSS Without Browser
XSS Without BrowserXSS Without Browser
XSS Without Browser
 
NanoSec Conference 2019: Code Execution Analysis in Mobile Apps - Abdullah Jo...
NanoSec Conference 2019: Code Execution Analysis in Mobile Apps - Abdullah Jo...NanoSec Conference 2019: Code Execution Analysis in Mobile Apps - Abdullah Jo...
NanoSec Conference 2019: Code Execution Analysis in Mobile Apps - Abdullah Jo...
 
Developing cross platform desktop application with Ruby
Developing cross platform desktop application with RubyDeveloping cross platform desktop application with Ruby
Developing cross platform desktop application with Ruby
 
Guidelines! sorry guys you have to!
Guidelines! sorry guys you have to!Guidelines! sorry guys you have to!
Guidelines! sorry guys you have to!
 
LISA Qooxdoo Tutorial Handouts
LISA Qooxdoo Tutorial HandoutsLISA Qooxdoo Tutorial Handouts
LISA Qooxdoo Tutorial Handouts
 
Questioning the status quo
Questioning the status quoQuestioning the status quo
Questioning the status quo
 
node.js - Eventful JavaScript on the Server
node.js - Eventful JavaScript on the Servernode.js - Eventful JavaScript on the Server
node.js - Eventful JavaScript on the Server
 
A Practitioner’s guide to Hardened JavaScript
A Practitioner’s guide to Hardened JavaScriptA Practitioner’s guide to Hardened JavaScript
A Practitioner’s guide to Hardened JavaScript
 
Jailbreak Detector Detector
Jailbreak Detector DetectorJailbreak Detector Detector
Jailbreak Detector Detector
 

Último

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 

Último (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

JavaScript Puzzlers!

  • 1. JavaScript Puzzlers: Puzzles to Make You Think (and write fewer bugs) Charles Bihis | Computer Scientist © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 1
  • 2. Who am I?  Charles Bihis  Computer Scientist  Adobe Identity Team  Blog: blogs.adobe.com/charles  Twitter: @charlesbihis  GitHub: github.com/charlesbihis © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 2
  • 3. What can I expect?  What are we going to talk about?  What are we NOT going to talk about?  Puzzlers!  3rd- party libraries or frameworks  Maximus the Confused!  e.g. jQuery, Node.js, etc.  Block Party!  That’s Odd!  Bugs  Let’s Print Some ZIP-Codes!  Say What?!  Loopty Loop!  A Case of Mistaken Identity  Why Are We Bankrupt?!  Will deal with only pure JavaScript  (i.e. no libraries!) © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 3
  • 4. What is a Puzzler? A Puzzler is a very simple programming puzzle that demonstrates or exploits weird behaviours and quirky edge-cases of a given programming language. © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 4
  • 5. How does this work? 1. Code – I introduce the code. 2. Question – I pose a multiple-choice question and you guess what the answer is…think hard! 3. Walkthrough – I walk through a reasonable explanation. 4. Answer – I tell you the real answer. 5. Moral – How can you avoid making mistakes like this in your own code. © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 5
  • 6. JavaScript Puzzler – Maximus the Confused! var commodusRule = 'thumbsUp'; alert('Maximus the ' + (commodusRule === 'thumbsUp') ? 'Gladiator' : 'Merciful'); What does this print? a) Maximus the Gladiator c) Error b) Maximus the Merciful d) None of the above  prints only "Gladiator" © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 6
  • 7. But why?  Order of operations dictates that the binary “+” operator takes precedence over the conditional “?” operator. 'Maximus the ' + (commodusRule === 'thumbsUp') ? 'Gladiator' : 'Merciful'; *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 7
  • 8. But why?  Order of operations dictates that the binary “+” operator takes precedence over the conditional “?” operator. 'Maximus the true' ? 'Gladiator' : 'Merciful'; *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 8
  • 9. But why?  Order of operations dictates that the binary “+” operator takes precedence over the conditional “?” operator. 'Gladiator'; *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 9
  • 10. But why?  Order of operations dictates that the binary “+” operator takes precedence over the conditional “?” operator. 'Gladiator';  According to the MDN (Mozilla Developer Network), the binary “+” operator has a precedence of 6 while the conditional “?” operator has a precedence of 15.  Note: This is below MOST commonly used operators (i.e. “*”, “/”, “%”, “<“, “>>” “!=”, “===“, etc). *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 10
  • 11. JavaScript Puzzler – Maximus the Confused…FIXED! var commodusRule = 'thumbsUp'; alert('Maximus the ' + (commodusRule === 'thumbsUp') ? 'Gladiator' : 'Merciful'); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 11
  • 12. JavaScript Puzzler – Maximus the Confused…FIXED! var commodusRule = 'thumbsUp'; alert('Maximus the ' + (commodusRule === 'thumbsUp' ? 'Gladiator' : 'Merciful')); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 12
  • 13. Moral  Be aware of order-of-operations!  Be explicit and place parenthesis accordingly to ensure correct and predictable order of execution. © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 13
  • 14. JavaScript Puzzler – Block Party! // global var var name = "World!"; What does this print? (function() { // check if "name" defined a) “Hello, World!” if (typeof name === "undefined") { // local "shadow" var b) “Hello, Mr. Bond.” var name = "Mr. Bond."; alert("Hello, " + name); c) “Hello, ” } else { alert("Hello, " + name); } d) None of the above })(); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 14
  • 15. But why? 1. No block scope! for (var i = 0; i < MAX; i++) { // do something } alert(i); // Note: "i" exists here! 2. “Hoisting” alert(i); // Note: "i" exists here too! for (var i = 0; i < MAX; i++) { // do something } © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 15
  • 16. But why? 1. No block scope! for (var i = 0; i < MAX; i++) { // do something } alert(i); // Note: "i" exists here! 2. “Hoisting” var i; alert(i); // Note: "i" exists here too! for (i = 0; i < MAX; i++) { // do something } © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 16
  • 17. JavaScript Puzzler – Block Party…FIXED! // global var var name = "World!"; (function() { // check if "name" defined if (typeof name === "undefined") { // local "shadow" var var name = "Mr. Bond."; alert("Hello, " + name); } else { alert("Hello, " + name); } })(); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 17
  • 18. JavaScript Puzzler – Block Party…FIXED! // global var var name = "World!"; (function() { var name; // declaration hoisted here // check if "name" defined if (typeof name === "undefined") { // local "shadow" var name = "Mr. Bond."; // assignment remains here alert("Hello, " + name); } else { alert("Hello, " + name); } })(); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 18
  • 19. JavaScript Puzzler – Block Party…FIXED! // global var var name = "World!"; (function() { var name = "Mr. Bond."; // check if "name" defined if (typeof name === "undefined") { alert("Hello, " + name); } else { alert("Hello, " + name); } })(); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 19
  • 20. Moral  There is no block-level scoping in JavaScript  Declare ALL of your variables at the top of your function © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 20
  • 21. JavaScript Puzzler – That’s Odd! (function(){ var values = [7, 4, '13', Infinity, -9]; What does this print? for (var i = 0; i < values.length; i++) { if (isOdd(values[i])) { alert(values[i]); a) 7, 13 } } b) 7, 13, Infinity, -9 })(); c) 7, -9 function isOdd(num) { return num % 2 == 1; } d) 7, 13, -9 © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 21
  • 22. But why?  Let’s take a closer look… 7 % 2 = 1 // displays 4 % 2 = 2 // does NOT display 13 % 2 = 1 // displays Infinity % 2 = NaN // does NOT display -9 % 2 = -1 // does NOT display © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 22
  • 23. But why?  -9 % 2 = -1? Really?  JavaScript shares the same behavior as the Java implementation of the modulus (%) operator. That is, it must satisfy the following identity function for all integer values a and non-zero integer values b. (a / b) * b + (a % b) == a  A side-implication of this behavior is that the result will have the same sign as the left operand! © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 23
  • 24. JavaScript Puzzler – That’s Odd…FIXED! (function(){ var values = [7, 4, '13', Infinity, -9]; for (var i = 0; i < values.length; i++) { if (isOdd(values[i])) { alert(values[i]); } } })(); function isOdd(num) { return num % 2 == 1; } © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 24
  • 25. JavaScript Puzzler – That’s Odd…FIXED! (function(){ var values = [7, 4, '13', Infinity, -9]; for (var i = 0; i < values.length; i++) { if (isOdd(values[i])) { alert(values[i]); } } })(); function isOdd(num) { return num % 2 != 0; } © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 25
  • 26. Moral  Be careful about the signs of operands when using the modulus operator. © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 26
  • 27. JavaScript Puzzler – Let’s Print Some ZIP Codes! // array of 5 valid zip-codes var zipCodes = new Array("93021", What does this print? "02392", "20341", a) 93021 "08163", 19  Firefox 20341 "32959"); 32959 // let's do something with each zip-code b) 93021 // for now, display them 2392 20341  Chrome for (var i = 0; i < zipCodes.length; i++) { 8163 32959 // sanity check if (!isNaN(parseInt(zipCodes[i])) && c) 93021 parseInt(zipCodes[i]) > 0) { 20341 alert(parseInt(zipCodes[i])); 32959 } d) It varies } © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 27
  • 28. But why?  Syntax var num = parseInt(string, radix); // "radix" is optional  When you omit the optional “radix” parameter, the following behavior takes place:  If the input string begins with “0x” or “0X”, radix of 16 is used (i.e. hexadecimal)  If the input string begins with “0”, radix 8 is used (i.e. octal) OR radix 10 is used (i.e. decimal)  If the input string begins with any other values, radix 10 is used (i.e. decimal)  Particularly when dealing with string values with leading 0’s, Mozilla had this to say… Exactly which radix is chosen is implementation-dependent. For this reason ALWAYS SPECIFY A RADIX WHEN USING parseInt. *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 28
  • 29. But why?  Another important note about the parseInt() API… If parseInt encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters and returns the integer value parsed up to that point.  A closer look… parseInt("93021") = 93021 // displays parseInt("02392") = (2 * 8) + (3 * 1) = 19 // displays parseInt("20341") = 20341 // displays parseInt("08163") = 0 // does NOT display parseInt("32959") = 32959 // displays *Reference: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 29
  • 30. JavaScript Puzzler – Let’s Print Some ZIP Codes…FIXED! // array of 5 valid zip-codes var zipCodes = new Array("93021", "02392", "20341", "08163", "32959"); // let's do something with each zip-code // for now, display them for (var i = 0; i < zipCodes.length; i++) { // sanity check if (!isNaN(parseInt(zipCodes[i])) && parseInt(zipCodes[i]) > 0) { alert(parseInt(zipCodes[i])); } } © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 30
  • 31. JavaScript Puzzler – Let’s Print Some ZIP Codes…FIXED! // array of 5 valid zip-codes var zipCodes = new Array("93021", "02392", "20341", "08163", "32959"); // let's do something with each zip-code // for now, display them for (var i = 0; i < zipCodes.length; i++) { // sanity check if (!isNaN(parseInt(zipCodes[i], 10)) && // radix value added parseInt(zipCodes[i], 10) > 0) { // here too alert(parseInt(zipCodes[i], 10)); // and here too } } © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 31
  • 32. Moral  parseInt() takes an optional radix parameter.  Omitting this optional parameter will cause unpredictable behavior across browsers.  Be explicit and ALWAYS include the radix parameter. © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 32
  • 33. JavaScript Puzzler – Say What?! function sayHello(name) { alert('Hello, ' + name); } sayHello('</script><script>alert("BOOM!");</script>'); What does this print? a) alert("BOOM!“); b) Hello, </script><script>alert("BOOM!");</script> c) BOOM! d) Error © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 33
  • 34. But why?  Let’s take a look at the code again… function sayHello(name) { alert('Hello, ' + name); } sayHello('</script><script>alert("BOOM!");</script>'); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 34
  • 35. But why?  Let’s take a look at the code again… <script> function sayHello(name) { alert('Hello, ' + name); } sayHello('</script><script>alert("BOOM!");</script>'); </script>  When a browser renders a page, first the HTML parser will parse the page and tokenize out all of the tags.  Only after this is done, will it then allow the JavaScript parser to tokenize and execute whatever tokens the HTML parser believes are JavaScript scripts! © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 35
  • 36. But why?  Let’s take a look at the code again… <script> function sayHello(name) { alert('Hello, ' + name); } sayHello('</script><script>alert("BOOM!");</script>'); </script>  Armed with this knowledge, we can see that the HTML parser will send 2 scripts to the JavaScript parser to tokenize and execute…  <script>function sayHello(name) { alert('Hello, ' + name); } sayHello('</script>  <script>alert("BOOM!");</script> © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 36
  • 37. A closer look  Again, the HTML parser will send these two script tags to the JavaScript parser…  <script>function sayHello(name) { alert('Hello, ' + name); } sayHello('</script>  <script>alert("BOOM!");</script>  If that name parameter is user-controlled, perhaps taken as input from the browser, or pulled from a datasource, whatever, then this is an open invitation for XSS attacks!  Errors like this can expose huge security holes which may allow an attacker to potentially take over a user’s browser! © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 37
  • 38. JavaScript Puzzler – Say What?!...FIXED!  In this particular case, the fix must be done on the server-side.  We want to eliminate the <script></script> tags from appearing in the source in the first place.  Suggested solution is to use the OWASP ESAPI APIs…  Stands for “The Open Web Application Security Project” “Enterprise Security API”  https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API  Have API bindings in all major languages including…  Java  Dot NET  PHP  JavaScript  Python  PHP © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 38
  • 39. JavaScript Puzzler – Say What?!...FIXED!  For this particular Puzzler, we want to use ESAPI.encoder().encodeForJavaScript()  Doing this on the server to JavaScript-encode the user-inputted variable, name, we get what we expect… © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 39
  • 40. Moral  NEVER . TRUST . THE . USER  Validate your input.  Encode your output appropriately.  i.e. HTML-encode for HTML URL-encode for URLs JavaScript-encode for JavaScript etc.  Use standard libraries (i.e. don’t reinvent the wheel). © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 40
  • 41. JavaScript Puzzler – Loopty Loop! What does this print? var END = 9007199254740992; // Math.pow(2, 53) a) 0 var START = END - 100; var count = 0; b) 100 for (var i = START; i <= END; i++) { count++; c) 101 } alert(count); d) None of the above  enters infinite loop © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 41
  • 42. But why?  9007199254740992 is a special number. Particularly, it is 2^53.  Why is this special?  First, we need to know something about how JavaScript represents numbers. *Reference: http://ecma262-5.com/ELS5_HTML.htm#Section_8.5 © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 42
  • 43. But why?  JavaScript numbers abide by the IEEE Standard for Floating-Point Arithmetic (IEEE 754).  As such, all numbers in JavaScript are represented by double-precision 64-bit floating point values… exponent -4 1.2345 = 12345 x 10 mantissa  In binary… 63 62 53 52 0 1 11...111 11111111111...111 sign exponent mantissa *Reference: http://ecma262-5.com/ELS5_HTML.htm#Section_8.5 © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 43
  • 44. But why?  2^53 is the largest exact integral value that can be represented in JavaScript!  From the ECMA specification… Note that all the positive and negative integers whose magnitude is no greater than 2^53 are representable in the Number type.  What does this mean? var numA = Math.pow(2, 53); var numB = numA + 1; alert(numA === numB); // true! *Reference: http://ecma262-5.com/ELS5_HTML.htm#Section_8.5 © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 44
  • 45. JavaScript Puzzler – Loopty Loop…FIXED! var END = 9007199254740992; // Math.pow(2, 53) var START = END - 100; var count = 0; for (var i = START; i <= END; i++) { count++; } alert(count); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 45
  • 46. JavaScript Puzzler – Loopty Loop…FIXED! var START = 0; var END = 100; var count = 0; for (var i = START; i <= END; i++) { count++; } alert(count); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 46
  • 47. Moral  Be aware of your number representations and number ranges!  There are REAL limitations imposed by your computer. When dealing with large (or important) numbers, know them! © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 47
  • 48. JavaScript Puzzler – A Case of Mistaken Identity! function showCase(value) { switch(value) { case "A": What does this print? alert("Case A was selected."); break; case "B": a) Case A was selected. alert("Case B here!"); break; case "C": b) This is Case C. alert("This is Case C."); break; default: c) Error alert("Don't know what happened."); break; } } d) Don’t know what happened. showCase(new String("A")); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 48
  • 49. But why?  The switch statement in JavaScript internally uses the strict equality operator (i.e. ===) as opposed to the non-strict equality operator (i.e. ==).  The strict equality operator behaves exactly as the non-strict version, except that no type- conversions are done.  So, when the switch statement evaluates equality, it checks that the following are true…  Their types are equal  Their uncast values are equal  Notice, we invoked showCase() with a new String object. alert(typeof "A"); // "string" alert(typeof new String("A")); // "object" © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 49
  • 50. JavaScript Puzzler – A Case of Mistaken Identity…FIXED! function showCase(value) { switch(value) { case "A": alert("Case A was selected."); break; case "B": alert("Case B here!"); break; case "C": alert("This is Case C."); break; default: alert("Don't know what happened."); break; } } showCase(new String("A")); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 50
  • 51. JavaScript Puzzler – A Case of Mistaken Identity…FIXED! function showCase(value) { switch(value) { case "A": alert("Case A was selected."); break; case "B": alert("Case B here!"); break; case "C": alert("This is Case C."); break; default: alert("Don't know what happened."); break; } } showCase("A"); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 51
  • 52. Moral  Get used to using the strict equality operator when possible. It will make you more aware of type conversions and true equalities.  From Douglas Crockford’s book “JavaScript: The Good Parts”… JavaScript has two sets of equality operators: === and !==, and their evil twins == and !=. The good ones work the way you would expect. The evil twins do the right thing when the operands are of the same type, but if they are of different types, they attempt to coerce the values, the rules by which they do that are complicated and unmemorable. © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 52
  • 53. JavaScript Puzzler – Why Are We Bankrupt?! What does this print? var costOfCandy = 0.60; // 60 cents a) 0 function calculateChange(cost, paid) { return paid - cost; b) 0.2 } c) 0.20 // pay for candy with 80 cents alert(calculateChange(costOfCandy, 0.80)); d) None of the above  0.20000000000000007 © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 53
  • 54. But why?  As we learned from a previous Puzzler, all JavaScript numbers use the IEEE 754 floating-point arithmetic specification.  Because of this, values are not represented exactly, but rather as a fraction.  Some non-integer values simply CANNOT be expressed exactly in this way. They must be approximated. Example: 123.45 = 12345 * 10^-2 // exact 1 / 3 = 0.333333333333333 * 10^0 // approximation! © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 54
  • 55. JavaScript Puzzler – Why Are We Bankrupt?!...FIXED! var costOfCandy = 0.60; // 60 cents function calculateChange(cost, paid) { return paid - cost; } // pay for candy with 80 cents alert(calculateChange(costOfCandy, 0.80)); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 55
  • 56. JavaScript Puzzler – Why Are We Bankrupt?!...FIXED! // Use only integer math when dealing with money! To do this, // represent your money in terms of cents to begin with! // // e.g. use 1599 instead of 15.99 to represent $15.99 var costOfCandy = 60; // 60 cents function calculateChange(cost, paid) { return paid - cost; } // pay for candy with 80 cents alert(calculateChange(costOfCandy, 80)); © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 56
  • 57. Moral  Floating-point arithmetic can be inaccurate when representing fractions.  When dealing with money, deal in terms of cents! This makes all of your calculations integer- calculations, which are exact!  Not completely exact, though…  Remember from our last Puzzler, it is exact only up until the largest representable integer value…  9007199254740992 (i.e. 2^52)  So, as long as you are dealing with less than $9 quintillion, you’re fine using integer arithmetic in JavaScript :) *Reference: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 57
  • 58. That’s it! Questions? © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 58
  • 59. Any favorites?  Puzzlers!  Maximus the Confused!  Block Party!  That’s Odd!  Let’s Print Some ZIP-Codes!  Say What?!  Loopty Loop!  A Case of Mistaken Identity  Why Are We Bankrupt?! © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 59
  • 60. Thanks for coming!  Charles Bihis  Computer Scientist  Adobe Identity Team  Blog: blogs.adobe.com/charles  Twitter: @charlesbihis  GitHub: github.com/charlesbihis © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential. 60
  • 61. © 2013 Adobe Systems Incorporated. All Rights Reserved. Adobe Confidential.