Monthly Archives: August 2014

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?

Bashing Aspect Ratio Mess

I got a large pile of photographs to work with which have several aspect ratios, mostly 4:3, 3:2 and 16:9. A large part of the work was automatable with a shell-script or two and the help of ImageMagick. As some of these scripts depend on the specific aspect ratio I wrote a little script to check for it. Continue reading