📜 ⬆️ ⬇️

Code Compression Techniques

Jed Schmidt, Thomas Fuchs and Dustin Diaz - guys who are quite famous in the JavaScript community recently found a new party for themselves - writing useful things of no more than one tweet, that is 140 bytes. Even the domain was registered - 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 code are used. They have a wiki page with tips, which I decided to translate.

At once I will make a reservation that the readability of the code processed in this way tends to zero, so it is worth using these tricks only in cases when the size is really above all. For example, when participating in a JS1k contest.
')
So.

Arguments


Use single-letter positional arguments in alphabetical order.


Since the function arguments should be as short as possible and most likely will be used several times during execution, it is easier to view them in terms of position and name them alphabetically, 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


You can use in to check for an argument.
 arguments.length>1||(cb=alert) //  1 in arguments||(cb=alert) //  


Variables


Use extra arguments instead of var


You can save several bytes by specifying an extra argument in a 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 an assignment statement returns an assignment 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 a temporary storage in order 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 type conversion when adding


Type casting in JS works very strangely and is one of the most common source of bugs. However, it can be used in various interesting ways to reduce the size of the code.
For example, in the pubsub implementation , Jed Schmidt decremented a variable with a negative number, and then added it to the string, getting something like "somestring-123" .
After that, in another place I used .split('-') to get the source string.

Cycles


Drop the loop body


Often you can implement all the logic inside the conditions and save on the body of the loop.
A good example of this approach can be found in the timeAgo function.

Use for instead of while


for and while usually take the same number of bytes, but for gives you more control and more possibilities for assignment.
 while(i--){...} //  for(;i--;){...} //  i=10;while(i--){...} //  for(i=10;i--;){...} //  


Use fast iteration on “true” arrays


If you have an array, all members of which are knowingly cast to true, you can use a shorter loop record:
 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..in with assignment to get object keys.


 a=[];for(b in window)a.push(window[b]) //  a=[];i=0;for(a[i++]in window); //  


Operators


Learn operator priority


This knowledge can help save a lot of brackets.
You can start by exploring this article on the Mozilla website.

Use ~ c indexOf


 hasAnF="This sentence has an f.".indexOf("f")>=0 //  hasAnF=~"This sentence has an f.".indexOf("f") //  


Use a comma to execute statements instead of block


 with(document){open();write("hello");close()} //  with(document)open(),write("hello"),close() //  


Use shorter ways to write undefined


Instead of undefined you can use []._ or void 0 .
There are options ""._ , 1.._ and [][0] , but they are much slower .

Remove optional spaces before operators


Sometimes spaces after the operators can be safely removed.
 typeof [] //  typeof[] //  


Numbers


Use ~~ or 0| instead of Math.floor


 rand10=Math.floor(Math.random()*10) //  rand10=0|Math.random()*10 //  


Use exponential format for large round numbers.


 million=1000000 //  million=1e6 //  


Use bitwise shifts for large binary numbers.


 color=0x100000 //  color=1<<20 //  


Use 1/0 instead of Infinity


It is shorter. Besides, zeroing 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 by one


In combination with the unary minus, this makes it possible, for example, to increment any variable that is not yet defined.
 // i = undefined i=i||0;i++ //  i=-~i //  


Strings


Break the lines with a zero


You can save two bytes when splitting rows with the split method, if you use zero as a separator:
 'alpha,bravo,charlie'.split(',') //  'alpha0bravo0charlie'.split(0) //  


Use browser link method


Strings in browsers have a not very well-known link method that creates an html link.
 html="<a href='"+url+"'>"+text+"</a>" //  html=text.link(url) //  


Use the replace and exec methods to iterate through the rows.


These methods allow you to pass a function as a second argument. This can be used for easy 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 of /\d{2}/ .

You can use eval instead of the regular constructor:
 r=new RegExp("{"+p+"}","g") //  r=eval("/{"+p+"}/g") //  


Boolean


Use ! with numbers to create true and 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 function walk .

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){return function(){console.log("called "+(++i)+" times")}}(0) //  (function a(){console.log("called "+(ai=-~ai)+" times")}) //  0,function a(){console.log("called "+(ai=-~ai)+" times")} //   


Drop brackets when calling the constructor with no arguments


 now = +new Date() //  now = +new Date //  


Omit the new keyword where possible


Some constructors do not necessarily need the new keyword.
 r=new Regexp(".",g) //  r=Regexp(".",g) //  l=new Function("x","console.log(x)") //  l=Function("x","console.log(x)") //  


Operator return


When you need to return something other than a variable, it is not necessary to put a space after return .
 return ['foo',42,'bar']; //  return['foo',42,'bar']; //  return {x:42,y:417}; //  return{x:42,y:417}; //  return .01; //  return.01; //  


For now.

In general, I recommend to get acquainted with the fruits of their work. In attempts to fit complex things into 140 bytes, the guys sometimes just work wonders. I think even an experienced programmer will find something new and interesting in their code.

Source: https://habr.com/ru/post/119898/


All Articles