Skip to content

Instantly share code, notes, and snippets.

@jimmed
Last active December 15, 2015 07:19
Show Gist options
  • Save jimmed/5222278 to your computer and use it in GitHub Desktop.
Save jimmed/5222278 to your computer and use it in GitHub Desktop.
TellAFriend.md

Tell A Friend

Let's take a look at the original code.

<script>document.write('<a target="_blank" href="YOURFORMLINK&referrer='+document.URL+'"'+'>Tell a Friend</a>');</script>

It's not the tidiest or most useable code in the world, nor is it the fastest. Let's put this through jsbeautifier -- an invaluable resource -- and see how it looks. We'll put it back to being a one-liner at the end.

<script>
    document.write('<a target="_blank" href="YOURFORMLINK&referrer=' + document.URL + '"' + '>Tell a Friend</a>');
</script>

That's a little easier to read now, just through the spacing. First things first, <script> tags should always have a type attribute - it's good practise, as it's not just JS that can be embedded in HTML.

<script type="text/javscript">
    document.write('<a target="_blank" href="YOURFORMLINK&referrer=' + document.URL + '"' + '>Tell a Friend</a>');
</script>

First, you can see that we make repeated calls to document. DRY (Don't Repeat Yourself) principles state that this is bad for many reasons - most importantly that programmers are lazy, and writing less is always better if you can get away with it. So, let's store a reference to document in a variable d.

<script type="text/javascript">
    var d = document;
    d.write('<a target="_blank" href="YOURFORMLINK&referrer=' + d.URL + '"' + '>Tell a Friend</a>');
</script>

Well, that's smaller already! But, we've now created a global variable called d, which some other script might have been using, and that's really bad. So, to prevent 'polluting the global namespace', we wrap the whole thing in a function, so that our d only exists for this bit of script. We then call this function immediately by putting () on the end.

<script type="text/javascript">
    (function(){
        var d = document;
        d.write('<a target="_blank" href="YOURFORMLINK&referrer=' + d.URL + '"' + '>Tell a Friend</a>');
    })();
</script>

Now, if we tried to access d from anywhere else in the page, it would be as if we were never there. (Rule #1: Be a ninja).

But, everything just got bigger when we wrapped it in that anonymous function. And, there's another (small) issue. When we're inside our function, document is not defined locally in the function. So, when we assign it to d, the JS engine looks in our function for document, then when it doesn't find it, looks in the next level up, where it does find it. This incurs a little performance hit - not important here, but it's a bad practise, so let's avoid it.

<script type="text/javascript">
    (function(d) {
        d.write('<a target="_blank" href="YOURFORMLINK&referrer=' + d.URL + '"' + '>Tell a Friend</a>');
    })(document);
</script>

And, as if by magic, there's no scope lookup to slow us down, and we got rid of a whole extra line of code! NINJA!

Now, there's not much left to improve, performance-wise. The only thing that we can speed up, is to get rid of the string concatenation - joining strings together to form longer strings. The best way of doing this is like so:

<script type="text/javascript">
    (function(d) {
        d.write([ 
            '<a target="_blank" href="YOURFORMLINK&referrer=', 
            d.URL, 
            '">Tell a Friend</a>' 
        ].join(''));
    })(document);
</script>

Here, we put all our bits of string into an array, and then join them together into a string. Performance-wise, this is a lot faster, but it's outside the scope of this article to explain why. It also (in my opinion) is clearer to read, and a lot easier to extend. Say, for handy example, we wanted to add a title parameter to our link. here's how easy it would be:

<script type="text/javascript">
    (function(d) {
        d.write([ 
            '<a target="_blank" href="YOURFORMLINK&referrer=', 
            d.URL,
            '&title=',
            d.title,
            '">Tell a Friend</a>' 
        ].join(''));
    })(document);
</script>

Our code just got a bit bigger, but it'll compress back down again just as nicely, like so:

<script type="text/javascript">
    (function(d){d.write(['<a target="_blank" href="YOURFORMLINK&referrer=',d.URL,'&title=',d.title,'">Tell a Friend</a>'].join(''))})(document);
</script>

Simpler, but harder to edit, and if we ever wanted to re-use this little snippet in a piece of code, it'd be nice to be able to change the text in the link, and the base URL used. So, let's parameterise these in the same way we did with document, but we'll skip out the step where we assign them as variables.

<script type="text/javascript">
    (function(d,f,t) {
        d.write([ 
            '<a target="_blank" href="',
            f,
            '&referrer=', 
            d.URL,
            '&title=',
            d.title,
            '">',
            t,
            '</a>' 
        ].join(''));
    })(document, 'YOURFORMNAME', 'Tell a Friend');
</script>

Uncompressed, it looks longer again, but if you now look at it when compressed, it's much, much easier to change these settings.

<script type="text/javascript">(function(d,f,t){d.write(['<a target="_blank" href="',f,'&referrer=',d.URL,'&title=',d.title,'">',t,'</a>'].join(''));})(document,'YOURFORMNAME','Tell a Friend');</script>

Et voila, your beautiful new JS one-liner, with added performance and configurability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment