When Type Coercion in JavaScript Is Not Helpful

Type coercion is something nice in ECMA script.
Well, not really.
If you don’t know what I mean, have forgotten it, or just repressed the fact, it is the funny fact of

alert(
" 2   + 2 +  2  = "     + ( 2  + 2 +  2 ) + "\n" +
"\"2\" + 2 +  2  = " + ("2" + 2 +  2 ) + "\n" +
" 2   + 2 + \"2\" = " + ( 2  + 2 + "2")
);

caused by a committee with members who paid a fortune to sit there. BTW: could it be that the cause of the spelling of “committee”…uhm…

To avoid the above mentioned problems when testing the above mentioned committee approved loose typing where 1 == "1" is true indeed, this already way too often mentioned bunch of seat-warmers decided to implement the === operator which takes care of types of the operands, too.

Now imagine a grumpy old man trying to find out if a numerical value is an integer and also representable as such. The next ECMA script edition (6) has something like Number.isInteger and Number.isSafeInteger. It is implemented in Firefox 32 (the last stable is 31) but the description of it over at the MDN gives a so called Polyfill

if (!Number.isInteger) {
  Number.isInteger = function isInteger (nVal) {
    return typeof nVal === "number" && isFinite(nVal) 
   && nVal > -9007199254740992 && nVal < 9007199254740992 
   && Math.floor(nVal) === nVal;
  };
}

To keep my code a bit cleaner I use prototypes of Number for these cases, especially when it makes at least a little sense.

var MP_NO=false;
var MP_YES=true;
Number.prototype.isOk = function(){
  return (  !isNaN(this) && isFinite(this)   ) ?MP_YES:MP_NO;
};
Number.prototype.isInt = function(){
  if(!this.isOk()){
    return MP_NO;
  }
  // ECMA 6 (Draft). Impl. by Firefox 32 only 
 /* if(Number.isSafeInteger){
    return (this.isSafeInteger())?MP_YES:MP_NO;
  }*/
  else{
    if(   this > -9007199254740992 
       && this <  9007199254740992
       && Math.floor(this) === this ){
      return MP_YES;
    }
  }
  return MP_NO;
};
alert(Number(4).isInt());

The above will popup a little gloating window saying “false”. You might have detected the error immediatly, especially after all of the foreplay, but this was called from a lot of places with a lot of very old code (able to run in Netscape 4.79, most of it even in 4.04!) hence hard to find.
If you still don’t get it try this reduced version:

Number.prototype.isInt = function(){
  alert((typeof Math.floor(this)) + " === " + 
        (typeof this));
}
Number(4).isInt();

It will return number === object which is obviously false. The Math-object (which isn’t really an Object but more about that in another post. hint) returns a Number but this is an Object even if that Object is Number:

alert(typeof Number);

returns function which means in full function Object so there we have it, the reason for all the pain in the backside. Funny, innit?

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s