// Do not use document.write, use DOM access instead
$( '#element' ).append(' <div>text</div>' );
// Incorrect
document.write('<div>text</div>');
// Use feature detection, not browser/User-Agent sniffing
if ( document.addEventListener ) {
// Incorrect
if ( !$.browser.msie ) {
// Always use semicolons, even though it can be optional at times
return obj;
// Incorrect
return obj
// Keep curly braces on the same line
return {
data: []
};
// Incorrect
return
{
data: []
};
// Always use curly braces, even when optional
if ( val ) {
doSomething();
}
// Incorrect
if ( val ) doSomething();
// Always use literal syntax, unless dealing with dynamic regular expressions
var val = 'mystring',
obj = { a: 1, b: 2, c: 3 },
arr = [1, 2, 3, 4, 5],
regex = /\d{16}/gi,
regex2 = new RegExp( '/' + val + '/', 'g' );
// Incorrect
var val = new String( 'mystring' ),
obj = new Object(),
arr = new Array(),
regex = new RegExp( '/\d{16}/', 'gi' );
// Exploit coercion whenever possible, avoiding comparisons
if ( val ) {
// Incorrect
if ( val !== 0 && val !== null && val !== undefined ) {
// Always use ===, unless comparing against null, which also checks for undefined
if ( val === true ) {
if ( val === 0 ) {
if ( val == null ) {
// Incorrect
if ( val == true ) {
if ( val == 0 ) {
// Do not directly compare against undefined, use typeof if absolutely necessary, or coercion
if ( typeof val === 'undefined' ) {
if ( val ) {
// Incorrect
if ( val === undefined ) {
// No global variables other than the application namespace, always use var
var Namespace = {};
Namespace.val = 3;
// Incorrect
val = 3;
// Incorrect
var Namespace = {},
val = 3;
<!--
No inline JavaScript in markup,
JavaScript must always be in a script block in an external file
-->
<script src="/js/script.js"></script>
<!-- Incorrect -->
<div id="element" onclick="doSomething()"></div>
// Do not ever use jQuery live, always use event delegation
$( '#element' ).on( 'click', 'li', function () {} );
// Incorrect
$( '#element li' ).live( 'click', function () {} );
// Never use eval, use JSON methods or array syntax on objects if needed
var obj = JSON.parse( val );
var val = obj[ 'prop' + i ];
// Incorrect
var obj = eval( val );
var val = eval( 'obj.prop' + i );
// Use anonymous function expressions or function references for setTimeout and setInverval, not strings
setTimeout( function () {}, 1000 );
setTimeout( myFunctionRef, 1000 );
// Incorrect
setInterval( "myFunctionRef()", 1000 );
// Do not ever use with, utilize caching instead, also improves scope lookups
var obj = data.store.obj;
obj.prop1 = 1;
obj.prop2 = 2;
// Incorrect
with ( data.store.obj ) {
prop1 = 1;
prop2 = 2;
}
// Start every JavaScript file with a function or some sort of closure and "use strict";
( function () {
"use strict";
// Convert strings to numbers using the unary + operator
var val = '3',
num = +val;
// Incorrect
var val = '3',
num = parseInt( num, 10 );
// If unary operator is unable to be used, always specify the radix on parseInt
var num = parseInt( '3', 10 );
// Incorrect
var num = parseInt( '3' );
// Never make synchronous AJAX calls
// Incorrect
$.ajax( { async: false } );
// Always cache the array length before looping
for ( var i = 0, il = arr.length; i < il; i++ ) {
// Incorrect
for ( var i = 0; i < arr.length; i++ ) {
// Never use for-in loops on arrays, always for loops
for ( var i = 0, il = arr.length; i < il; i++ ) {
// Incorrect
for ( var val in arr ) {
// Do use || operator to assign default values if falsy values are unacceptable
var val = obj || {};
// Incorrect
var val = obj;
if ( !val ) {
val = {};
}
// Declare variables at the top of functions to avoid issues with hoisting
// Do not declare in blocks
function () {
var val1 = 1,
val2 = 2,
val3 = 3;
// Exception: declaring loop variables is acceptable at the top of the function
// or in the loop definition
function () {
for ( var i = 0, il = arr.length; i < il; i++ ) {
// Incorrect
function () {
console.log( val1 );
var val1 = 1,
val2 = 2,
val3 = 3;
for ( var i = 0, il = arr.length; i < il; i++ ) {
var current = arr[i];
// Use single var pattern in environments with weak minification,
var val1 = 1,
val2 = 2,
val3 = 3;
// Alternate
var val1 = 1;
var val2 = 2;
var val3 = 3;
// When using for-in loops, always pair it with the hasOwnProperty check
for ( var key in obj ) {
if ( obj.hasOwnProperty( key ) ) {
// Always cache a jQuery selection if it will be used more than once
$( '#element' ).on( 'click', 'li', function () {
var el = $( this ),
text = el.text(),
name = el.attr( 'name' );
// Incorrect
$( '#element' ).on( 'click', 'li', function () {
var text = $( this ).text(),
name = $( this ).attr( 'name' );
// Do not modify host or native objects
// Incorrect
Object.prototype.doSomething = function () {};
window.alert = function () {};
// Constructor functions should guarantee their instances to avoid
// creating globals in ECMAScript3 and exceptions in ECMAScript5
var Person = function fn ( name ) {
if ( !( this instanceof fn ) ) {
return new fn( name );
}
this.name = name;
};
var person1 = new Person( 'bob' ),
person2 = Person( 'john' );
// Incorrect
var Person = function ( name ) {
this.name = name;
};
// Works fine
var person1 = new Person( 'bob' ), // works fine
// Creates global variable "name" in ECMAScript3, exception in ECMAScript5
person2 = Person( 'john' );
// Using terse JavaScript is OK if it doesn't kill readability
console && console.log && console.log(val);
<!--
All scripts must go at the bottom of the page before
the closing body tag, unless HTML5 shimming
-->
<script src="script1.js"></script>
<script src="script2.js"></script>
</body>
<!-- Incorrect -->
<head>
<script src="script1.js"></script>
<script src="script2.js"></script>
</head>
<body>
// Do use the Single Responsibility Principle (a function only performs one task)
// Pass every script through the JSHint website