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 MARKDOWN_HASHb2145aac704ce76dbe1ac7adac535b23MARKDOWN_HASH
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 MARKDOWN_HASH7ce4f5cca0e937c88b050a8bba83218eMARKDOWN_HASH
instead of MARKDOWN_HASH2063849717d32dd19e534b77cabac517MARKDOWN_HASH
MARKDOWN_HASH2063849717d32dd19e534b77cabac517MARKDOWN_HASH
(or MARKDOWN_HASHde0219f9333d57ea89a9ba235df098baMARKDOWN_HASH
) operator performs an automatic type conversion if needed. The MARKDOWN_HASH7ce4f5cca0e937c88b050a8bba83218eMARKDOWN_HASH
(or MARKDOWN_HASH9656440b434e7b538e45e09079b0604cMARKDOWN_HASH
) operator will not perform any conversion. It compares the value and the type, which could be considered faster than MARKDOWN_HASH2063849717d32dd19e534b77cabac517MARKDOWN_HASH
.
1 2 3 4 5 6 7 8 9 10 |
[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 |
MARKDOWN_HASH5e543256c480ac577d30f76f9120eb74MARKDOWN_HASH
, MARKDOWN_HASH37a6259cc0c1dae299a7866489dff0bdMARKDOWN_HASH
, 0, MARKDOWN_HASH68934a3e9455fa72420237eb05902327MARKDOWN_HASH
, MARKDOWN_HASH7ecfb3bf076a6a9635f975fe96ac97fdMARKDOWN_HASH
, MARKDOWN_HASHe6fda0f0d3e0adfff69e334462d1ef6aMARKDOWN_HASH
(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: https://davidwalsh.name/javascript-semicolons.
5 – Create an object constructor
1 2 3 4 5 6 7 8 |
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.
1 2 3 4 5 6 7 |
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:
1 2 3 4 5 6 7 8 9 |
(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
1 2 3 4 5 |
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.
1 2 3 |
var x = Math.floor(Math.random() * (max - min + 1)) + min; |
10 – Generate an array of numbers with numbers from 0 to max
1 2 3 4 5 |
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
1 2 3 4 5 6 7 8 9 |
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
1 2 3 4 5 |
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.
1 2 3 |
String.prototype.trim = function(){return this.replace(/^s+[/fusion_text][fusion_button link="/courses" target="_self" hide_on_mobile="small-visibility,medium-visibility,large-visibility" color="custom" size="large" stretch="default" shape="round" icon_position="left" icon_divider="no" animation_direction="left" animation_speed="0.3"]Explore Web Development Training Courses[/fusion_button][/fusion_builder_column][/fusion_builder_row][/fusion_builder_container][fusion_builder_container hundred_percent="no" equal_height_columns="no" hide_on_mobile="small-visibility,medium-visibility,large-visibility" background_position="center center" background_repeat="no-repeat" fade="no" background_parallax="none" parallax_speed="0.3" video_aspect_ratio="16:9" video_loop="yes" video_mute="yes" overlay_opacity="0.5" border_style="solid"][fusion_builder_row][fusion_builder_column type="1_1" layout="1_1" background_position="left top" background_color="" border_size="" border_color="" border_style="solid" border_position="all" spacing="yes" background_image="" background_repeat="no-repeat" padding="" margin_top="0px" margin_bottom="0px" class="" id="" animation_type="" animation_speed="0.3" animation_direction="left" hide_on_mobile="small-visibility,medium-visibility,large-visibility" center_content="no" last="no" min_height="" hover_type="none" link=""][fusion_text]s+$/g, "");}; |
A native implementation of the trim() function is available in the recent JavaScript engines.
14 – Append an array to another array
1 2 3 4 5 6 7 |
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
1 2 3 |
var argArray = Array.prototype.slice.call(arguments); |
16 – Verify that a given argument is a number
1 2 3 4 5 |
function isNumber(n){ return !isNaN(parseFloat(n)) && isFinite(n); } |
17 – Verify that a given argument is an array
1 2 3 4 5 |
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…
1 2 3 |
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.
1 2 3 4 5 6 7 8 9 10 11 |
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
1 2 3 4 5 |
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
1 2 3 4 |
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…
1 2 3 4 5 6 7 |
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…
1 2 3 4 5 6 7 |
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.
1 2 3 4 |
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.
1 2 3 4 |
myArray.length = 10; // the new array length is 10 myArray[myArray.length - 1] ; // undefined |
22 – Use logical AND/ OR for conditions
<
pre> The logical OR could also be used to set a default value for function argument.
23 – Use the map() function method to loop through an array’s items
24 – Rounding number to N decimal place
NOTE : the 25 – Floating point problems
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 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.
27 – Comma operator
28 – Cache variables that need calculation or querying In the case of a jQuery selector, we could cache the DOM element.
29 – Verify the argument before passing it to
30 – Avoid negative indexes in arrays
Make sure that the arguments passed to 31 – Serialization and deserialization (working with JSON)
32 – Avoid the use of Use of
33 – Avoid using Using 34 – Avoid using for-in loop for arrays Instead of using…
…it’s better to use…
As a bonus, the instantiation of
Why? The length of the array NOTE : the issue of recalculating the length in each iteration was fixed in the latest JavaScript engines. 35 – Pass functions, not strings, to If you pass a string into
…use…
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.
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…
39 – An HTML escaper function
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…
…use…
41 – Set timeouts to You could abort the connection if an XHR takes a long time (for example, due to a network issue), by using
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
The var foo = 10;
foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething();
foo == 5[/fusion_text][/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]
MARKDOWN_HASH56324f72d2cb5809172c8e0a13d33768MARKDOWN_HASH
function returns a string and not a number.
MARKDOWN_HASH56324f72d2cb5809172c8e0a13d33768MARKDOWN_HASH
and MARKDOWN_HASH845fbb3604f9f7c9c63533b7159c264fMARKDOWN_HASH
to resolve this problem.
MARKDOWN_HASH9854daf0525685e4b5ba5d82d95af3e4MARKDOWN_HASH
MARKDOWN_HASH87ee0cd6d5160033e8b4fd72aaefc230MARKDOWN_HASH
are not negative.
MARKDOWN_HASH66828ac336e1ead0ace442ca9ddd2c5cMARKDOWN_HASH
or the MARKDOWN_HASH86408593c34af77fdd90df932f8b5261MARKDOWN_HASH
constructorMARKDOWN_HASH2eed1fe0db36d674643b5f84d2adf46eMARKDOWN_HASH
or the MARKDOWN_HASH86408593c34af77fdd90df932f8b5261MARKDOWN_HASH
constructor are expensive operations as each time they are called script engine must convert source code to executable code.
MARKDOWN_HASH51f7c454d5d5df69796c04217c48c0f4MARKDOWN_HASH
(The good part)MARKDOWN_HASH51f7c454d5d5df69796c04217c48c0f4MARKDOWN_HASH
inserts a variable at the global scope. Thus, if another variable has the same name it could cause confusion and overwrite the value.
MARKDOWN_HASH865c0c0b4ab0e063e5caa3387c1a8741MARKDOWN_HASH
and MARKDOWN_HASHf5a8e923f8cd24b56b3bab32358cc58aMARKDOWN_HASH
is executed once because it’s in the first statement of the for loop. Thsi is faster than using…
MARKDOWN_HASH42b7edf34760b439ad3f09a9833537b6MARKDOWN_HASH
is recalculated every time the loop iterates.MARKDOWN_HASHf7639575910feccc742abed10e36dfcfMARKDOWN_HASH
and MARKDOWN_HASH94a6942556b929d14d84585eca782de2MARKDOWN_HASH
MARKDOWN_HASHf7639575910feccc742abed10e36dfcfMARKDOWN_HASH
or MARKDOWN_HASH94a6942556b929d14d84585eca782de2MARKDOWN_HASH
, the string will be evaluated the same way as with MARKDOWN_HASH2eed1fe0db36d674643b5f84d2adf46eMARKDOWN_HASH
, which is slow. Instead of using…
MARKDOWN_HASH8969227dffc3d8d2bf4adfcfe4e0c50fMARKDOWN_HASH
MARKDOWN_HASHf7639575910feccc742abed10e36dfcfMARKDOWN_HASH
with the XHR call.
MARKDOWN_HASHcafad4e260a92a1fc04605c64395acc3MARKDOWN_HASH
…
MARKDOWN_HASH95d9c873ba1a06f63441a6f74f247a32MARKDOWN_HASH
function should be added at the end of the MARKDOWN_HASH26529d202ec7c6fd069689c6d1bb9a8fMARKDOWN_HASH
method of the webSocket connection and the MARKDOWN_HASH1fcde5476a9882f65006b8ab7917cd99MARKDOWN_HASH
at the end of the MARKDOWN_HASH6c186b609e97313765f61448f5e04e5cMARKDOWN_HASH
method.
43 – Keep in mind that primitive operations can be faster than function calls. Use VanillaJS.
For example, instead of using…
1 2 3 4 |
var min = Math.min(a,b); A.push(v); |
…use…
1 2 3 4 |
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
- Code Academy JavaScript tracks: https://www.codecademy.com/tracks/javascript
- Eloquent JavaScript by Marjin Haverbeke: https://eloquentjavascript.net/
- Advanced JavaScript by John Resig: https://ejohn.org/apps/learn/
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:
- JavaScript Performance Best Practices (CC)
- Google Code JavaScript tips
- StackOverFlow tips and tricks
- TimeOut for XHR
[/emaillocker-bulk-1]