JavaScript Best Practices

JavaScript is not only amazing language but also very tricky language. To make correct use of it, you need to follow some best practices to avoid any problems that might come about otherwise. I share some of the best practices you really should be following when writing JavaScript code. Of course this is not an exhaustive list but at the most fundamental level, every programmer should know and adhere to it.

1 -NEVER FORGET VAR KEYWORD

Most of the developers know about this but yet I wanted to mention this because it may not be clear to some or newbies or people having other programming language background that come to JavaScript.

Consider the following piece of code:

function myFunc(){
var firstName = 'sarfraz';
lastName = 'ahmed';
}

It should be noted that in JS, variables have function-level scope which means a variable declared inside a function can not be accessed outside of it. So let’s test above two variables:

myFunc();
console.log(lastName); // ahmed
console.log(firstName); // undefined

As you will notice, we are still able to access lastName variable. The reason is that it does not have function-level scope because we forgot to put var keyword before it unlike firstName variable. Hence, lastName variable went into global scope and became part of window (while inside browser) object eg window.lastName will output the last name too.

It is therefore always required to put var keyword before variables so that they do not become part of global scope. It has following benefits:

  • You save the memory and improve performance
  • You don’t pollute the global scope
  • You mistakenly don’t overwrite a global variable that might have the same variable name

This is a very important concept and JS developers have always been finding solutions to avoid this problem. One of the most popular solution is Singleton or Module Pattern you should check out. By the way, if you want to see other patterns also, take a look at:

Essential JavaScript Design Patterns For Beginners

2 – DECLARE VARIABLES ON TOP

Another thing that should be followed is that variables should be declared on top of each function because of what is known as JavaScript Hoisting. Here is an example:

var name = 'sarfraz';

(function(){
console.log(name); // undefined
     var name = 'nawaz';
     console.log(name); // nawaz
})();

Notice that even though name variable is outside the scope of function but on the very fist line it gives back undefined rather than actual name. The reason for this is that interpreter hoists or moves variables on top of the function, here is how interpreter sees or re-arranges it:

var name = 'sarfraz';

(function(){
     var name;
     console.log(name); // undefined
     name = 'nawaz';
     console.log(name); // nawaz
})();

As can be seen, name variable has been hoisted to top and declared there and also var keyword has been stripped from it where we assigned the value of ‘nawaz‘.

The same is issue is not only with variables but also function declarations but NOT with function expressions. You can learn more about the difference between function declaration and function expression here:

Named Functions Demystified

The solution to this problem is to always declare variables and function declarations on top of container function:

function myFunc(){
     var foo;
     var bar;
     var baz;

     // do something foo, bar, baz
}

The preferred and recommended syntax though that you must follow is to declare all variables in one go by separating them with a comma:

function myFunc(){
     var foo, bar, baz;

     // do something foo, bar, baz
}

3 – INITIALIZING MULTIPLE VARIABLES

Declaring variables on top is good practice but not multiple initialization. Consider:

function myFunc(){
var lang = encoding = 'en';
}

This is a very common mistake even amongst experienced JS developers where they think they have quickly assigned two variables same scope and same value. Though value for both lang and encoding variable is some but not the scope. Try it out:

myFunc();
console.log(encoding); // en
console.log(lang); // undefined

Here again, variable encoding has gone into global scope. Since var keyword is only appears before lang variable, that is the one which gets correct functional scope. In short, you should avoid that shorthand initialization unfortunately.

4 – STARTING CURLY BRACE ON THE SAME LINE

Consider the following code block where starting curly brace “{” is on a new line, this works fine in most situations.

function myFunc()
{
// some code
}

However, same convention will not yield expected results if you happen to write:

function myFunc()
{
     return
     {
         name: 'sarfraz'
     };
}

var f = myFunc();
console.log(f);

The result will be undefined because behind the scenes, interpreter puts a semicolon ‘;‘ after the return keyword making it:

function myFunc()
{
     return; // <----------------
     {
         name: 'sarfraz'
     };
}

To remedy such hard-to-debug issues, it is good practice to always put starting curly brace on the same line, this would work fine though:

function myFunc() {
     return {
         name: 'sarfraz'
     };
}

var f = myFunc();
console.log(f.name); // sarfraz

And that’s a reason why Douglas Crockford in his book “JavaScript: The Good Parts“, advocates this syntax for JS:

function () {
     // some code
}

if (expression) {
     // do something
}

Go ahead and check out JavaScript Coding Style to learn more as well as naming conventions.

Notice that it is not the return keyword affected by automatic semi-colon insertion but all these too:

  • var statement
  • empty statement
  • expression statement
  • do-while statement
  • continue statement
  • break statement
  • throw statement

Experienced JavaScript developers know pretty well about JavaScript’s automatic semi-colon insertion problem and avoid it. The benefit of above coding style however is that you avoid this problem without knowing that this problem exists just by following that coding style.

5 – USE ARRAY LITERAL INSTEAD OF NEW ARRAY()

There are two ways you can create arrays in JS:

var arr1 = new Array(); // array constructor
var arr2 = []; // array literal

Though both serve the purpose of creating arrays but there is important difference between the two.

In JS, even an array is an object. With first constructor method above, you are telling interpreter to call constructor of the Array and generate an object. The interpreter looks up into the execution context to find the constructor and once found, it calls it and creates the Array object. It seems that it has performance hit too as compared to latter array literal method. With the array literal method, interpreter just creates the array on run-time with no extra processing done.

Other than that, Array constructor is mis-guiding the way it handles its parameters. Consider:

console.log(new Array(5)); // [,,,,]
console.log(new Array('5')); // ["5"]

When one argument is passed to Array and that happens to be a number, a new array is returned with its length property equal to that number passed. The important thing to note here is that Array will be initialized from what number you specified to it, for example:

// Array constructor
var arr = new Array(2);
console.log(arr.length); // 2
console.log(arr[0]); // undefined

// Array literal
var arr = [2];
console.log(arr.length); // 1
console.log(arr[0]); // 2

So the conclusion is to always use array literal notation rather than Array constructor.

6 – USE PROTOTYPE TO SHARE ACROSS

The concept of prototypes or prototypal inheritance is rather confusing. I have seen people especially inexperienced JS developers adding class members to parent function which needs to be shared across child classes. Consider the following code:

function Person(name){
this.name = name;
}

Now let’s assume we want to have child classes the ability to display the names some how, one of doing it is putting method directly inside Person class:

function Person(name){
     this.name = name;

     this.display = function(){
         alert(this.name);
     }
}

Other way is to use prototype:

function Person(name){
     this.name = name;
}

Person.prototype.display = function(){
     alert(this.name);
}

With both ways, all child classes will be able to use the display method but there is important difference between the two. When you attach any methods or properties via this (first way above) to a class then all instances of inheriting child classes will also have these properties or methods within them or their signature. On the other hand, when you use prototype to add members (properties and methods) to parent class, children classes will still inherit all members but it won’t be present inside their own functionality or signature, rather they will be borrowing that functionality from their parent class thereby saving memory. For this reason, later approach seems good to follow in most situations.

7 – PUT COMMA BEFORE PROPERTIES

When working with objects or arrays, it is always a good idea to put a comma before the variable or object property eg:

// jQuery - create a new div with some css
$('</pre></pre></pre>
<div>').attr({</div>
<pre>
<pre>
<pre>
 "id" : "myId"
 , "class" : "myClass"
 , "class" : "myClass"
 , "color" : "green"
 , "fontWeight" : "bold"
});

In this way, we never add an extra comma or forget one from the last property. The reason why this is good practice is that, in IE, with extra comma at the last property, we do not get expected results sometimes (ExtJS developers must have learned this). I do the same with multiple variable declarations or arguments of function. It also makes the code look pretty too as far as I see it.

8 – DON’T MIX JS AND HTML

One of the most important best practices is to always separate JS code from HTML and go unobtrusive. One would often see code like this:

<a href="#" onclick="doSomething()">Some Action</a>
<input type="button" onclick="doSomething()" value="Do Something" />
<form onsubmit="doSomething();">...

That’s a very bad practice in that it is hard to manage and maintain. HTML and JS should not be mixed ever. You could do the same thing like this:

<a href="#" id="link">Some Action</a>
<input type="button" id="button" value="Do Something" />
<form id="frm">...

<script type="text/javascript">
var link = document.getElementById('link'),
 btn = document.getElementById('button'),
 frm = document.getElementById('link');

link.onclick = function(){
 // do something
};

btn.onclick = function(){
 // do something
};

frm.onsubmit = function(){
 // validate form
};

</script>

This way it becomes easy to manage, maintain or enhance both HTML and JavaScript.

9 – PUT SCRIPTS AT BOTTOM

Normally scripts are put in <head></head> tags but this should be avoided. The reason for this is that browser loads your scripts sequentially and by the time they are loading, nothing else is done and website load times slow down (or at least that’s how visitors will perceive it) and you see actual output only after those scripts have been loaded by the browser.

The best practice is that scripts should be put on bottom of page just before closing body tag eg </body>. This way browser will instantly display page and page load time will be better for users who view that page.

By the way, always put CSS on top in <head></head> tags because that’s something browser reads first and renders page’s layout accordingly.

Read more about this at famous Yahoo’s performance article.

I would also suggest you to use Yahoo’s YSlow or Google’s PageSpeed add-on (add-ons of Firebug) which suggest you a lot of things on how to improve the performance of the page.

10 – NEVER FORGET SEMI-COLON

Always end statements and function expressions with a semi-colon:

var name = 'some name'; // <-------------

var myFunc = function(){
// some doe

}; // <------------

This is useful when you want to compress the code (for faster load times). If at any place, semi-colon isn’t present, you won’t be able to compress the code or wouldn’t get expected results most likely code-wise. You should always, always use semi-colons.

BONUS

The good news is that you can solve most of above problems by using JSHint or JSLint code quality tool. It will tell you about best-practices and any errors that might exist in your code. Having said that, it is good to improve your JS skills and avoid the need to go to such tools.

Handy PHP Tips & Tricks

I have written some handy php tips and tricks right into a php file that puts them to use. You will learn some of the hidden tricks and pitfalls. Of course you would come to this file again and again unless you remember everything it contains. So here is the code with explanation:

$newline = "\n___________________________________________\n\n";
$br = "\n";

////////////////////////////////////////////////////////////
$name = 'Sarfraz';

// variable recognition in single and double quotes
print 'hello $name\n'.$br;
print "hello $name$br";

// reading string varibale as array / extracting text
print $name[3];
print $newline;
////////////////////////////////////////////////////////////

// heredoc: useful way of representing string vars. It can be handy
// in echoing out the html code or related text.
// PHP Comments inside heredocs are not applicable

$url = '/deal.php';
$text = 'Deal More Cards';
$remaining_cards = 5;

print <<< HTML
There are <b>$remaining_cards</b> cards left.

<a href="$url">$text</a>
HTML;
echo $br;

// second example
$a = <<< END
Once upon a time, there was a
END
. ' boy!';
print $a.$br;

// third example

print <<< END
Right now, the time is
END
. strftime('%c') . <<< END
 but tomorrow it will be
END
. strftime('%c',time() + 86400);
print $newline;
////////////////////////////////////////////////////////////

// read chars from backward using negatvie start value
print substr('watch out for that tree',-6);

print $newline;
////////////////////////////////////////////////////////////

$message = <<< TEXT
The function substr_replace is useful when you've got text that's too big to display all at once, and you want to display some of the text with a link to the rest. For example, this displays the first
25 characters of a message with an ellipsis after it as a link to a page that displays more text
TEXT;

printf('<a href="more-text.php?id=%d">%s</a>',
       1, substr_replace($message,' ...',25));
print $newline;
////////////////////////////////////////////////////////////

// counts vowels in a given string using strstr
$string = "This weekend, I'm going shopping for a pet chicken.";
$vowels = 0;
for ($i = 0, $j = strlen($string); $i < $j; $i++) {
    if (strstr('aeiouAEIOU',$string[$i])) {
        $vowels++;
    }
}
print "Number of vowels are: $vowels";
print $newline;
////////////////////////////////////////////////////////////

//To reverse by words, explode the string by word boundary,
// reverse the words, then rejoin:

$s = "Once upon a time there was a turtle.";
$words = explode(' ',$s);
$words = array_reverse($words);
$s = join(' ',$words);
print $s.$br;
print $newline;
////////////////////////////////////////////////////////////

/*
The trim functions can also remove user-specified characters
from strings. Pass the characters you want to remove as a second argument. You can indicate a range of characters with two dots between the first and last characters in the range.
*/
// Remove numerals and space from the beginning of the line
print ltrim('10 means ten',' 0..9').$br;
// Remove semicolon from the end of the line
print rtrim('SELECT * FROM turtles;',';');
print $newline;
////////////////////////////////////////////////////////////

//Use split( ) or preg_split( ) if you need a POSIX or Perl regular //expression to describe the separator:
// regexp plus means one or more chars
$words = split(' +','This sentence  has  some extra whitespace  in it.');

foreach($words as $value)
{
    print $value . " ";
}
echo $br;
print_r($words);
print $newline;
////////////////////////////////////////////////////////////

/*
Helpfully, is_numeric properly parses decimal numbers, such as 5.1; however, numbers with thousands separators, such as 5,100, cause is_numeric( ) to return false.

To strip the thousands separators from your number before calling is_numeric( ) use str_replace( ):
*/
$number = "5,100";
print is_numeric(str_replace($number, ',', ''));
print $newline;
////////////////////////////////////////////////////////////

// ==========================================
// Variable variables (IMPORTANT)
// ==========================================

/*
You want to construct a variable's name dynamically. For example, you want to use variable names that match the field names from a database query.
*/
$animal = 'turtles';
$turtles = 103;
print $$animal.$br.$br;

/*
The previous example prints 103. Because $animal = 'turtles', $$animal is $turtles,
which equals 103.

Using curly braces, you can construct more complicated expressions that indicate variable names:
*/

$stooges = array('Moe','Larry','Curly');
$stooge_moe = 'Moses Horwitz';
$stooge_larry = 'Louis Feinberg';
$stooge_curly = 'Jerome Horwitz';

foreach ($stooges as $s) {
  print "$s's real name was ${'stooge_'.strtolower($s)}.\n";
}
print $newline;
////////////////////////////////////////////////////////////

// This is how to capture page data before showing it to the user's browser:

$user = "Sarfraz";

ob_start();
var_dump($user);
$dump = ob_get_contents();
ob_end_clean();
print $dump;

print $newline;
////////////////////////////////////////////////////////////

// StrPos Usage Warning

/*
strpos() returns the location of the first substring within a string. If the
substring isn't found, strpos( ) returns false. If it is found, it returns an integer with the position. Therefore, to find a substring position, you might write:
if (strpos($string, $substring)) { found it! }

However, if $substring is found at the exact start of $string, the value returned is 0.
Unfortunately, inside the if, this evaluates to false, so the conditional is not executed.

Here's the correct way to handle the return value of strpos( ):
*/

if (false !== strpos("hello there", "hello")) { print "found"; }

print $newline;
////////////////////////////////////////////////////////////

// open the index.php in main window / frame.
header('Window-target: main');
header('Location: index.php');

////////////////////////////////////////////////////////////

/*
You want to force output to be sent to the browser. For example, before doing a slow database query, you want to give the user a status update.

The flush() function sends all output that PHP has internally buffered to the web server, but the web server may have internal buffering of its own that delays when
the data reaches the browser. Additionally, some browsers don't display data immediately upon receiving it, and some versions of Internet Explorer don't display a page until they've received at least 256 bytes. To force IE to display content, print blank
spaces at the beginning of the page:
*/

print str_repeat(' ',300);
print 'Finding identical snowflakes...';
flush();
$sth = $dbh->query('SELECT shape,COUNT(*) AS c FROM snowflakes');
////////////////////////////////////////////////////////////
/*
You want to start generating output before you're finished sending headers or cookies.

Call ob_start at the top of your page and ob_end_flush( ) at the bottom. You can
then intermix commands that generate output and commands that send headers.
The output won't be sent until ob_end_flush( ) is called:
*/

/*
<?php ob_start(); ?>
I haven't decided if I want to send a cookie yet.
<?php setcookie('heron','great blue'); ?>
Yes, sending that cookie was the right decision.
<?php ob_end_flush(); ?>
*/

/*
You can pass ob_start( ) the name of a callback function to process the output buffer with that function. This is useful for postprocessing all the content in a page, such as hiding email addresses from address-harvesting robots:

<?php
function mangle_email($s) {
    return preg_replace('/([^@\s]+)@([-a-z0-9]+\.)+[a-z]{2,}/is',
                        '<$1@...>',
                        $s);
}

ob_start('mangle_email');
?>

I would not like spam sent to ronald@example.com!

<?php ob_end_flush(); ?>

The mangle_email( ) function transforms the output to:
I would not like spam sent to <ronald@...>!
*/
////////////////////////////////////////////////////////////
/*
You want to process a variable with a period in its name, but when a form is submitted, you
can't find the variable.

Replace the period in the variable's name with an underscore. For example, if you have a form
input element named foo.bar, you access it inside PHP as the variable $_REQUEST['foo_bar'].

Because PHP uses the period as a string concatenation operator, a form variable called
animal.height is automatically converted to animal_height, which avoids creating an
ambiguity for the parser. While $_REQUEST['animal.height'] lacks these ambiguities, for
legacy and consistency reasons, this happens regardless of your register_globals
settings.
*/

////////////////////////////////////////////////////////////

/*
You can put a username and password in the URL if you need to retrieve a protected page. In
this example, the username is david, and the password is hax0r. Here's how to do it with
fopen( ):

$fh = fopen('http://david:hax0r@www.example.com/secrets.html','r')
    or die($php_errormsg);
while (! feof($fh)) {
    $page .= fread($fh,1048576);
}
fclose($fh);
*/
////////////////////////////////////////////////////////////

// Build query string from an array

$query = http_build_query($array);

////////////////////////////////////////////////////////////