[EN] My entry for the DailyJS “contest”
Last Friday, DailyJS had 5 digital subscriptions to Hacker Monthly to give away. They set up a small one-liner contest:
If you’d like to read more from Hacker Monthly, we’ve got 5 digital subscriptions to give away — worth $29 each! Just post a comment with your favourite JavaScript one-liner, and I’ll select 5 winners.
Thanks to this piece of code, I am the happy winner of one of the subscriptions:
(function ___(__){return function(_){return _!='?' && ___(__+_) || __+'!';};})('d')('a')('i')('l')('y')('j')('s')(' ')('r')('o')('c')('k')('s')('?') |
In this article, I’ll explain what it does and how it works.
What it does?
If you copy/paste/run it in your favorite JavaScript debugger you’ll see that the weirdly formatted question ('d')('a')('i')('l')('y')('j')('s')(' ')('r')('o')('c')('k')('s')('?') is answered: "dailyjs rocks!"
Yes, this was blatant flattery (even called ass-kissing
). Well… It worked!
How it works?
To understand it I am going to uncompress this one-liner bit by bit.
Let’s add some new lines and spaces:
(function ___(__){ return function (_){ return _ != '?' && ___(__ + _) || __ + '!'; }; }) ('d')('a')('i')('l')('y')('j')('s')(' ')('r')('o')('c')('k')('s')('?') |
I obviously use the underscore character to make the variable and function names more meaningful. Who wants obscure names like these:
(function createAccumulator(allPreviousLetter){ return function (newLetter){ return newLetter != '?' && createAccumulator(allPreviousLetter + newLetter) || allPreviousLetter + '!'; }; }) ('d')('a')('i')('l')('y')('j')('s')(' ')('r')('o')('c')('k')('s')('?') |
createAccumulator is the best name I could think of but it’s not that good… I really prefer ___.
It’s more readable now but what is this && and || stuff ?
You know what it means here:
if( conditionA && conditionB || conditionC){ } |
Since JavaScript is fun, you can use objects instead of booleans and it works since there are such things as truthy and falsy values (“” == false, for instance).
if( newLetter != '?' && someFn() || someString ){ } |
What more interesting is that if (A && B) is true, it doesn’t “returns” true but it returns B! You probably use the same feature with || to specify a default value:
var a = b || c; |
So with all this knowledge it’s easy to translate
return newLetter != '?' && createAccumulator(allPreviousLetter + newLetter) || allPreviousLetter + '!'; |
into:
return newLetter != '?' ? createAccumulator(allPreviousLetter + newLetter) : ( allPreviousLetter + '!' ); |
or more readable:
if ( newLetter != '?' ){ return createAccumulator(allPreviousLetter + newLetter); } else { return allPreviousLetter + '!'; } |
Now let’s remove this disturbing Immediately-Invoked Function Expression (IIFE) and these chained function calls.
function createAccumulator(allPreviousLetter){ return function (newLetter){ if ( newLetter != '?' ){ return createAccumulator(allPreviousLetter + newLetter); } else { return allPreviousLetter + '!'; } }; } var accumulate_D_and_return_a_new_accumulator = createAccumulator('d'); var accumulate_DA_and_return_a_new_accumulator = accumulate_D_and_return_a_new_accumulator ('a'); var accumulate_DAI_and_return_a_new_accumulator = accumulate_DA_and_return_a_new_accumulator('i'); //… var lastOne = accumulate_STUFF_and_return_a_new_accumulator('s'); var totalStringWithExclamationMark = lastOne('?'); |
Crystal clear now, isn’t it?
« Controler deux machines avec un seul clavier/souris et x2x
[EN] Change Firebug’s own style »