Code Compression Techniques
- Transfer
Jed Schmidt, Thomas Fuchs and Dustin Diaz - guys quite well-known in the JavaScript community recently found a new amusement - writing useful things no larger than one tweet, i.e. 140 bytes. They even registered a domain - 140byt.es , where everyone is invited to try their hand at writing super-compact functions.
Naturally, all the most sophisticated methods and techniques for reducing the size of the source are used. They have a wiki page with tips, which I decided to translate.
I must say right away that the readability of the code processed in this way tends to zero, so it’s worth using these tricks only in cases when the size is really above all. For example, when participating in the JS1k contest.
So.
Since function arguments should be as short as possible, and most likely to be used several times at run time, it is easier to consider them in terms of position and name them in alphabetical order, rather than trying to give them any meaningful names.
Can be used
Use "extra" arguments instead
You can save a few bytes by specifying an extra argument in the function, instead of declaring a variable with
Since the assignment operator returns the assigned value, you can use assignment and validation at the same time:
The array can be used as temporary storage, so as not to declare an extra variable.
Type conversion in JS works very strange and is one of the most common source of bugs. However, it can be used in various interesting ways to reduce code size.
For example, in a pubsub implementation , Jed Schmidt decremented a variable with a negative number, and then added it to the string, getting something of the kind
After that, in another place I used
Often, you can implement all the logic inside the conditions and save on the body of the cycle.
A good example of this approach can be seen in the timeAgo function .
If you have an array whose members are all known to be true, you can use a shorter loop entry:
Use
This knowledge can help save a lot on brackets.
You can start by exploring this article on the Mozilla website.
Use
Use shorter recording methods
Instead,
There are options
Sometimes spaces after operators can be removed painlessly.
Use
Use
It is shorter. In addition, dividing by zero is always fun.
Instead of comparing numbers, it is sometimes shorter to reduce the value to zero and check its truth.
Use
In combination with the unary minus, this makes it possible, for example, to increment any variable that has not yet been defined.
You can save two bytes when splitting strings by the method
Use browser method
Lines in browsers have a not-so-well-known method
Use
These methods allow you to pass a function as the second argument. This can be used for convenient iteration over the line.
Examples of use: templates and UUID .
Use
Can be used
Use
This is often shorter, because it allows you to drag values through the stack, without unnecessary variables.
As an example, the walk function .
If you need to store the state between function calls, you can use the function as an object and store data in its properties:
Some designers do not necessarily have a keyword
When you need to return something other than a variable, putting a space after is
That's all for now.
In general, I recommend that you familiarize yourself with the fruits of their work. In attempts to fit complex things into 140 bytes, guys sometimes just work wonders. I think even an experienced programmer will find something new and interesting in their code.
Naturally, all the most sophisticated methods and techniques for reducing the size of the source are used. They have a wiki page with tips, which I decided to translate.
I must say right away that the readability of the code processed in this way tends to zero, so it’s worth using these tricks only in cases when the size is really above all. For example, when participating in the JS1k contest.
So.
Arguments
Use single-letter positional arguments in alphabetical order
Since function arguments should be as short as possible, and most likely to be used several times at run time, it is easier to consider them in terms of position and name them in alphabetical order, rather than trying to give them any meaningful names.
function(t,d,v,i,f){...} // доfunction(a,b,c,d,e){...} // послеCheck for arguments instead of length
Can be used
into check for an argument.arguments.length>1||(cb=alert) // до1inarguments||(cb=alert) // послеVariables
Use "extra" arguments instead var
You can save a few bytes by specifying an extra argument in the function, instead of declaring a variable with
var:function(a){var b=1;...} // доfunction(a,b){b=1;...} // послеUse variables several times
setTimeout(function(){for(var i=10;i--;)... }, a) // до
setTimeout(function(){for(a=10;a--;)... }, a) // послеUse Assignment Where Possible
Since the assignment operator returns the assigned value, you can use assignment and validation at the same time:
a=this.localStorage;if(a){...} // доif(a=this.localStorage){...} // послеUse an array to swap variables
The array can be used as temporary storage, so as not to declare an extra variable.
var a=1,b=2,c;c=a;a=b;b=c // доvar a=1,b=2;a=[b,b=a][0] // послеUse casting when adding
Type conversion in JS works very strange and is one of the most common source of bugs. However, it can be used in various interesting ways to reduce code size.
For example, in a pubsub implementation , Jed Schmidt decremented a variable with a negative number, and then added it to the string, getting something of the kind
"somestring-123". After that, in another place I used
.split('-')to get the source string.Cycles
Lower the body of the loop
Often, you can implement all the logic inside the conditions and save on the body of the cycle.
A good example of this approach can be seen in the timeAgo function .
Use for instead of while
forand whileusually occupy the same amount of bytes, but forallows you to get more control and more opportunities for assignment.while(i--){...} // доfor(;i--;){...} // после
i=10;while(i--){...} // доfor(i=10;i--;){...} // послеUse fast iteration over “true” arrays
If you have an array whose members are all known to be true, you can use a shorter loop entry:
for(a=[1,2,3,4,5],l=a.length,i=0;i<l;i++){b=a[i];...} // доfor(a=[1,2,3,4,5],i=0;b=a[i++];){...} // послеUse for..inwith assignment to get object keys
a=[];for(b inwindow)a.push(window[b]) // до
a=[];i=0;for(a[i++]inwindow); // послеOperators
Learn operator priority
This knowledge can help save a lot on brackets.
You can start by exploring this article on the Mozilla website.
Use ~cindexOf
hasAnF="This sentence has an f.".indexOf("f")>=0// до
hasAnF=~"This sentence has an f.".indexOf("f") // послеUse a comma to execute statements sequentially instead of a block
with(document){open();write("hello");close()} // доwith(document)open(),write("hello"),close() // послеUse shorter recording methods undefined
Instead,
undefinedyou can use []._or void 0. There are options
""._, 1.._and [][0], but they are much slower .Remove optional spaces before operators
Sometimes spaces after operators can be removed painlessly.
typeof [] // доtypeof[] // послеThe numbers
Use ~~or 0|insteadMath.floor
rand10=Math.floor(Math.random()*10) // до
rand10=0|Math.random()*10// послеUse exponential format for large round numbers
million=1000000// до
million=1e6// послеUse bit shifts for large binary numbers
color=0x100000// до
color=1<<20// послеUse 1/0insteadInfinity
It is shorter. In addition, dividing by zero is always fun.
[Infinity,-Infinity] // до
[1/0,-1/0] // послеUse the falsity of zero
Instead of comparing numbers, it is sometimes shorter to reduce the value to zero and check its truth.
a==1||console.log("not one") // до
~-a&&console.log("not one") // послеUse ~to change any value to one.
In combination with the unary minus, this makes it possible, for example, to increment any variable that has not yet been defined.
// i = undefined
i=i||0;i++ // до
i=-~i // послеLines
Break lines with zero
You can save two bytes when splitting strings by the method
split, if you use zero as a separator:'alpha,bravo,charlie'.split(',') // до'alpha0bravo0charlie'.split(0) // послеUse browser method link
Lines in browsers have a not-so-well-known method
linkthat creates an html link.html="<a href='"+url+"'>"+text+"</a>"// до
html=text.link(url) // послеUse replaceand methods execto iterate through the lines
These methods allow you to pass a function as the second argument. This can be used for convenient iteration over the line.
Examples of use: templates and UUID .
Use arrays to create simple strings.
for(a="",i=32;i--;)a+=0// до
a=Array(33).join(0) // послеRegular expressions
Use
{n}to shorten regular expressions. For example, /\d{3}/instead of /\d\d\d/. And vice versa /\d\d/instead /\d{2}/. Can be used
evalinstead of the regular constructor constructor:r=newRegExp("{"+p+"}","g") // до
r=eval("/{"+p+"}/g") // послеBoolean
Use
!with numbers to create trueand false.[true,false] // до
[!0,!1] // послеFunctions
Use named functions for recursion instead of loops
This is often shorter, because it allows you to drag values through the stack, without unnecessary variables.
As an example, the walk function .
Use named functions to store state
If you need to store the state between function calls, you can use the function as an object and store data in its properties:
function(i){returnfunction(){console.log("called "+(++i)+" times")}}(0) // до
(functiona(){console.log("called "+(a.i=-~a.i)+" times")}) // после0,functiona(){console.log("called "+(a.i=-~a.i)+" times")} // еще вариантOmit brackets when calling constructor without arguments
now = +newDate() // до
now = +newDate// послеOmit the new keyword where possible
Some designers do not necessarily have a keyword
new.r=new Regexp(".",g) // до
r=Regexp(".",g) // после
l=newFunction("x","console.log(x)") // до
l=Function("x","console.log(x)") // послеReturn statement
When you need to return something other than a variable, putting a space after is
returnnot necessary.return ['foo',42,'bar']; // доreturn['foo',42,'bar']; // послеreturn {x:42,y:417}; // доreturn{x:42,y:417}; // послеreturn.01; // доreturn.01; // послеThat's all for now.
In general, I recommend that you familiarize yourself with the fruits of their work. In attempts to fit complex things into 140 bytes, guys sometimes just work wonders. I think even an experienced programmer will find something new and interesting in their code.