JavaScript coding standards Table of Contents IndentationLine LengthCommentsVariable DeclarationsFunction DeclarationsNamesStatements Simple StatementsCompound StatementsLabelsreturn Statementif Statementfor Statementwhile Statementdo Statementswitch Statementtry Statement WhitespaceClassesOther Suggestions getElementAvoid Direct DOM manipulationSynchronous AJAX{} and [], (comma) Operatoreval is EVIL JavaScript coding standards are the standards we use when writing JavaScript code. These standards are inspired by the conventions outlined by Crockford: http://javascript.crockford.com/code.html Indentation The unit of indentation is 4 spaces Line Length Avoid lines longer than 120 characters. When a statement will not fit on a single line, it may be necessary to break it. Place the break after an operator, ideally after a comma. A break after an operator decreases the likelihood that a copy-paste error will be masked by semicolon insertion. The next line should be indented with 4 spaces. if (value.toLowerCase.indexOf("help") > -1 || value.toLowerCase.indexOf("broke") > -1 || value.toLowerCase.indexOf("outage") > -1) { g_form.setValue("priority", "1"); g_form.setValue("urgency", "1"); } Comments Be generous with comments. They will be read later by people (possibly yourself) who will need to understand what you have done. The comments should be well-written and clear, just like the code they are annotating. An occasional nugget of humor might be appreciated. Frustrations and resentments will not. It is important that comments be kept up-to-date. Erroneous comments can make programs even harder to read and understand. Make comments meaningful. Focus on what is not immediately visible. Don't waste the reader's time with stuff like i = 0; // Set i to zero. Generally use line comments. Save block comments for formal documentation. Variable Declarations All variables should be declared before use. JavaScript does not require this, but doing so makes the program easier to read and makes it easier to detect undeclared variables that may become implied globals. Implied global variables should never be used. The var statements should be the first statements in the function body. var currentEntry; // currently selected table entry var level; // indentation level var size; // size of table Each variable should be given its own line and comment. Do not use: var i = 0, j = 1; Use this instead: var i = 0; var j = 1; JavaScript does not have block scope, so defining variables in blocks can confuse programmers who are experienced with other C family languages. Define all variables at the top of the function. The use of global variables should be minimized. Implied global variables should never be used. Function Declarations All functions should be declared before they are used. There should be no space between the name of a function and the ( (left parenthesis) of its parameter list. There should be one space between the ) (right parenthesis) and the { (left curly brace) that begins the statement body. The body itself is indented with tabs. The } (right curly brace) is aligned with the line containing the beginning of the declaration of the function. function outer(msg) { var logMessage = "Log: " + msg; jslog(logMessage); } Names Names should be formed from the 26 upper and lower case letters (A .. Z, a .. z), the 10 digits (0 .. 9), and _ (underbar). Avoid use of international characters because they may not read well or be understood everywhere. Do not use $ (dollar sign) or \ (backslash) in names. Use the _ (underbar) to indicate the function is not intended to be called outside of the script. Avoid conventions that demonstrate a lack of competence.Local variables and functions should start with a lowercase letter and use camelCaseUpAndDownGlobal variables should start with a g_, for example: g_formConstructor functions that must be used with the new prefix should start with a capital letter Statements Simple Statements Each line should contain at most one statement. Put a ; (semicolon) at the end of every simple statement. Note that an assignment statement which is assigning a function literal or object literal is still an assignment statement and must end with a semicolon. JavaScript allows any expression to be used as a statement. This can mask some errors, particularly in the presence of semicolon insertion. The only expressions that should be used as statements are assignments and invocations. Compound Statements Compound statements are statements that contain lists of statements enclosed in { } (curly braces). The enclosed statements should be indented with 4 spaces.The { (left curly brace) should be at the end of the line that begins the compound statement.The } (right curly brace) should begin a line and be indented to align with the beginning of the line containing the matching { (left curly brace). if (condition) { doSomething(); doSomethingElse(); } Labels Statement labels are optional. Only these statements should be labeled: while, do, for, switch. return Statement A return statement with a value should not use ( ) (parentheses) around the value. The return value expression must start on the same line as the return keyword in order to avoid semicolon insertion. function shortDescriptionIsEmpty() { if (g_form.getValue(short_description) == "") return true; return false; } if Statement The if class of statements should have the following form: if (condition) { statements } if (condition) { statements } else { statements } if (condition) { statements } else if (condition) { statements } else { statements } for Statement A for class of statements should have the following form: for (initialization; condition; update) { statements } for (variable in object) { if (filter) { statements } } This form should be used with arrays and with loops of a predeterminable number of iterations. while Statement A while statement should have the following form: while (condition) { statements } do Statement A do statement should have the following form: do { statements } while (condition); Unlike the other compound statements, the do statement always ends with a ; (semicolon). switch Statement A switch statement should have the following form: switch (expression) { case expression: statements default: statements } Each case should be tabbed in. Each group of statements (except the default) should end with break, return, or throw. Do not fall through. try Statement The try class of statements should have the following form: try { statements } catch (variable) { statements } Whitespace Blank lines improve readability by setting off sections of code that are logically relatedA blank space should not be used between a function value and its ( (left parenthesis). This helps to distinguish between keywords and function invocationsEach ; (semicolon) in the control part of a for statement should be followed with a space.Whitespace should follow every , (comma) Classes ServiceNow uses an object-oriented approach to JavaScript with support from the prototype.js library. Classes are defined as: var ClassNameHere = Class.create({ // constructor initialize: function(constructor_arguments) { // define instance variable here this.variable = initial_value; }, // functions defined here function1: function(arguments) { }, type: 'ClassNameHere' }); To create a subclass that extends another class, the class definition looks like this: var ClassNameHere = Class.create(ParentClassName, { ... Constants are defined as instance variables before the initialize method and are uppercase. Note that these variables are really no different than the instance variables defined in the initialize method. var ClassNameHere = Class.create({ CONSTANT_VARIABLE1: 'constant_value1', CONSTANT_VARIABLE2: 'constant_value2', // constructor initialize: function(constructor_arguments) { // define instance variable here this.variable = initial_value; }, // functions defined here function1: function(arguments) { }, type: 'ClassNameHere' }); Constants, or class statics, should really be defined as: ClassNameHere.CONSTANT_VARIABLE1 = 'constant_value_1'; But doing this would move the constants to the after the class definition since the var ClassNameHere must be defined before using ClassNameHere.CONSTANT making them hard to find and making the class hard to read. Other Suggestions getElement Use g_form.getElement(id) instead of document.getElementById(id). Avoid Direct DOM manipulation Use g_form.getElement(id) to get the DOM element if you must modify the element. Instead, for most common operations, use the following g_form functions (found in GlideForm.js): setDisabledsetDisplaysetMandatorysetReadonlysetValuesetVisible Synchronous AJAX Avoid synchronous AJAX, such as: GlideRecord.js query() makes a call and blocks the browser until the response is returned (bad unless unavoidable)query(callbackFunc) makes a call without blocking the browser and calls the specified callbackFunc when the response is received (good) GlideAJAX GlideAjax.getXMLWait - blocks the browser (bad unless unavoidable)GlideAjax.getXML - calls the callback function when the response is received (good) g_form.getReference makes a synchronous GlideRecord call which blocks the browser (bad). This should be used only if necessary. Should use this instead: var sysId = g_form.getValue(field_name); var gr = new GlideRecord(table); gr.query('sys_id', sysId, refCallback); function refCallback(gr) { // gr now has the GlideRecord with the results of the query } {} and [] Use {} instead of new Object(). Use [] instead of new Array().Use arrays when the member names would be sequential integers. Use objects when the member names are arbitrary strings or names. , (comma) Operator Avoid the use of the comma operator except for very disciplined use in the control part of for statements. (This does not apply to the comma separator, which is used in object literals, array literals, var statements, and parameter lists.) eval is EVIL The eval function is the most misused feature of JavaScript. Avoid it.eval has aliases. Do not use the Function constructor. Do not pass strings to setTimeout or setInterval.