I'm currently writing an introduction course to JS libraries and have decided jQuery is like Batman – Objects are wrapped in a utility belt that does everything but are essentially unchanged underneath – while Prototype is more like Wolverine – Objects are injected with stuff to make them better, stronger, more deadly.
Having gotten hooked on it during the first js1k, written about extreme JS minification and submitted a bunch of stuff to 140bytes, I think it's fairly safe to say I'm an addict. Because of that, there was really no chance that I could let this year's js1k go by without entering.
The theme this year is ‘Love’. Seeing as I never actually submitted my maze1k demo, I decided I'd spruce it up, restyle a bit and submit it covered top to bottom in hearts.
There's not a lot I can say about minification techniques that hasn't already been covered either on thissite, on Marijn Haverbeke's site, on Ben Alman's or on the 140bytes wiki page on byte-saving techniques. The only things I will add are a couple of techniques which are new to me. I have thoroughly commented the code below, however. If you want to play along, have a look.
Left-first Evaluation
It's a feature of most programming languages that when you have a logical operator such as && or ||, the value of the left side of the operator determines whether the right side will be evaluated at all. If the left side of an AND is false, we're going to get a false for the whole thing. It doesn't matter what the right side is so we don't even need to look at it. Similarly, if the left side of an OR is true, the eventual return value will be true so we don't need to look at the right. For example, here are two statements:
coffee&&morning
wine||work
In the first example (&& – AND), we will only check morning if coffee is true. We first have a look at coffee and if it is false, we don't care whether morning is true or not, we just skip it (and, presumably, go back to bed). If coffee is true, we'll then have a look to see if morning is true. It doesn't matter if morning is a function or a variable assignment or whatever, it will only happen if coffee is true.
In the second example (|| – OR), we will only evaluate work if wine is false. We start by looking at and evaluating wine. If that is true, the JS interpreter saves us from even considering work and skips it. The right-side of the operator, work, is only considered if wine is false.
You can probably see how, in a few simple situations, this can help avoid an if(), thereby saving at least one byte. Usually.
‘A’ font
If you want to set the font-size on a canvas 2D context, you have to use the font property. Makes sense, right? Unfortunately for obsessive minifiers, you can't just set the fontSize, you also have to set the fontFamily at the same time:
canvas.getContext('2d').font="20px Arial"
Failure to set the font family means that the whole value is invalid and the font size isn't applied.
My thought process: “But 'Arial'? The word's so… big (5 bytes). There must be some way to make this smaller. If only there were a font called ‘A’ (1 byte)…”
Well, it turns out, if you set a font that doesn't exist on the user's system, the canvas will fall back on the system sans-serif by default. On windows that is... Arial. On OS X, it's Helvetica. I'm glad about that because otherwise, Helvetica wouldn't get a look-in, being 9 whole bytes.
There is always the chance that someone will have a font called ‘A’ but I'm willing to take that risk. This possibility could be avoided by using an unlikely character like ♥ for the font name.
The code
These are hosted on GitHub rather than in my usual code blocks to make it easier for you to fork them, pull them apart and get elbow-deep in them.
The almost-impossible-to-read minified submission:
The full, unminified code with thorough commenting:
The submission
My entry is up on the js1k site now. It's already getting quite busy up there after only a few days and I have to say I'm impressed by the fantastic job @kuvos has done in building it up over the last couple of years and providing me with fuel for my addiction.
While putting together last week's promo video for Museum140 (a vote'd be awsm, btw), I knocked up a few tools to make my life easier. As I always say, if you find something you like, make a plugin for it. Seriously, I always say that. That might even be how I proposed to my wife, I'll have to check.
Anyway.
Play
This is a simple timing helper. It just provides a little array you can push slide durations into and at the end, you call 'play'. I can't see many uses for this other than in creating videos.
ImpressJS.play(3000); //Set the first slide duration for 3 seconds
ImpressJS.play(1000); //Set the second slide duration for 1 second
ImpressJS.play(); //Play from the start
Edit
This is much more useful.
If this script is included in the page (after the impress.js script), you can drag your slides around, rotate and scale them into exactly the position you want. Once you're happy, you can get the current HTML output onto the console for pasting back into your original slideshow file. I could have snuck in a drag-n-drop file handler but that would make it Chrome only.
Disclaimer
These tools rely on ImpressJS having a public API which it currently doesn't have. It's obviously high on the author's priority list (given the amount of discussion it's raised) but, as too many pull requests spoil the broth, I've made a little fork of my own, added the public functions the tools require and I'll update them once the main repository's settled down a bit.
Download
These are available in the tools folder of this fork of impress.js. Each one contains an example. Hopefully, these will be updated to use the public API as soon as it's available.
After wrestling with another 140bytes challenge, I found myself wondering how many different ways you can test an object in JS to see if it’s a function. I wrote out a few of them then threw it out to my colleagues who came up with a few more. I’d love to hear from anyone who can suggest more to add to the list. Ideally, you want to find a test that will return true for all functions and only for functions. It’d be great if it’s a universal test that can be slightly modified to test for other types but that’s not essential.
Bear in mind, most of these shouldn’t be used in the real world, this is just for fun.
There are a couple of main categories and several variations within.
Duck Typing
When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.
In other words, if an object has the methods of a function and the properties of a function, it’s probably a duck. No, that doesn’t sound right.
This simply detects whether the object we’re testing contains the methods or properties we’d normally associate with a function. The most common test is checking whether a.call exists. In most cases, this will only be defined on a function and it will be defined on all functions. It is, therefore, a good test to use.
The downside is that it can be fooled by setting a property of call on the object to be truthy. This will pass the test but still not be a function. Also, if the object is null or undefined, this will throw a TypeError (as pointed out by subzey on git).
a.call // Hey, this has a call property. Quack?
a.call && a.call.call // The call also has a call so is probably also a function. Quack.
a.apply // As before but with apply this time
a.apply && a.apply.apply // ditto and ditto
String comparisons on typeof
This area of inspection is probably the richest for coming up with silly ideas to test. The typeof operator simply returns a string containing the type of the object. That’s it. Anything you can think of to compare a string against another string, be it RegEx, charAt, equals or threequals (===) can be manipulated to become a check for type.
typeof a>'f'&&typeof a<'g' // Long-winded and quite silly. Performs a numerical comparison on the strings
(typeof a).charAt(0)=='f' // Sturdy but not very useful.
typeof a==typeof eval // May as well use eval for something, it’s a global function
typeof a==typeof dir // Shorter but might not exist everywhere
typeof a=='function' // The usual way to test. Everything above here is purely academic
/^f/.test(typeof a) // Matching the string against a unique RegEx. See the table below
typeof a==typeof b // Requires access to another variable which is a known function
(typeof a)[0]=='f' // Small and robust but doesn’t work in IE6 or 7
Table of RegEx Patterns to match object types:
As little aside here, we’ve got a table of simple RegEx tests that do the same as the one mentioned above. They return true if the type is what you expect, false for all other types. They work by assuming things like ‘object’ being the only type to contain a ‘j’ or ‘boolean’ being the only one with an ‘a’.
Type RegEx Note
boolean /a/.test(typeof a) // Shorter than typeof a==‘boolean’
function /^f/.test(typeof a) // Shorter than typeof a==‘function’
undefined /d/.test(typeof a) // Shorter than typeof a==‘undefined’
number /m/.test(typeof a) // Same length as typeof a==‘number’
object /j/.test(typeof a) // Same length as typeof a==‘object’
string /s/.test(typeof a) // Same length as typeof a==‘string’
null /ll/.test(typeof a) // Longer than typeof a==‘null’
Pick & Mix
This not only makes the assumption that an object is probably a function if it contains a ‘call’ but also that if that call has the same type as the object, they’re both probably functions.
typeof a==typeof a.call // A mixture of typeof string comparison and duck typing
instanceof
In some circumstances, instanceof is going to be better than typeof as it compares types rather than strings.
a instanceof Function // This will throw a ReferenceError if a is undefined.
The [[Class]] of the object
This comes from the JavaScript Garden where you’ll find they have a strong opinion on typeof and instanceof. This uses call to execute the toString method on the prototype of the basic Object constructor. Phew. At that point, you'd have a string ‘[Object Function]’. You can then chop off the beginning and the end using slice (treating the string as if it were an array) to get just the type. All together, it looks like this:
Object.prototype.toString.call(a).slice(8, -1);
Testing the string representation of the object
This is fairly nasty but still quite effective. Convert the object itself to a string (not its type but the actual object) and see if that begins with ‘function’. This is nowhere nearly as robust as some of the other tests as this will also pass true for any strings that begin "function..." but it’s quite cunning. Credit goes to Max for this one.
/^function/.test(a.toString()) //Test if the output of .toString() begins with ‘function’
/^function/.test(a+"") //As above but using a shortcut to coerce the function to a string.
Running it
This isn’t so much checking whether it looks and sounds like a duck, this is more like serving it à l’orange and seeing if it tastes like a duck. The idea here is to actually try and execute it. If it throws an error, it’s not executable, if it doesn’t, it is. Or something like that. Here, we’re testing that the error is an instanceof TypeError as an undefined object would also end up in the catch.
The obvious downfall to this technique is that you don’t necessarily want the function executed when you’re testing it. In fact, you almost never want to do that. I might go as far as to say you never want that.
The other big weakness in the above technique is that, even if the object is a function, the call itself might throw a TypeError. In Chrome, there's a bit more transparency as the error thrown has a type property. In that case you want to check that the type is 'called_non_callable' but that might still be a consequence of the function. In Safari, there's a similar property on the error (e.message) but the error object itself is no longer a TypeError, it is just an Error.
More…
I’m certain there are more. Many, many more. There are also several dozen that are trivial variations on those mentioned above – you could do the same string comparison tests on the [[Class]] property, for instance – but I missed these out. There’s probably a huge section missed out here (I'd forgotten instanceof existed until after the first draft of this post, for instance). If you can think of any more, let me know here or on The Twitter.
I'll also reiterate my point from earlier: most of these are deliberately useless or inefficient. The point here isn't to find better ways to do things, it's to practice doing what you do every day. The more you play while being a web developer, the less you need to work.