Tuesday, June 2, 2015

No Strings attached



Javascript function 'name' property




In a recent project I witnessed line after line - in who knows how many files - of typeof comparisons. It looks sloppy and it's error prone. I decided to show some alternatives to my coworkers, but in such a large codebase, and since the code works, it’s doubtful anything will change. However, for new projects, here’s a js 6 alternative:

The problem: pretend you are looking at hundreds of these...

    
  if(typeof shouldBeStr === 'string') {...}
The name property on a non-anonymous function returns a string. So since the string type has a constructor we don’t have to compare against a hand-coded string.
    
  String.name
  //"String"
Unfortunately, this give us back the name of the constructor with a capital “S”. But there’s an easy workaround.
    
  if(typeof 'ugh' === String.name.toLowerCase()){}
So how might we cache this value and use it more like an enum? Easy:
    
 typeEnum = {
     string : String.name.toLowerCase(),
     function : Function.name.toLowerCase(),
     array : Array.name.toLowerCase(),
     true : true.toString(),
     false : false.toString(),
     object : Object.name.toLowerCase(),
     number : Number.name.toLowerCase(),
     bool : Boolean.name.toLowerCase()
  }
Now you could do something like this:
    
  if(typeof 'ugh' === typeEnum.string){}
A little more to understand how the 'name' property works:
    
  var f = function(){};
  f.name // ""
  //an anonymous function has no name
  var g = function g(){}
  g.name // "g"