Javascript Notebook

These are code snippets and rambling musings about Javascript.

Angular Service and Factory

I was reading the docs, and read things that seemed to contradict what I thought. I thought that Services were singletons, and Factories were instantiating new instances. It turns out that's not quite right. It's explained well here.

Benchmarking String Function to camelCase

I needed a function to turn snake_case to camelCase. The reason why? Angular and Javascript are better with camelCase, and Python and Django prefer snake_case. I tried working with both in the Django side, and it wasn't pretty. Even worse, I lost track of when I switched from one to the other, if I switched at all. So, I'm going to try renaming the keys as they are handed off from Django Rest Framework to the Javascript.

There were a bunch out there that used String.replace with a callback. It's terse, but looked slow to me. So I decided to write a few different versions and test them out.

function camelCaseClosure( word ) {
    return word.replace(/_([a-z])/g, function(g) { return g[1].toUpperCase(); }); 
}

function camelCaseString( word ) {
    var newword = ""; 
    var j=0;
    for(var i=0,l=word.length; i<l; i++) {
        if (word[i]=='_') {
            newword += word[i+1].toUpperCase();
            i++;
        } else {
            newword += word[i];
        }
        j++;
    }
    return newword;
}

function camelCaseJoin( word ) {
    // var newword = new Array( word.length ); // much slower on chrome
    var newword = [];
    var j=0;
    for(var i=0,l=word.length; i<l; i++) {
        if (word[i]=='_') {
            newword[j] = word[i+1].toUpperCase();
            i++;
        } else {
            newword[j] = word[i];
        }
        j++;
    }
    return newword.join();
}

// a testing function
function fixKeysClosure( hash ) {
    var newhash = {};
    var keys = Object.keys(hash);
    for(var i=0, l=keys.length; i < l; i++) {
        k = keys[i];
        newhash[ camelCaseClosure(k) ] = hash[ k ];
    };
    return newhash;
}

I didn't include all the testing code, but it all looks like fixKeysClosure. It changes the keys in a hash to camel case.

Firefox v33 results, 500,000 iterations, in ms:
fixKeysClosure 3880
fixKeysString 2209
fixKeysJoin 2829

Chromium v38 results:
fixKeysClosure 2087
fixKeysString 753
fixKeysJoin 791

So the string version, using the usual concatenation, is fastest. This includes a superfluous variable, j, which I didn't need.

fixKeysJoin was a lot slower on Chrome if you pre-allocated an array of the correct size.

A function to convert the keys of an array to camel case is attached.

AttachmentSize
test.html1.25 KB

Bookmarklet to Mass-Unfollow Twitter Users

I almost wrote a page for this, but it turns out a bookmarklet is good enough:

javascript:$('.js-follow-btn').click();undefined;

Make a bookmark, and set that as the URL. Then load up the page of people you're following. Scroll down a bit so more of the users get loaded. Then click the bookmarklet. In a second, all the users will be unfollowed. Reload and start again.

CSS Animations using Transitions with Conditional CSS, Stacked Rectangles

This is a somewhat elaborate example of how to use conditional CSS and transitions to create a fluid, responsive stack of rectangles that are polite enough to stack up when the screen is narrow. The idea is I'm working on is to have a menuing system that stacks when the screen shrinks.

There are three versions of this code, with menustack-onemotion.html being the simplest. I should have saved a much simpler version that didn't have so much code, but I didn't. You can fake it by editing all the "top", "box-shadow", and "transition" settings out.

To see it in action, load up one of the three pages, and then resize the window so it's narrow. Firefox works the best. Chromium might not let you shrink the window enough, but you can zoom in and see the full effect. Konqueror doesn't seem to support transitions, at least not with this code.

<!DOCTYPE html>
<html>
    <head>
        <style type="text/css">
            body { 
                background-color: #e3e3e3;
            }
            .menu {
                border: 1px solid #ddd;
                width: 120pt;
                height: 400pt;
                background-color: white;
                position: absolute;
                margin-left: -1px;
                box-shadow: 0px 0px 0px #fff;
                transition: left 0.5s, top 0.5s, box-shadow 0.25s;
            }
            .L1 { 
                left: 5pt; 
                top: 5pt;
            }
            .L2 { 
                left: 125pt; 
                top: 5pt;
            }
            .L3 { 
                left: 245pt; 
                top: 5pt;
            }
            @media screen and (max-width: 380pt) {
                .menu {
                    border: 1px solid #eee;
                    box-shadow: 0px 1px 1px #ddd;
                }
                .L1 { 
                    left: 5pt; 
                    top: 9pt;
                }
                .L2 { 
                    left: 10pt; 
                    top: 6pt;
                    box-shadow: 0px 1px 2px #ddd;
                }
                .L3 { 
                    left: 130pt; 
                    top: 3pt;
                    box-shadow: 0px 1px 4px #ddd;
                }
            }
            @media screen and (max-width: 260pt) {
                .L1 { 
                    left: 5pt; 
                    top: 9pt;
                }
                .L2 { 
                    left: 10pt; 
                    top: 6pt;
                    box-shadow: 0px 1px 2px #ddd;
                }
                .L3 { 
                    left: 15pt; 
                    top: 3pt;
                    box-shadow: 0px 1px 4px #ddd;
                }
            }
        </style>
    </head>
    <body>
        <div class="menu L1"></div>
        <div class="menu L2"></div>
        <div class="menu last L3"></div>
    </body>
</html>

So, if you're a programmer, this is going to look a little odd because there's no logic that causes the magic to happen. You have to think more like an animator. Animators think in terms of "key frames", and you can think of this animation as having three key frames.

Conditional CSS is used to define the positions of the rectangles.

@media screen and (max-width: 380pt) {...

That means if the width is less than 380pt, the following styles are applied. These styles override the styles that appeared above this rule.

Likewise, @media screen and (max-width: 260pt) {... causes additional CSS to be applied, overriding not both the above block and the original CSS.

It's a little weird to work with CSS because the right way to code it uses this overriding behavior.

We could have written it (less elegantly) like this:


@media screen and (min-width: 380pt) {
  ... frame 1 ...
}
@media screen and (min-width: 281pt) and (max-width: 379pt) {
 ... frame 2 ...
}
@media screen and (min-width: 0pt) and (max-width: 280pt) {
 ... frame 3 ...
}

But that would be wrong.

It not only leads to more code - you're more likely to mess up the code because you have to keep track of more things. It's better to think like this:

- you start with one working layout that shows everything on a big screen.
- then you create a conditional layout that alters the original.
- as the screen space shrinks, you need to alter the layout more.

The logic of your code should be developed separate from your drawings or HTML sketches. Your HTML sketches can be messy, but the conditional CSS code should be crafted. It's no different than writing computer code: the first version is the one you throw away.

More Tricks

The use of L1, L2, and L3 is somewhat incorrect - I could have used IDs. I didn't because I was thinking this could be used for menus, and menus might have unique IDs, but two menus could share the same "depth" in the menu hierarchy.

It still feels like a hack to me. Maybe that's more my problem than anything else.

The magical animation features are enabled with the "transition" line. The transition property causes the listed CSS styles to be transitioned rather than immediately applied.

When there's a transition property, the browser takes the new value, and then calculates tween values and applies them over the specified intervals. In this example, changes to the styles are triggered by the conditional CSS. (You could also cause changes to styles by using Javascript code to add classes or styles to elements.)

The scope of a transition property is the element it's on.

So, there you go. Not the greatest tutorial, but it's a nice effect, and the code is pretty simple for what it does.

AttachmentSize
frames.png7.07 KB
menustack-onemotion.html1.52 KB
menustack-progressive.html1.98 KB
menustack-sketch.html4.72 KB

CSS Animations via Styles (similar to jQuery animations)

This article is a little obsolete, because the latest way to do animations is via CSS Transitions but browser support isn't all there yet. This explores how to do CSS-style based animations, where the animations are controlled via Javascript code that adds and deletes class names from the className property.

This is basically how jQuery and Angular do CSS animations. jQuery also does animations by calculating the tween positions, but, that's going to be obsolete because the mobile browsers now support CSS animations.

The hard part about understanding CSS animations (for me) was getting the concepts. This example tries to break down the parts of the animation. Try it out, and then read the code and comments.

<!DOCTYPE html>
<html>
    <style type="text/css">
        /* the styles that are the same between the two positions */
        .box {
            border: 1px solid silver;
            margin: 2px;
        }
        /* the starting positions */
        .small {
            width: 20px;
            height: 20px;
            background-color: white;
        }
        /* the ending positions */
        .big {
            width: 300px;
            height: 80px;
            background-color: gray;
        }
        /* The animation is made up of two parts.  Metainformation
           about how long the animation runs, direction, and some other
           things are set via styles named animation-*.

           The @keyframes are the values for the styles that are rendered.
           The CSS engine takes care of tweening between the keyframes.

           To start an animation, you add the animation settings class
           name to the element's className property.
        */
        /* the animation settings */
        .small-to-big {
            animation-duration: 2s;
            animation-name: grow;
        }
        /* the animation */
        @keyframes grow {
            /* this matches the starting class */
            from {
                width: 20px;
                height: 20px;
                background-color: white;
            }
            /* this matches the ending class */
            to {
                width: 300px;
                height: 80px;
                background-color: gray;
            }
        }
    </style>
    <script>
        function animate( id, start, end, animation ) {
            var e = document.getElementById(id);
            /* When an animation completes, you need to replace
               the starting class name with the ending class name.
               So, we create a function that does that replacement.
               It's a little clunky, yes.

               The 'animationend' event is raised at the 
               end of the animation.  We attach the handler
               to that event.
            */
            var finisher = function() {
                /* The element may or may not have the classname of
                   the starting state.

                   Don't be afraid to add spaces all around.
                */
                e.className = ( e.className.replace(start,' ') + ' ' + end );
                /* We could leave the animation class name in there,
                   but it's nicer to be tidy.
                */
                e.className = e.className.replace(animation, ' ');
            };
            e.addEventListener('animationend', finisher, false);
            /* Then, we add the animation settings class to the 
               className, which starts the animation.
            */
            e.className = e.className + ' ' + animation;
        }
        function boom() {
            animate('b1','small','big','small-to-big');
            animate('b2','small','big','small-to-big');
            animate('b3','small','big','small-to-big');
        }
    </script>
    <body>
        <p>Three boxes that zoom out into three larger boxes.</p>
        <!-- note that the small class, the initial style, is added -->
        <div id="b1" class="box small"></div>
        <div id="b2" class="box small"></div>
        <div id="b3" class="box small"></div>
        <button onclick="boom();">click</button>
    </body>
</html>
<!-- 
  - What HTML needs is an animation compiler that will take the starting
  - and ending styles, and then emit the entire animation.  It would 
  - calculate the common parts, the different parts, and make the keyframes,
  - and write the javascript to control the animation.
  -->
AttachmentSize
tween.html3.65 KB

CSS Animations via Transitions

I don't know anything about CSS Transitions, so I made this little demo to try it out. It's ultra-simple, and I normally wouldn't post this kind of thing, but the examples I saw were a lot snazzier, so it was harder to read the code. (To this end, this is probably too fancy.)

<!DOCTYPE html>
<html>
    <head>
        <style type="text/css">
            .all {
                border: 1px solid white;
                width: 50px;
                float: left;
            }
            .a {
                height: 50px;
                background-color: violet;
            }
            .a:hover {
                height: 100px;
                background-color: red;
            }
            .a:active {
                height: 60px;
                background-color: blue;
            }
            .move {
                transition: 0.5s;
            }
        </style>
    </head>
    <body>
        <div class="all a move"></div>
        <div class="all a move"></div>
        <div class="all a move"></div>
        <div class="all a move"></div>
        <div class="all a move"></div>
        <div class="all a move"></div>
        <div class="all a move"></div>
        <br clear="both" />
        <div class="all a move"></div>
        <div class="all a move"></div>
        <div class="all a move"></div>
        <div class="all a move"></div>
        <div class="all a move"></div>
        <div class="all a move"></div>
        <div class="all a move"></div>
    </body>
</html>

One thing I've done a little weird is to separate out the transition into the move class. That's not necessary. It's only for me.

The other thing I did, which is similar to my other CSS animation post, is to break out the CSS styles into one class for all the common styles, "all", and three classes for the three animated keyframe states, "a", "a:hover" and "a:active". This *is* necessary.

AttachmentSize
trans.html1.19 KB

Function-Generating Functions in Javascript

I wrote this before I practiced with the module pattern and with adding methods to prototypes. So this article doesn't explain a best practice. Still, it's a pretty good pattern. See also the Javascript Patterns book.

JS has closures, and with closures, you can create functions that return functions as values. Erm. So what? Well, the closure is not just a function, but also its "environment". I think the term in JS is "local variables". So the function carries with it, a bunch of its local variables.

This means you can create a function that "remembers" some values you've passed to it. Here's an example:

foo = function (x) { return function (y) { return x + y; } }

To use it, you do this:

addone = foo(1);
addten = foo(10);

Now, addone(5) returns 6. addten(6) returns 16.

If that doesn't make sense, look at the code again. The body of foo is "return function (y) { return x + y; }".

Well, x, in this case, is a local variable that you passed into foo().

So the code of addone is really something like this: "function addone(y) { var x = 1; return x + y; }".

You may need to re-read the above.

The point here is that the function creates another function, and that function is slightly tailored to do something. Now, that might seem pointless, but it's not. It's a lot like objects and methods, except instead of creating a lot of objects, you now can create a lot of functions that contain some data.

If you think about it, the jQuery and current JS style of programming involves creating a lot of anonymous functions and attaching them as handlers onto the DOM objects. A function-making function is really handy, because you can go through a DOM and attach a unique handler function to each object.

Here's part of a function I'm working on. It might not work:

SW.map.listFormatterMaker = function (prefix) {
  return function (d) {
    $.template('MainInjectList', 
      ' ${name} ${city}, ${address}');
    document.getElementById( prefix+'-list' ).innerHTML = '';
    document.getElementById( prefix+'-list2' ).innerHTML = '';
    a = d.slice(0,5);
    b = d.slice(5,10);
    a.forEach(SW.listInserter( prefix+'-list')); // this is another function-making function
    b.forEach(SW.listInserter( prefix+'-list2'));  // ditto
  }
}

It's a little long, but it's a function that returns a "listFormatter". A "listFormatter" is a function that formats some data that's passed do it.

It takes a 'prefix' parameter. The HTML includes two UL elements that have IDs of 'map-list' and 'map-list2'. I'm using a naming convention, and the prefix is "map".

When SW.map.listFormatterMaker('map') is called, it returns a function. That function, when passed some data, d, it'll format and insert the data into my page.

Before inserting the data, it splits the array into two (for two columns), and then inserts into -list and -list2, separately. To do the insertion, it uses forEach and another function-making function called listInserter().

So, if I want to re-use this code, I could create some HTML with IDs of 'map2-list' and 'map2-list2' and pass 'map2' as the prefix. Then, calling SW.map.listFormatterMaker('map2'), will make a different function that will do the same thing for a different area of my page.

It's used like this:

$.getJSON('foo.php',{arg:1},SW.map.listFormatterMaker('map'));
$.getJSON('bar.php',{arg:1},SW.map.listFormatterMaker('map2'));

So that's 2 function calls that are visible to the user, but the result is that four different areas of the page get updated with data. Each area is updated by anonymous functions.

You might be wondering if this can be done without this function-making-function business. I think it can, but it would be a lot more code. You would have to write a customized data handler for each call. With this style of programming, you avoid that.

Also, it's not just useful for specifying a selector. You can also pass it functions, so it's possible to create functions that have different behaviors depending on the functions passed into the function-maker.

Generate a Page of Random Passwords with Javascript

The attached HTML page is a password generator that creates a page of random 10-character passwords. It helps you manage one password per website, so a password leaked for one site doesn't get used on other sites. To use it, click and view the file.

You can also download it and use it - it's all done with Javascript so there's nothing that requires the server.

To use it, just keep the printed page in a safe place. Make a copy and store it in a fireproof safe or safe deposit box. As you use each password, make a note of the site. You may not want to use the full site URL. It doesn't matter. You might even try to obfuscate the site name or use an abbreviation. You have three blank columns so you can put in some fake data in there to add chaff, which is junk data meant to mislead someone who gets this paper.

You can also do tricks, like ignore one letter in the password. So you have 9 character passwords instead of 10 character passwords. If the password list is lost or stolen, the guesser would have to guess which character is being dropped from the actual password.

You can transform: perhaps the first character is reduced by 1, so B becomes A, 8 becomes 7, etc. You can transpose - the first two characters can be swapped, so 1} becomes }1.

Every year or so, you can change your passwords and clean up your lists (doing things like alphabetizing them. You might keep the old lists as "decoys". Repeated failed logons will cause some sites to lock out the account. This is another kind of chaffing, where you "fluff up the haystack" and hide your needle in it.

The real password and url is discoverable, but it should be hard for someone to figure out.

See also: http://en.wikipedia.org/wiki/Password_strength#Creating_and_handling_passwords.

AttachmentSize
randompasslist.html1.22 KB

Hiding Email Addresses from Spiders and Spammers

Here's a bit of PHP code that emits javascript. The javascript emits an email link, but coded in Javascript, so that most spiders won't be able to get your email address for spamming.


<?php
function printEmailAddress( $email )
{
$parts = explode( '@', $email );
echo ' var d = document;';
echo 'd.write("");';
echo 'd.write("'.$parts[0].'");';
echo 'd.write("@");';
echo 'd.write("'.$parts[1].'");';
echo 'd.write("
");';
}

printEmailAddress("fake@mail.com");
?>

Interstitial Ad in jQuery

Normally, you should use canned Javascript or canned PHP modules to implement web features, but sometimes, that can suck. Typically, these products, if they're popular, start to suffer from feature bloat. Such was the case with some code for "interstitials", which are those ads that pop up on some web pages, interrupting your reading. Popups have been around a long time, and the drop-in code is just really huge.

Nowadays, you can assume that you'll have at least one JS library installed on the site. I started with Dojo, and now use jQuery. There's also Scriptaculous on top of Prototype (I'm kinda iffy about those), and Mootools.

So you can immediately cut code size by using the library, which is large, but can be cached -- if you link to it from one of the CDNs like Google -- and is reused for other things. Then, you can start looking at libraries.

The best interstitial library seems to be Shadowbox.js. It just looks nice.

Of course, sometimes, you just want to make your own, and you need special behaviors. In my case, I needed a form that integrates with an external site, not a thumbnail that expands, so Shadowbox wasn't a great fit. I just coded it by hand, and learned some more jQuery and CSS. To top it off, the code is a little smaller.

The interstitial ad feature is attached. If you need more explanation, please ask in a comment, and I'll do my best to accomodate.

May-Jun 2012: 80, pagerank 1 for interstitial jquery ad

AttachmentSize
inter.zip30.05 KB

Javascript Delayed Hiding of an Element, Delayed Function Calls in Different Contexts

So I'm working on a small "speech bubble" library, and needed to delay hiding of the bubble. It's not that it was required, but it was a pain in the butt figuring out how to arrange the event handlers on the different elements so that you don't end up with a situation where you get a flickering bubble because you hide the bubble, and that fires a mouseover event that, in turn, displays the bubble again. That fires a mouseout event that causes the bubble to be hidden.

The usual right way to fix this is to detect the mouse moving into the area around the hotspot, and when it does that, hide it. My cheap fix is to just delay the hiding, and if the mouse happens to enter another element that requires the bubble to be displayed, the handler for this other element can cancel the hide.

A delay is also "nice" because it also gives the user a chance to roll back if they overshoot a target a little bit.

Here's the code fragment to implement a delay:

  var hide = function () {
    this.bubble.style.display = 'none';
  }
  var delayedHide = function() {
    (function (x) {
      x.hideInProgress = setTimeout(function () {x.hide()},250);
    })(this);
  }
  var cancelHide = function() {
    clearTimeout(this.hideInProgress);
  }

The one really weird part is in delayedHide. What this does is construct a function that will call setTimeout(), then immediately call it. That calls setTimeout(), which registers the timeout handler to fire off in 1/4 second. Why not just call it like this?

this.hideInProgress = setTimeout(function () {this.hide()}, 250);

Well, the problem is that "this" changes between the two calls. When it's called from the bubble object (i.e. b.delayedHide() ), "this" is set to the object. When the timeout happens and the function's called by the system, I think "this" is set to window. Anyway, it's a different "this". "this" may not even exist. We're screwed.

So what we do, instead, is use a function to create a closure. A closure holds is local variables. So, what's happening is that (function(x) { ... })(this) is setting the local variable x to = this. Then, when function(){x.hide()} is created, it also carries the local variable x within the closure. That's because the closure contains the local variables in the scope in which is was defined.

After the call, the outer function wrapper is thrown away, but the inner one is stored away in window, ready to be called in 250 milliseconds.

Javascript Functions and Closures for Private Properties

A JavaScript Module Pattern is a fantastic example of how to use closures.

Javascript Closures has more detailed information.

Douglas Crockford brought the style over to JS, and his site has a lot of important articles about Javascript hacking (as a functional language).

A good description of closures is part of Blocks and Closures in Ruby an interview with Matz.

This video, Advanced Topics In Programming Languages: Closures For Java with Neal Gafter has a pretty detailed explanation about implementing closures in Java.

Last but not least, PHP 5.3 will have closures. What's new in PHP by John Mertic at IBM developerworks details the feature. The PHP RFC also has good examples.

AttachmentSize
closure.png12.65 KB

Javascript Functions and Functors

Joel on Software has a good article that explains functors, the purpose of passing functions as paramters, and leads into an explanation of map/reduce and parallel computing. These ideas are explained in Javascript, but also apply to Lisp, Scheme, and Perl (see the Mark Jason Dominus book). All these languages are functional programming languages, where functions are objects (or objects are functions).

(Add examples of functional programming here.)

Unfortunately, PHP, the other language covered here, has only half-baked functional programming. See the Function Handling Functions section of the manual.

Learning Javascript via the Read Eval Print Loop (REPL)

All the tutorials out there teach JS by having the user write a file, and load it into the browser. That's unnecessary work, if what you're really doing is learning the language syntax and are not interested in the web browser environment.

Most contemporary scripting languages have a Read Eval Print Loop (REPL), which some might call a "shell", or "console", or "interactive debugging", or "interactive toplevel", or "interactive mode". It's a prompt at which you type code, and the interpreter runs your code, and prints an output.

There are a few different REPLs for JS. The main one is in the error console, at the bottom. It's a command line. You can type anything into there, and it'll be evaluated.

In Firebug, there's a red button in the right side of the console's command line. If you press it, you'll get a small text editor where you can enter more complex expressions or even complete programs. To execute, press Control-Enter, or click "Run".

If you're on a Unix system, you can install node.js. On Ubuntu Linux, it's the "nodejs" package. The "nodejs" command starts a REPL for JavaScript.

Password Quality Evaluator

This is an up-and-coming feature on some sites. It measures the quality of a password, and gives the user immediate feedback about how good it is. The JavaScript below does that. It calculates the score by grouping the keyboard into uppercase, lowercase, punctuation, and numbers. You get points for length, for diversity in using keys from different groups, for switching groups often, and extra for using punctuation. The HTML part was intended for creating an .htaccess password. Here's a demo:
Password
Quality:

Resize YouTube Video (works with Vimeo and most sites)

This is a script to resize youtube video embed codes. It also works with other site. The youtube video is scaled proportionately. It should work with other video sites like Revver, Vimeo, LiveLeak, and even non-video embed codes.
Paste your code here:


Resize to this dimension (fill one):
Width:  
Height:
Get your new code here:
Return to: How to Resize a YouTube Video for Your Website on Associated Content. Return to: How to Resize a YouTube Video and Have it Look Right on eHow.

SelectAdd - A Checkbox Alternative

Checkboxes work well if you're dealing with a few choices, but stop working so well when there are many options, and only a few are selected. SelectAdd is some code that will display a CSS/JS/DHTML widget that makes it look like you're adding selections to a list.

This is just a demo script. It doesn't include any integration with a database backend.

AttachmentSize
selectadd.zip2.89 KB

Time Sheet Calculator

This script turned into the Multiple Time Sheets program. It's a calculator for time intervals in javascript.

Javascript Timesheet Calculator

This page reads your timesheet, which you paste in below, and adds up your hours. It's designed to work with somewhat organized data, in a format that I've used for years.

Do not type your timesheet into this page. You will lose your data! Use something like "Stickies" or some other notetaker, or Notepad, instead. Copy your data into this page, and use it as a calculator and timesheet formatter.

Total:        

A few caveats about the data format.

A little bit about this script.

It's written in Javascript, and requires a Netscape 4 or later browser that supports regular expressions. It's pretty much all about regular expressions. There's no PHP or Perl or anything like that involved. The script was written by John Kawakami and is in the public domain.

If you're interested in regexs, check out a refcard at Visibone. I used that page to make this page. (The cards are a good cheap gift for your local webhead.)

Using strings to create functions

One of the less-used features is the Function() object, which can turn a string of Javascript code into a function. This is an example of how it can be useful.

I recently hit an annoyance with the Android browser. Around version 3 and 4 of Android, the browser stopped supporting the JS history.pushState() and history.replaceState() methods, basically killing my LA IMC JS app.

Just to verify, I wrote the following to test the existence of those objects:

<script>
if (history) {
  document.write("history supported<br />");
}
if (history.back) {
  document.write("history.back supported<br />");
} else {
  document.write("history.back not supported<br />");
}
if (history.state) {
  document.write("history.state supported<br />");
} else {
  document.write("history.state not supported<br />");
}
if (history.pushState) {
  document.write("history.pushState supported<br />");
} else {
  document.write("history.pushState not supported<br />");
}
if (history.replaceState) {
  document.write("history.replaceState supported<br />");
} else {
  document.write("history.replaceState not supported<br />");
}

Yup. My inexpensive Android tablet with the 4.0.x OS didn't support them. Since the company wasn't releasing updates, it would never support them. What a pain. Also, since hundreds of thousands of devices out there lack this support, web apps will have to detect and work around the problem. "Thank you Google."

Anyway, all that code was long and a pain to edit, so I thought there must be a better way, and there was. You can use Function() to create new functions, like this:

apiname = "history.replaceState";
new Function( "if ("+apiname+") { document.write('"+apiname+" supported<br />'); } else { document.write('"+apiname+" <b>not</b> supported<br />'); }" )();

What Function() does is read the string, parse it as code, and then create a function object from it. Because it's a string, we can construct it using code, which we did, by inserting apiname into the code.

The () after the function causes the new function object to execute immediately. If you ignore the string, it looks like this: new Function("...")(); That makes a new function object, then calls it.

Expanding on that example, you can replace the first example with this:

apinames = ["history","history.back","history.state","history.pushState","history.replaceState"];
for( i=0; i < apinames.length; i++ ) {
  apiname = apinames[i];
  new Function( "if ("+apiname+") { document.write('"+apiname+" supported<br />'); } else { document.write('"+apiname+" <b>not</b> supported<br />'); }" )();
}

If you prefer the Array.forEach() style:

apinames = ["history","history.back","history.state","history.pushState","history.replaceState"];
apinames.forEach( function() {
  new Function( "if ("+apiname+") { document.write('"+apiname+" supported<br />'); } else { document.write('"+apiname+" <b>not</b> supported<br />'); }" )();
} );

Caveat: note that the Function constructor does NOT create closures. The functions are created in the global namespace. This can be good - as closures are slow and use a bit of memory. Closures keep references to their calling environment and have access to local variables in the context where the closure was defined.