45 Useful JavaScript Tips, Tricks and Best Practices

keep-calm-and-learn-javascript

By Saad Mousliki

As you know, JavaScript is the number one programming language in the world, the language of the web, of mobile hybrid apps (like PhoneGap or Appcelerator), of the server side (like NodeJS or Wakanda) and has many other implementations. It’s also the starting point for many new developers to the world of programming, as it can be used to display a simple alert in the web browser but also to control a robot (using nodebot, or nodruino). The developers who master JavaScript and write organized and performant code have become the most sought after in the job market.

In this article, I’ll share a set of JavaScript tips, tricks and best practices that should be known by all JavaScript developers regardless of their browser/engine or the SSJS (Server Side JavaScript) interpreter.

Note that the code snippets in this article have been tested in the latest Google Chrome version 30, which uses the V8 JavaScript Engine (V8 3.20.17.15).

1 – Don’t forget var keyword when assigning a variable’s value for the first time.

Assignment to an undeclared variable automatically results in a global variable being created. Avoid global variables.

2 – use === instead of ==

The == (or !=) operator performs an automatic type conversion if needed. The === (or !==) operator will not perform any conversion. It compares the value and the type, which could be considered faster than ==.

[10] === 10    // is false
[10]  == 10    // is true
'10' == 10     // is true
'10' === 10    // is false
 []   == 0     // is true
 [] ===  0     // is false
 '' == false   // is true but true == "a" is false
 '' ===   false // is false 

3 – undefined, null, 0, false, NaN, '' (empty string) are all falsy.
4 – Use Semicolons for line termination

The use of semi-colons for line termination is a good practice. You won’t be warned if you forget it, because in most cases it will be inserted by the JavaScript parser. For more details about why you should use semi-colons, take a look to this artice: http://davidwalsh.name/javascript-semicolons.

5 – Create an object constructor

function Person(firstName, lastName){
    this.firstName =  firstName;
    this.lastName = lastName;        
}  

var Saad = new Person("Saad", "Mousliki");

6 – Be careful when using typeof, instanceof and constructor.

  • typeof : a JavaScript unary operator used to  return a string that represents the primitive type of a variable,  don’t forget that typeof null will return “object”, and for the majority of object types (Array, Date, and others) will return also “object”.
  • constructor : is a property of the internal prototype property, which could be overridden by code.
  • instanceof : is another JavaScript operator that check in all the prototypes chain the constructor it returns true if it’s found and false if not.
var arr = ["a", "b", "c"];
typeof arr;   // return "object" 
arr  instanceof Array // true
arr.constructor();  //[]

7 – Create a Self-calling Function

This is often called a Self-Invoked Anonymous Function or Immediately Invoked Function Expression (IIFE). It is a function that executes automatically when you create it, and has the following form:

(function(){
    // some private code that will be executed automatically
})();  
(function(a,b){
    var result = a+b;
    return result;
})(10,20)

8 – Get a random item from an array

var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];

var  randomItem = items[Math.floor(Math.random() * items.length)];

9 – Get a random number in a specific range

This code snippet can be useful when trying to generate fake data for testing purposes, such as a salary between min and max.

var x = Math.floor(Math.random() * (max - min + 1)) + min;

10 – Generate an array of numbers with numbers from 0 to max

var numbersArray = [] , max = 100;

for( var i=1; numbersArray.push(i++) < max;);  // numbers = [1,2,3 ... 100] 

11 – Generate a random set of alphanumeric characters

function generateRandomAlphaNum(len) {
    var rdmString = "";
    for( ; rdmString.length < len; rdmString  += Math.random().toString(36).substr(2));
    return  rdmString.substr(0, len);

}

12 – Shuffle an array of numbers

var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
numbers = numbers.sort(function(){ return Math.random() - 0.5});
/* the array numbers will be equal for example to [120, 5, 228, -215, 400, 458, -85411, 122205]  */

A better option could be to implement a random sort order by code (e.g. : Fisher-Yates shuffle), than using the native sort JavaScript function. For more details take a look to this discussion.

13 – A string trim function

The classic trim function of Java, C#, PHP and many other language that remove whitespace from a string doesn’t exist in JavaScript, so we could add it to the String object.

String.prototype.trim = function(){return this.replace(/^\s+|\s+$/g, "");};  

A native implementation of the trim() function is available in the recent JavaScript engines.

14 – Append an array to another array

var array1 = [12 , "foo" , {name "Joe"} , -2458];

var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* array1 will be equal to  [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */

15 – Transform the arguments object into an array

var argArray = Array.prototype.slice.call(arguments);

16 – Verify that a given argument is a number

function isNumber(n){
    return !isNaN(parseFloat(n)) && isFinite(n);
}

17 – Verify that a given argument is an array

function isArray(obj){
    return Object.prototype.toString.call(obj) === '[object Array]' ;
}

Note that if the toString() method is overridden, you will not get the expected result using this trick.

Or use…

Array.isArray(obj); // its a new Array method

You could also use instanceof if you are not working with multiple frames. However, if you have many contexts, you will get a wrong result.

var myFrame = document.createElement('iframe');
document.body.appendChild(myFrame);

var myArray = window.frames[window.frames.length-1].Array;
var arr = new myArray(a,b,10); // [a,b,10]  

// instanceof will not work correctly, myArray loses his constructor 
// constructor is not shared between frames
arr instanceof Array; // false

18 – Get the max or the min in an array of numbers

var  numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411]; 
var maxInNumbers = Math.max.apply(Math, numbers); 
var minInNumbers = Math.min.apply(Math, numbers);

19 – Empty an array

var myArray = [12 , 222 , 1000 ];  
myArray.length = 0; // myArray will be equal to [].

20 – Don’t use delete to remove an item from array

Use splice instead of using delete to delete an item from an array. Using delete replaces the item with undefined instead of the removing it from the array.

Instead of…

var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ]; 
items.length; // return 11 
delete items[3]; // return true 
items.length; // return 11 
/* items will be equal to [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154,       119]   */

Use…

var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ]; 
items.length; // return 11 
items.splice(3,1) ; 
items.length; // return 10 
/* items will be equal to [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154,       119]   */

The delete method should be used to delete an object property.

21 – Truncate an array using length

Like the previous example of emptying an array, we truncate it using the length property.

var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];  
myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].

As a bonus, if you set the array length to a higher value, the length will be changed and new items will be added with undefined as a value. The array length is not a read only property.

myArray.length = 10; // the new array length is 10 
myArray[myArray.length - 1] ; // undefined

22 – Use logical AND/ OR for conditions

var foo = 10;  
foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething(); 
foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();

The logical OR could also be used to set a default value for function argument.

function doSomething(arg1){ 
    arg1 = arg1 || 10; // arg1 will have 10 as a default value if it’s not already set
}

23 – Use the map() function method to loop through an array’s items

var squares = [1,2,3,4].map(function (val) {  
    return val * val;  
}); 
// squares will be equal to [1, 4, 9, 16] 

24 – Rounding number to N decimal place

var num =2.443242342;
num = num.toFixed(4);  // num will be equal to 2.4432

NOTE : the toFixed() function returns a string and not a number.

25 – Floating point problems

0.1 + 0.2 === 0.3 // is false 
9007199254740992 + 1 // is equal to 9007199254740992  
9007199254740992 + 2 // is equal to 9007199254740994

Why does this happen? 0.1 +0.2 is equal to 0.30000000000000004. What you need to know is that all JavaScript numbers are floating points represented internally in 64 bit binary according to the IEEE 754 standard. For more explanation, take a look to this blog post.

You can use toFixed() and toPrecision() to resolve this problem.

26 – Check the properties of an object when using a for-in loop

This code snippet could be useful in order to avoid iterating through the properties from the object’s prototype.

for (var name in object) {  
    if (object.hasOwnProperty(name)) { 
        // do something with name                    
    }  
}

27 – Comma operator

var a = 0; 
var b = ( a++, 99 ); 
console.log(a);  // a will be equal to 1 
console.log(b);  // b is equal to 99

28 – Cache variables that need calculation or querying

In the case of a jQuery selector, we could cache the DOM element.

var navright = document.querySelector('#right'); 
var navleft = document.querySelector('#left'); 
var navup = document.querySelector('#up'); 
var navdown = document.querySelector('#down');

29 – Verify the argument before passing it to isFinite()

isFinite(0/0) ; // false 
isFinite("foo"); // false 
isFinite("10"); // true 
isFinite(10);   // true 
isFinite(undefined);  // false 
isFinite();   // false 
isFinite(null);  // true  !!! 

30 – Avoid negative indexes in arrays

var numbersArray = [1,2,3,4,5]; 
var from = numbersArray.indexOf("foo") ;  // from is equal to -1 
numbersArray.splice(from,2);    // will return [5]

Make sure that the arguments passed to splice are not negative.

31 – Serialization and deserialization (working with JSON)

var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} }; 
var stringFromPerson = JSON.stringify(person); 
/* stringFromPerson is equal to "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}"   */ 
var personFromString = JSON.parse(stringFromPerson);  
/* personFromString is equal to person object  */

32 – Avoid the use of eval() or the Function constructor

Use of eval or the Function constructor are expensive operations as each time they are called script engine must convert source code to executable code.

var func1 = new Function(functionCode);
var func2 = eval(functionCode);

33 – Avoid using with() (The good part)

Using with() inserts a variable at the global scope. Thus, if another variable has the same name it could cause confusion and overwrite the value.

34 – Avoid using for-in loop for arrays

Instead of using…

var sum = 0;  
for (var i in arrayNumbers) {  
    sum += arrayNumbers[i];  
}

…it’s better to use…

var sum = 0;  
for (var i = 0, len = arrayNumbers.length; i < len; i++) {  
    sum += arrayNumbers[i];  
}

As a bonus, the instantiation of i and len is executed once because it’s in the first statement of the for loop. Thsi is faster than using…

for (var i = 0; i < arrayNumbers.length; i++)

Why? The length of the array arrayNumbers is recalculated every time the loop iterates.

NOTE : the issue of recalculating the length in each iteration was fixed in the latest JavaScript engines.

35 – Pass functions, not strings, to setTimeout() and setInterval()

If you pass a string into setTimeout() or setInterval(), the string will be evaluated the same way as with eval, which is slow. Instead of using…

setInterval('doSomethingPeriodically()', 1000);  
setTimeout('doSomethingAfterFiveSeconds()', 5000);

…use…

setInterval(doSomethingPeriodically, 1000);  
setTimeout(doSomethingAfterFiveSeconds, 5000);

36 – Use a switch/case statement instead of a series of if/else

Using switch/case is faster when there are more than 2 cases, and it is more elegant (better organized code). Avoid using it when you have more than 10 cases.

37 – Use switch/case statement with numeric ranges

Using a switch/case statement with numeric ranges is possible with this trick.

function getCategory(age) {  
    var category = "";  
    switch (true) {  
        case isNaN(age):  
            category = "not an age";  
            break;  
        case (age >= 50):  
            category = "Old";  
            break;  
        case (age <= 20):  
            category = "Baby";  
            break;  
        default:  
            category = "Young";  
            break;  
    };  
    return category;  
}  
getCategory(5);  // will return "Baby"

38 – Create an object whose prototype is a given object

It’s possible to write a function that creates an object whose prototype is the given argument like this…

function clone(object) {  
    function OneShotConstructor(){}; 
    OneShotConstructor.prototype= object;  
    return new OneShotConstructor(); 
} 
clone(Array).prototype ;  // []

39 – An HTML escaper function

function escapeHTML(text) {  
    var replacements= {"<": "&lt;", ">": "&gt;","&": "&amp;", "\"": "&quot;"};                      
    return text.replace(/[<>&"]/g, function(character) {  
        return replacements[character];  
    }); 
}

40 – Avoid using try-catch-finally inside a loop

The try-catch-finally construct creates a new variable in the current scope at runtime each time the catch clause is executed where the caught exception object is assigned to a variable.

Instead of using…

var object = ['foo', 'bar'], i;  
for (i = 0, len = object.length; i <len; i++) {  
    try {  
        // do something that throws an exception 
    }  
    catch (e) {   
        // handle exception  
    } 
}

…use…

var object = ['foo', 'bar'], i;  
try { 
    for (i = 0, len = object.length; i <len; i++) {  
        // do something that throws an exception 
    } 
} 
catch (e) {   
    // handle exception  
} 

41 – Set timeouts to XMLHttpRequests

You could abort the connection if an XHR takes a long time (for example, due to a network issue), by using setTimeout() with the XHR call.

var xhr = new XMLHttpRequest (); 
xhr.onreadystatechange = function () {  
    if (this.readyState == 4) {  
        clearTimeout(timeout);  
        // do something with response data 
    }  
}  
var timeout = setTimeout( function () {  
    xhr.abort(); // call error callback  
}, 60*1000 /* timeout after a minute */ ); 
xhr.open('GET', url, true);  

xhr.send();

As a bonus, you should generally avoid synchronous XHR calls completely.

42 – Deal with WebSocket timeout

Generally when a WebSocket connection is established, a server could time out your connection after 30 seconds of inactivity. The firewall could also time out the connection after a period of inactivity.

To deal with the timeout issue you could send an empty message to the server periodically. To do this, add these two functions to your code: one to keep alive the connection and the other one to cancel the keep alive. Using this trick, you’ll control the timeout.

Add a timerID

var timerID = 0; 
function keepAlive() { 
    var timeout = 15000;  
    if (webSocket.readyState == webSocket.OPEN) {  
        webSocket.send('');  
    }  
    timerId = setTimeout(keepAlive, timeout);  
}  
function cancelKeepAlive() {  
    if (timerId) {  
        cancelTimeout(timerId);  
    }  
}

The keepAlive() function should be added at the end of the onOpen() method of the webSocket connection and the cancelKeepAlive() at the end of the onClose() method.

43 – Keep in mind that primitive operations can be faster than function calls. Use VanillaJS.

For example, instead of using…

var min = Math.min(a,b); 
A.push(v);

…use…

var min = a < b ? a : b; 
A[A.length] = v;

44 – Don’t forget to use a code beautifier when coding. Use JSLint and minification (JSMin, for example) before going live.

45 – JavaScript is awesome: Best Resources To Learn JavaScript

Conclusion

I know that there are many other tips, tricks and best practices, so if you have any ones to add or if you have any feedback or corrections to the ones that I have shared, please adda comment.

References

In this article I have used my own code snippets. Some of the snippets are inspired from other articles and forums:

Modern Web Newsletter

Subscribe to receive the Modern Web tutorials, sent out every second Wednesday.

  • http://incroya.bl.ee Dimitri Nicolas

    23 – Use the map() functio* method [...]

    • https://plus.google.com/104639715967304245815/posts Saad

      Thanks Dimitri, We’ll update it ASAP

  • http://www.helpknow.com William

    #8 the array has a syntax error

    // ;

    • https://plus.google.com/104639715967304245815/posts Saad

      Thanks William, We’ll update it ASAP

  • http://www.naveenbhat.in Naveen Bhat

    Nice article, good set of tips.

  • Thomas

    Your tipps are very suggestive, without explaining the cases where they apply. Some suggestions will do some complete different flow, for example the first tip: You do not explain wha’s the difference when you ‘forget’ the variable declaration, so the tip is useless and somehow dangerous.

    Same as with tip 40: The two variants you mention have a complete different logic. The one which you say to avoid executes the catch every loop interval, the second breakes the loop when the error occours. It depends on what’s your target which form you shoud use.

    And last but not least you should recognize your own tips in your example: In tip 37 you don’t do what you insist in tip 2 (use === instead of ==) This applies also to >== <== etc. of course.

    • https://plus.google.com/104639715967304245815/posts Saad

      Thanks Thomas, I’m a developer and I know that when a developer need a quick list of snippets that is verified/tested and approved, he will not spend his time reading a long explanation and test it again, he need some things which could copy/paste and use it quickly in his code.

      Regards

      • Murthy

        Saad, I’m a developer too and have moved to web from windows applications recently. Sorry to say but I agree with Thomas. I understand you have put a lot of effort in writing this article but would definitely appreciate if it was more elaborate. I would rather understand the concept before “copy/pasting” your code. Hope to see a much more elaborate article. Thanks

        • https://plus.google.com/104639715967304245815/posts Saad

          Thanks Murthy, I think that I’ll update the article with some links to JsPerf tests, and other articles too, hope that I find time for that …

      • http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1213/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR.aspx Richard Waddell

        Saad, Thanks for the great tips. I actually appreciate the brevity. Hopefully I can work out the rest for myself if I need to.

        On #40 I’d say the advice should be that exception handling is expensive so it should be used only for exception handling, not error handling. Probably the only time I would use exception handling in an inner loop is in some kind of batch process where you don’t want some unanticipated error in data or code to abort the entire run. Once an exception has been logged however, you should either fix the code (obviously) or code to anticipate what is now a known error and handle it instead of throwing an exception. In my experience some developers get the concept confused and think that coding for exceptions is expensive. Not so – it’s only expensive if it actually has to handle an exception.

    • http://www.google.com SyntaxError

      Since there are no strict comparison operators in JavaScript, 37 is fine.

      • duq

        There *are* strict comparisons in JS, see #2.

    • Javier

      Sounds like T Maul

  • http://gotofritz.net gotofritz

    What on earth is the benefit of #27 – Comma operator??

    • https://plus.google.com/104639715967304245815 Saad

      IMHO it could be considered as a trick that should be known by a JavaScript developer, you could see it somewhere and don’t understand it ;)

      • http://gotofritz.net gotofritz

        …errrr… a trick to achieve what?

        in that case you should include all the golfing tricks too

        I’m sorry, but to me that’s utterly pointless

        • http://jtmpl.com atmin

          Check https://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/ for use cases.

          Example:

          if (expression) { doSomething(); return something; } else { doSomethingElse(); return somethingElse; }

          vs

          return expression ? (doSomething(), something) : (doSomethingElse(), somethingElse);

          • https://plus.google.com/104639715967304245815 Saad

            Thanks atmin for this illustration ;)

  • VeX

    Just as a reference, doesn’t #22 implement #2 either.

  • https://plus.google.com/104639715967304245815 Saad

    The second best practice will be updated by a clear explanation, sorry for the inconvenience

  • http://google.com Lazurowy

    #43 I think speed of
    A.push(v);
    and
    A[A.length] = v;
    depend on browser
    http://jsperf.com/push-vs-length-test

    • https://plus.google.com/104639715967304245815 Saad

      I have seen the performance tests, an I have noticed that when length gain against push, it has about twice op/s, but when push gain it is not more than 20%. ;-)

      Thanks

  • http://www.avronp.com/nsn/nsn_stringvb/vb.htm Avron Polakow

    (See: http://www.avronp.com/nsn/nsn_stringvb/rsrcs/js/foundations/js_string.js)
    In addition to Trim() check out all the vb functions (and more) both as:
    ******************************************************************************
    functions – Trim(mystring);
    methods – mystring.trim();
    eg:
    // .trim | Trim() | trims string on left and right
    // .ltrim | LTrim() | left trim string
    // .rtrim | Rtrim() | right trim string
    // .left | Left() | Returns left part of string
    // .right | Right() | Returns right part of string
    // .nolf | Nolf() | removes linefeeds (ASCII 10)
    // .nocr | Nocr() | removes carriage returns (ASCII 13)
    // .nocrlf | Nocrlf() | removes carriagereturns + linefeeds (ASCII 13+10)
    // .nolfcr | Nolfcr() | removes linefeeds + carriage returns (ASCII 10+13)
    // .nosp | Nosp() | removes spaces
    // .nosquotes | Nosquotes() | removes single quotes
    // .crbr | Crbr() | replaces carriage returns
    // .brcr | Brcr() | carriage returns replaces
    // .lpad | Lpad() | left pads a string with a fill string to a count
    // .rpad | Rpad() | right pads a string with a fill string to a count
    // .flat | Flat() | on each line removes leading and trailing spaces
    // .degremlin | Degremlin() | removes gremlins from a string
    // | | Default gremlins: Some Non alphanumerics
    // | | Optional: Parameter can contain list of gremlins
    // .upperhtml | Upperhtml() | Convert HTML tags to uppercase
    // .lowerhtml | Lowerhtml() | Convert HTML tags to lowercase
    // .htmlattribs | Htmlattribs()| FORMAT HTML tags (quotes/case) | see: details in function
    // .format | Format() | formats a string to a pattern | format can be expanded to include any formatting pattern required
    // .count | Count() | counts occurrences of a pattern in a string
    // .strreverse | Strreverse() | reverses a string
    // .isnumber | Isnumber() | checks to see if a string is a number
    // .isnotdigit | Notdigit() | checks to see if a string is not a digit

  • http://orbital.co.nz Johan

    Great list. Typo in #20 – description refers to split it should be splice as correctly shown in code example.

    • https://plus.google.com/104639715967304245815/posts Saad

      Thanks Johan :D, yes it was my mistake, we will fixe it ASAP

  • Sjeiti

    Where is requestAnimationFrame? (setInterval is bad practice)

    • https://plus.google.com/104639715967304245815/posts Saad

      As I said in the article introduction, I’m sharing tips that are related to the language, this method will not work for example in server side SSJS, It’s related to the browsers and not yet implemented by all browsers, http://caniuse.com/#feat=requestanimationframe

      • http://www.google.com SyntaxError

        On a related note, the JSON object didn’t exist before IE8. The few IE7 users left would need a polyfill.

    • http://themapps.com Kev

      who says setInterval() is bad practice? I had major issues (like not updating the screen for several seconds) with RAF on iOS (6 and 7) and had to abandon it. Of course, YMMV.

    • http://www.akademy.co.uk/me Matthew Wilcoxson

      While SetInterval may be bad practice, requestAnimationFrame should only be used when updating something visible on screen (i.e. animating) but not for general timing purposes.

      Use SetTimer repeatedly instead, as is done in #42 (although in that particular case perfect timer isn’t essential and setInterval could work!)

  • Christian

    Hi Saad.

    Great “little” compilation of tips & tricks.

    I’ve stumbled over a few minor typo’s etc. And I just saw some of my bullets below have been commented on while I wrote. Passing them on anyway :)

    #14 – Append an array to another array.
    Using push this way is actually limited by max number of arguments (less than 2^17 on Chrome).
    So for huge arrays this trick will throw an exception.

    #20 – Don’t use delete to remove an item from array
    A minor typo – “Use split instead of …” (split => splice)

    #22 – Use logical AND/ OR for conditions

    “The logical AND could …” => “The logical OR could …”

    Also the function has fallen victim to some automatic spell check… (Uppercase Function and uppercase ‘Arg1′)

    #26 – Check the properties of an object when using a for-in loop
    “if (object.hasOwnProperty(name))” is necessary only on objects being new’ed and if you want to disregard prototype properties.
    Object literals can safely be run though using for..in.

    #27 – Comma operator
    I agree with your note that developers should know how to use the comma operator.
    Actually, many use it in var lists and they should have explicit knowledge that there is no great difference between your example and the var list use.

    #30 – Avoid negative indexes in arrays
    “… passed to indexOf are …” => “… passed to splice are …”

    An interresting use of out-of-bounds indeces is: “for (var i=0; myArray[i]; ++i)” since element lookup outside the range will return “undefined” (of course, this require the array to contain no other falsy items :)

    #33 – Avoid using with() (The good part)
    A good example would be

    function f(object) {
    var x = 2;
    with (object)
    ++x;
    return x;
    }

    Calling f for any object not having a ‘x’ property will make f always return 3.
    Calling f({x:7}) (an object with property ‘x’ being numerical – or convertable to) will return 8.
    Calling f with any object having a non-numerical ‘x’ will return 2.
    Unless applied with care using “with” is best suited for code obfuscation – or job security :)

    #34 – Avoid using for-in loop for arrays
    Last line: “Why? The length of the array arrayNumbers is recalculated every time the loop iterates.”
    I doubt length is recalculated. However, the object property lookup will often be slower than local variable lookup.
    Having a sufficiently good optimizing interpreter no discernable difference should show.

    • https://plus.google.com/104639715967304245815/posts Saad

      Thanks Christian for the notes, many benchmarking tests were done in JsPerf to demonstrate those tips, and as you may know JavaScript implementation depends on (JavaScript Runtime Engines) : the browsers (client side), and also on the Server (SSJS :Server-Side JavaScript ) implementation, it’s why the results could be differents depending in the implementation, in the list, I have chosen the tips which overcome in the max of browsers and SSJS Server, I add also that many tips (#34,#26, #14, #38, #42 …etc. ) will have a native implementation in the latest JavaScript version ES6 and ES7 (work in progress)
      it’s not a Bible ;)

  • http://whatsthepointy.blogspot.com Mike McNally

    #12 is **not** a good way to shuffle an array. In fact it really has no well-defined behavior at all. Use a Fisher-Yates shuffle.

    • http://martinsmucker.com Michael Martin-Smucker

      Indeed, Array.prototype.sort isn’t the way to go. If anyone is interested in the reasoning (or if you want to see a good Javascript implementation of Fisher-Yates) check out the answers to this StackOverflow question: http://stackoverflow.com/a/962890/388639

  • Pingback: Web Development | Annotary

  • http://www.donburks.com Don Burks

    Typo in #14, you need a colon between name and “Joe” in: var array1 = [12 , "foo" , {name: "Joe"} , -2458];

    Otherwise, fantastic list.

  • http://vxtindia.com Debjeet

    #11 has a reference error

    • https://plus.google.com/104639715967304245815/posts Saad

      Yes, I have just seen it.

      Thanks Debjeet

  • Tamm Kwun

    Great article!

  • http://flippinawesome.org/2013/12/23/45-useful-javascript-tips-tricks-and-best-practices/#comment-10786 raj kimor

    Very useful list, thanks !

  • http://www.aamirafridi.com Aamir Afridi

    For 14, use concat
    var one = ["Cecilie", "Lone"];
    var two = ["Emil", "Tobias", "Linus"];
    var both = one.concat(two);

    • http://google.com dotnetCarpenter

      +1

    • http://flippinawesome.org/2013/12/23/45-useful-javascript-tips-tricks-and-best-practices/#comment-10786 raj kimor

      Hi Aamir, the tip is about appending and not concatenating, the concat() method could be a good option too

      thanks

  • http://github.com P

    Correction for #11:

    var rdmstring = “”;
    Should be
    var rdmString = “”; // because currently when you call rdmString later on, it will cause error due to being undefined

  • http://n/a shaun

    #43 is missing the colon in your conditional operator. Not sure if someone already pointed this out. Thanks for the article!!

    Also a good read on flippinawesome: http://flippinawesome.org/2013/11/25/fun-with-javascript-native-array-functions/

  • http://None Andrei
  • http://heythere.de Sebastian Otto

    Example 10 will not contain 0 in the numbersArray

  • Joel

    #10 Would return [1...99] instead of the indicated [0,1,2,3 ... 100]
    ————-
    var numbersArray = [] , max = 100;
    for( var i=1; numbersArray.push(i++) < max;); // numbers = [0,1,2,3 ... 100]

    • https://plus.google.com/104639715967304245815 Saad

      It returns [1,2,3 ... 100] and not to 99,

      it will be fixed ASAP

      Thanks

      • http://google.com Kir6

        Actually, this is a trick and not a good practice.
        Reading too fast, one would think it would return [1 ... 99] but it will return [1 ... 100] because the push method is an instruction that is irremediably evaluated, whatever the result of the conditional for-loop parameter is.
        100 is a value that is pushed in-extremis. After that, the test returns false, but it is already too late.
        You are not tricking the interpreter, but the reader. And that’s not good.
        The conditional segment should stay as clear as possible of any misinterpretation.

        I like your blog article. But it lacks of reminders about “good tricks versus good practices”.

        In good practice, devs should avoid the ternary operator as often as possible. They are good practice in limited use at the beginning of methods to set local variables and such. Not in the core implementations. And should not be used to branch code logic. Use the good old if (){} else {}. And choose to prefer not go against JSLint advices.

        If you really need other devs to be unable to read you, or to read you correctly, use an obfuscator !
        Ternary branching are also hard to debug with breakpoints. That’s a minor point.

        A[A.length] = v; // is not a good practice either. But it depends entirely of your scope structure or your browser or your real array end. Some would prefer stacking objects anyway. And not caring about the indices. Never assume your array would never be trimmed down or spliced. You may one day be surprised your array length is shorter than expected.

        Keep up the good work in compiling those tricks anyway. They make good cheat sheets though.

  • Pingback: 45 Useful JavaScript Tips, Tricks and Best Practices

  • Robin

    Technically, #24 returns “2.4432″, it is a string, not a number. So if you were to add another number to n after the toFixed, it would simply add it to the end as in string concatenation.

    var n = 2.414233;
    n = n.toFixed(4);
    console.log(typeof n); // string

  • Ankit Garg

    Nice article man !! Thanks.

  • Bill

    What happened to tip #3?

    • remotesynth

      Nice catch. My fault. Fixed.

  • http://www.wpguru.com.au/web-development-sydney/ Robin

    Nice article. Flipping Awesome.

  • http://codemeek.blogspot.com/ Kevin

    Crockford’s “The Good Parts” recommends against using the new operator in tip #5 (under the “Bad Parts” – “new” and “The Constructor Invocation Pattern” sections) and also against the ++ increment operator in tip #34 (under the “Bad Parts” – “++” section). Stefanov’s “JavaScript Patterns” book suggests using the += increment operator instead of ++ (e.g., i += 1 instead of i++) in the “Essentials – for Loops” section. “The Good Parts” gives several recommended alternates to the new operator in “Chapter 5. Inheritance”. Thanks for all of the tips, it’s always nice to review articles like this for reinforcement and finding new gems!

  • http://www.google.com JasonHuang

    nice article ! but with some typo witch will easily mislead new fish … like the sugguestion for remove a item from a array with slice or delete . typoed the slice to splite ….

  • Swapneel

    These are very handy tips. Thanks for sharing!

  • http://stackoverflow.com/users/469491/brennanyoung Brennan Young

    #4 – Not very persuasive about semicolons. It’s “good practice” yes, but why? Well, it will bite you if you write a return value on the next line after the keyword return, such as

    function greeting () {
    return
    “hello world”
    }

    This function will actually return undefined because a semicolon will get inserted after return. AFAIK this is the main reason for enforcing the semicolon rule, although the more effective rule would be “begin your return value on the same line as the keyword return”. If people only did that, they could be as sloppy as they liked with semicolons.

    Your advice to use jslint is admirable. I wish you had used it on your own examples! e.g. you didn’t use the single var pattern in the longer snippets, and it really can be a source of errors to declare vars anywhere but at the top of the function because of hoisting etc. I am sure you know this, as will many readers.

    Otherwise, thanks for a good article. Some useful tricks.

  • Konrad Dzwinel

    Bugfixes/Improvements:
    - It’s hard (and silly) to remember the tip without understanding why it’s important, please add missing explanations.
    - syntax highlighting!
    - #6 – this is a good example of a tip that misses proper explanation
    - #7 `})(10,20)` – missing semicolon (see point #4)
    - #13 extending build-in objects is controversial
    - #14 `{name “Joe”}` -> `{name “Joe”}`
    - #16 linking to the author of this code would be nice ( http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric )
    - #19 and #21 are the same thing
    - #22 `Function doSomething(arg1){ ` -> `function doSomething(arg1){ `, `Arg1 = arg1 || 10;` -> `arg1 = arg1 || 10;`
    - #22 It’s worth mentioning that last example is not entirely true. If arg1 will be set to e.g. 0 or false it will be replaced with default value.
    - #27 interesting, but not useful
    - #30 “Make sure that the arguments passed to indexOf are not negative.” -> “Make sure that the arguments passed to splice are not negative.”? I’m not 100% sure what you meant here.
    - #34 “The length of the array arrayNumbers is recalculated every time the loop iterates.” – it’s no longer true for modern JS engines
    - #35 `setTimeOut` -> `setTimeout`
    - #36 “Avoid using it when you have more than 10 cases.” – why?
    - #39 link to the source: https://gist.github.com/leommoore/4710081/
    - #41 “synchronous Ajax” -> “synchronous XHR”. A in Ajax stands for “asynchronous”.
    - #42 `var min = a `var min = a < b ? a : b; `
    - #45 this resource is locked and outdated (it's from 2011)

    • https://plus.google.com/104639715967304245815 Saad

      Thanks Konrad for this good review, As I said the list is open to the readers suggestions and improvments, I’ll check this list and others, after that update the article ;).

      For #45, have you could share a list of good resources if you have !

  • John

    Re: 13 – A String Trim Function: JavaScript does have a string trim function: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim

  • Pingback: Tweet Parade (no.01 Jan 2014) - Best Articles of Last Week | gonzoblog

  • http://dropjs.com Christian

    You wrote «slice» instead of «splice». Also JS does have a ‘trim’ function, check out this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim

    - otherwise this is a great write-up!

  • Bernard

    #22 in the first example doSomething() always return something, so in the first case the variable will take the returned value, even undefined. In the case from comments it won’t.

    Nice article. You wrote you didnt want explanations. They or links for live examples or external explanations would be useful.

    Regards

  • http://google.com dotnetCarpenter

    #10 should be:
    var max = 100, numbersArray = new Array(max); // faster
    for( var i=1; numbersArray.push(i++) < max;); // numbers = [0,1,2,3 ... 100]

    If you use jQuery you could do:
    var numbersArray = jQuery.map(new Array(100), function(el, i) { return i; }); // numbers = [0,1,2,3 ... 100]

    I know for a fact, that the D3 library has changes all its Array initialization to use use new Array([array length]) solely for performance reasons.

    • http://flippinawesome.org/2013/12/23/45-useful-javascript-tips-tricks-and-best-practices/#comment-10786 raj kimor

      This code :
      var max = 100, numbersArray = new Array(max); // faster

      will create an array of 100 undefined items, As I said in the top, the tips are not related to any frameworks (JQuery, D3 …etc), only native JavaScript code ;)

      Thanks for sharing

      • https://plus.google.com/+saadMousliki Saad

        Thanks dotnetCarpenter, I’ll update the comment the created array strats from 1 to 100, and not from 0.

  • http://google.com dotnetCarpenter

    #19 If the array contain references to DOM nodes or titanium proxy objects you’ll get a memory leak in older IE and Appcelerator.
    Instead you have to explicitly null the references before emptying the array.
    var myArray = [12 , objReference, 1000 ];
    myArray.forEach(explNull); // forEach is part of ecmaScript5
    myArray.length = 0; // myArray will be equal to [].
    function explNull(item) {
    item = null; // reference is freed for the garbage collector
    }
    In ecmaScript3 (IE8 and before) you can polyfil it with:
    if(!Array.prototype.forEach) {
    Array.prototype. forEach = function forEach(fn, context) { // named functions are easier to debug
    for(var i = 0, len = this.length; i < len; ++i)
    fn.call(context, this[i], i, this);
    };
    }

  • http://google.com dotnetCarpenter

    #43 has a typo. “var min = a < b ? a b;" should be "var min = a < b ? a : b;"

    Nice list. I didn't know about the trick in #37. Very nice

  • Pingback: 45 Useful JavaScript Tips, Tricks and Best Practices | CompkSoft

  • http://codysc.weebly.com Cody

    var z = 1; // ONE
    function fn(x, y){ console.log(‘@args:’, x, y, z); return x + y + z; }

    fn(( z && (z++, 4) ), 6); // returns 12

    var z = 0; // ZERO
    function fn(x, y){ console.log(‘@args:’, x, y, z); return x + y + z; }

    fn(( z && (z++, 4) ), 6); // returns 6

    Kinda neat-o!

  • https://plus.google.com/104639715967304245815 Saad

    Cody, Thanks for this snippet :)

  • http://yawboakye.com Yaw

    Tip #14 looks good but array1.concat(array2) is the natural way of joining 2 arrays into one in JavaScript

  • http://yawboakye.com Yaw

    Tip #16

    A little tricky, silly implementation I learnt from Lea Verou

    function isNumber(n) {
    return n === +n;
    }

  • Grégoire

    29 – isFinite(und*i*fined); // false

  • Pingback: Monday Trends – Links Digest 6/1/14 | Monday Trends

  • Pingback: Miscellaneous | Annotary

  • http://themapps.com Kev

    23 – map() should never be an automatic choice for looping over an array. Function call overhead on every iteration. Only use map() if you don’t care about performance.

  • http://www.sansys.net SanSYS

    36 – Use a switch/case statement instead of a series of if/else

    please see test http://jsperf.com/if-vs-switch-statement
    switch more slow than if statement

  • http://www.sansys.net SanSYS

    43 – Keep in mind that primitive operations can be faster than function calls. Use VanillaJS.

    Keep in mind that examples should be tested http://jsperf.com/vanilla-vs-math-min/2 =)

  • https://plus.google.com/+saadMousliki Saad

    Thanks I’ll check the given jsperf tests ;)

  • justin

    Great reference for when you need something quick. Thanks for putting it together.

    One typo… You’re missing a : on…
    var min = a < b ? a : b;
    A[A.length] = v;

  • http://www.basslagter.com Bas Slagter

    In tip 34 ‘ Avoid using for-in loop for arrays’ you state that one should use a for loop instead of a for-in loop.
    Of course this is true and your exampled alternative is indeed a lot better. But how about this one:

    for(var i=myArray.length; i–;){
    // Do something under the awareness that we are looping back.
    }

    This actually is an even faster way to loop through the array since we do not have to check the value of i against the length of the array. This is because i will become 0 (falsy) at one point and the loop will end. Maybe it’s a minor performance gain but i like it.

    • http://www.sansys.net/ SanSYS

      What do you think about this method?

      for (var i = myArray.length, item; item = myArray[--i];){
      // do something with item
      }

      Notice: array should not contain values interpreted like false (empty string, undefined, zero…)

  • Pingback: Interesting Web Dev Things 13 Jan 2014 | Joseph Khaw

  • http://www.no.com mm

    can you say the reason about 37 ?

  • Pingback: JavaScript best practices, SVGs, typography | The Treehouse Show Episode 74 - Treehouse Blog

  • Pingback: JavaScript best practices, SVGs, typography | The Treehouse Show Episode 74 | Html5 Tutorials

  • http://blog.maheshj.info MJ

    In 42, you have used `cancelTimeout,` which is not a JS function AFAIK. What you probably want is `clearTimeout`

    • http://flippinawesome.org/authors/saad-mousliki/ Saad

      Thanks, I just see it, It was my mastake, it’ll be updated ASAP ;)

  • Pingback: Ape Boy Studio | JavaScript best practices, SVGs, typography | The Treehouse Show Episode 74

  • http://site.org Stan88

    It’s awesome man!! Thanks for article!

  • http://google.com Kir6

    #3 I would add an exemple.
    This is good practice to not be lazy and to write for example: “if ( val === null) {}” instead of “if ( !val ) {}”.
    As you stated: undefined, 0, “”, null, NaN and false, are false.
    But you don’t want to know if this is false, in that case, you would want to know why, or specifically what is.
    Is this because this is binary false, because it’s null or undefined ?
    So write it.

    Of course, “if ( !val ){}” stays valid and can be used if you know what your are doing.

  • http://www.ajraksoft.com Nadeem Jamali

    Very nice….

  • http://www.paitadesign.com/blog Giacomo Paita

    Hi! I found this article really useful! Can i translate it, mentionioning the source and the actual author, and put it in my blog? http://www.paitadesign.com/blog ? Thanks!

    • https://plus.google.com/104639715967304245815 Saad

      Hi Giacomo,
      Ok, I hope that it could be helpful for people who doesn’t understand english ;)

      • http://www.paitadesign.com/blog Giacomo Paita

        Thanks! As soon as i can i will start, once i end the post i will notify you.

  • http://argutech.blogspot.in kumar

    very useful list.

    Thanks.

  • Yogeesh R

    Good Tips & Tricks. Waiting for some more . . .

  • http://zinoui.com Dimitar Ivanov
Top