Badass JavaScript

A showcase of awesome JavaScript that pushes the boundaries of what's possible on the web, by @devongovett.

Has.js: UA Sniffing Is Dead. Long Live JavaScript Feature Detection!

September 30th 2010

Pete Higgins and a few other JS ninjas have been working on a new library for doing JavaScript feature detection.

Browser sniffing and feature inference are flawed techniques for detecting browser support in client side JavaScript. The goal of has.js is to provide a collection of self-contained tests and unified framework around using pure feature detection for whatever library consumes it.

It is similar to Modernizr, but instead of testing for HTML5/CSS3 features, it tests for JavaScript features such as:

  1. ES5 array, string, and object features
  2. Native JSON support
  3. Native console support
  4. ActiveX
  5. Native XHR
  6. Some DOM and event features

There are a lot of tests available, with even more being added daily.  Because the library is modular, you can import just the tests you need to save bandwidth.  Here is an example of the library in use:

if(has("function-bind")){
    // your enviroment has a native Function.prototype.bind
}else{
    // you should get a new browser. 
}

Has.js was also designed to allow other libraries to include the tests and provide their own API.  For example:

mylibrary.trim = has("string-trim") ? function(str){
    return (str || "").trim();
} : function(str){
    /* do the regexp based string trimming you feel like using */
}

By doing this, we can easily defer to browser-native versions of common functions, augment prototypes (which has.js will not do) to supplement the natives, or whatever we choose.

Running has() is a one-time cost, deferred until needed. After first run, subsequent has() checks are cached and return immediately.

You can also add your own tests to the library if you would like using a very simple API.

has.add("some-other-test", function(){
    return false;
})

This is a very worthwhile project, and looks to have tests for just about everything.  UA sniffing is not a good way to tell whether or not a browser supports a given feature since the user might have changed the UA string or may be using a browser that you didn’t know about when you wrote your code (i.e. a newer version).  Feature detection is the way to go!  You can check out has.js on Github.