Global scope & closure wrapping
Variables must not be leaked into the global scope unless there is an explicit functional need for global access. Within function scope, variables must be declared with the var statement.
To help prevent scope leaking, each script file should be entirely wrapped in an anonymous, self-executing closure, passing the jQuery and Underscore objects as parameters:
;( function($, _, undefined){ // Code goes here }(jQuery, _));
This prevents variables from leaking into the global scope, and also ensures jQuery code making use of the dollar variable $ does not conflict with any other code that might be running on the page.
Note that a semi-colon appears as the first character. This helps prevent errors caused by incorrect semi-colon insertion in previous code, should this script be concatenated with others. It is a defensive coding practice, and recommended in all files.
Strict mode
The use of strict mode is required for all default javascript in IPS4. Strict mode helps prevent leaking into the global scope, catches code problems that would otherwise fail silently, and enables javascript engines to perform more optimizations. However, it is important that this is applied using the per-function syntax and not the per-script syntax, otherwise unexpected behavior can occur when script files are concatenated with 3rd-party scripts.
Given that all script files should be wrapped in a self-executing closure, the syntax for enabling strict mode looks like this:
;( function($, _, undefined){ "use strict"; // Script here, e.g. module definition etc. }(jQuery, _));
By putting the "use strict"; statement inside the the closure, we ensure all of our code runs in strict mode without affecting any external code by accident. Note that the strict mode statement must be the very first line of the function, as shown.
Further information about strict mode and the code requirements it imposes is available at MDN.
Documentation & commenting
The use of JSDoc is highly encouraged to document code. Refer to the JSDoc documentation for exact syntax.
Within scripts, comment blocks /* */ should be reserved for formal documentation and situations where large blocks of existing code need to be commented out temporarily. Line-by-line comments should always use the single-line // comment style.
/** * Formal documentation */ // Informal comments to describe code
Semi-colons
Semi-colons must be used at the end of every statement, even when function/object literals are being assigned. For example:
// Simple statements $('#element').doSomething(); var test = 'value'; return 'text'; // Function and object literals var test = function () { ... }; var test2 = { key1: 'value' };
Names
All names (variables, methods, properties etc.) should use lowerCamelCase, such as deselectAll, createModule and itemSelector.
Logging
You should not use console.log for debugging. This does not provide for disabling debugging in production, and can break pages on older browsers if not accounted for. A debugging method is provided via Debug.log that addresses these concerns, and should be used instead.
Line length
Aim to keep the line length below 120 characters to maintain readability. Longer lines should be split immediately after a comma or operator, with the remainder of the statement indented further to ensure clarity. For example:
if( ( options.dataSource && options.dataSource.indexOf('#') === 0 && $( options.dataSource ).length ) || originalTextField.is('[list]') ){
jQuery chaining
It is recommended that multiple jQuery methods chained on an element are placed on newlines to improve clarity. Additionally, indentation should be used to reflect the current working level of the chain. For example:
$('selector') .find('.classname') .hide() .end() .find('.otherClassname') .css('width', '100%') .show() .end() .append( $('<div/>').attr( { id: 'someID' });
By indenting in this way, we make it clear that the hide() method applies only to the elements matching .classname, before calling end() to return to the original working level - and so on.
Report Guide