P. 1
JavaScript Code Conventions

JavaScript Code Conventions

|Views: 46|Likes:
Published by nbsp
JavaScript Code Conventions
JavaScript Code Conventions

More info:

Published by: nbsp on Sep 05, 2012
Copyright:Attribution Non-commercial


Read on Scribd mobile: iPhone, iPad and Android.
download as DOCX, PDF, TXT or read online from Scribd
See more
See less





JavaScript Code Conventions

30 Mar 2011

I've put together a list of JavaScript code conventions I use for personal and commercial projects. In addition to this page, I've also created test cases that demonstrate the trickier bits of JavaScript. These are available on GitHub.

JavaScript files should be stored in .js files. Indentation should be four spaces. Don't use tabs. Avoid lines over 80 characters. End all statements with a semicolon. The amount of JavaScript on an HTML page should be kept to a minimum. Typically the page could start initialization code:
... <script> $(document).ready(function () { myNamespace.initializePage({ color: "blue" }); }); </script> </body> </html>

Add useful comments to bits of code that might require explanation.
var calculateBoxWidth = function (element) { // Add a predefined constant to the width of the element to avoid overlap. return $(element).width() + myNamespace.SPACING_CONSTANT;

// Calculate the box width. DON'T DO THIS.. // Correct: separate the code into functions. /* . // Correct: use proper naming.. . // A big hunk of initialization code. */ // Setup events. var initializePage = function () { loadData(). var cbw = function (element) { var mbs = 45..}. /* Long block of code.. /* Long block of code.. /* Long block of code. */ }.. */ // Create widgets. var calculateBoxWidth = function (element) { var maximumBlockSpan = 45... // maximum block span /* . DON'T DO THIS. Don't use comments where you should use functions. var initializePage = function () { // Load data.. // Names shortened to their first letters. */ }. */ }. Don't use comments where you should use proper naming..

var bar = function () {}. // These variables leak into the global namespace. This can cause conflicts between different libraries. var powerFluxCapacitor = function () { /* . functions and objects in a custom namespace. Variable names should start with a lowercase letter and use camelCase. Take time to figure out the proper names that represent what you're trying to achieve. setupEvents(). Names Variable name should use uppercase. everything in JavaScript ends up in the global namespace.foo = 12. var myNamespace = {}. myNamespace. DON'T DO THIS. }. Don't use underscores.. */ }.. Namespaces By default. lowercase and numbers.bar = function () {}.createWidgets(). var welcomeText = "Hello. Encapsulate your variables. var meaningOfLife = 42. Avoid using special characters. myNamespace. var foo = 12. Naming things is one of the hardest things in programming. World!". // Correct: create one namespace to store everything under. Variable declaration . Use meaningful names that indicate the function of a variable.

JSLint complains if you're initializing variables without the var keyword.Be careful with declaring variables. . They clutter up the global namespace. // Correct: always use the var keyword. // DON'T DO THIS. DON'T DO THIS. DON'T DO THIS. return tmp. }. return tmp. function multiply(a. var toUpper = function (v) { var tmp = v. // Leaky global variable. // tmp is now part of the global namespace. // Function literals are automatically global. }.toString(). var multiply = function (a. Use the var keyword to define functions. b) { return a * b.toUpperCase(). }. b) { return a * b. } // Correct: use the var keyword to define a function.toUpperCase(). Forgetting the var keyword creates an implicit global variable. tmp = v. var toUpper = function (v) { // Since we forgot the "var" keyword.toString(). Functions Don't use function literals.

myNamespace.multiply = function (a. but also requires a bit more discipline. var badReturn = function () { return { success: true }. }. An object can be created using the "new" keyword. // DON'T DO THIS. }. start the returned object on the same line. but prototype-based inheritance. // the JavaScript parser considers this line finished and inserts a semicolon. // This means that the return statement returns nothing. When returning from a function. var goodReturn = function () { return { success: true }. // Because the return statement is on a line of its own. // Correct: start the statement on the same line as the return keyword.// Better: put functions under your namespace.description = description. Objects Objects are different in JavaScript than in Python or Java. b) { return a * b. Otherwise. }. They don't use class-based inheritance. . the JavaScript parser will think the statement has finished and return without a value. var LifeForm = function (description) { this. This makes the object model more flexible. }.

To create methods on the object.name. var TestObject = function () { this. always start the name with an uppercase.toJSON = function () { return { name: this. the result will be undefined. Customer.address = address. which means everything will end up in the global namespace. "The object has been created. }.counter === 42.prototype. // Correct: use the new keyword to create objects. since you don't return anything from the function.var myLifeForm = new LifeForm(). ok(typeof newObj === "object". var Customer = function (name."). ok(newObj. this. "this" will be set to the window. . always use the "new" keyword. ok(obj === undefined. // Forgetting the new keyword.counter = 42. If you forget the "new" keyword. var newObj = new TestObject(). var obj = TestObject(). "Variable counter has leaked into the global namespace. DON'T DO THIS. This has an effect on the meaning of the "this" variable. Furthermore. "The counter is part of the object. When creating an object."). To indicate that this is an object that should be instantiated with the "new" keyword. address) { this. ok(counter === 42. add them to the function prototype.name = name. }."). "No object has been created.").

goodSearch = function () { var that = this. Instead. }.prototype.query }.getJSON(PAGE_SEARCH_URL.query = query.results = data. PageSearcher. // Correct: thanks to closures.getJSON(PAGE_SEARCH_URL. }. Variables declared in blocks remain available outside of the block. }.results. Scoping JavaScript does not have block scope. It only has function scope. use "that".address: this. $. }). To avoid confusion. their "this" points to the window global. "that" points our PageSearcher object. at the top of the function.results = []. function (data) { that. DON'T DO THIS. { 'q': this. Inner functions don't have access to the object using this.query }. // The "this" in the inner function points to the window global. }. To avoid conflicts. // leaking variables.address }. PageSearcher. var PageSearcher = function (query) { this.prototype. { 'q': this.results = data. declare all variables before you use them. .results. function (data) { this. }).badSearch = function () { $. this.

"). }. "The tmp variable is still accessible. var total = total + ++counter. DON'T DO THIS. . // Tricky code. "The i variable is still accessible. 9. var betterLoopFunction = function () { var i. "The tmp variable is still accessible."). // Correct: define all variables at the top of the function. DON'T DO THIS. 10. i += 1) { tmp = i. var loopFunction = function () { for (var i = 0. }. but at least it is explicit. i += 1) { var tmp = i. but at least it is explicit. // Confusing scoping.JSLint will check for this. var counter = 5. } equals(i. i < 10. equals(tmp. var total = 42. i < 10. Various Avoid using ++ and -. for (i = 0. "The i variable is still accessible. // ++ can introduce bugs. 9. } equals(i.")."). 10. tmp.since they can create tricky code that is prone to errors. equals(tmp.

// Correct: use += and -=. c. test("Area of a circle".PI. Organize tests into modules. Here's a complete test example: module("Circle"). i += 1) { doTheThing()."). c. } Unit Testing QUnit makes testing JavaScript easy. function () { var c = new Circle({ radius: 5 }). One module = one file. }).PI.radius * c."). i < 10. equals(c. Useful resources    JSLint: a web service that checks your JavaScript code for potential errors. test("Circumference of a circle". }).area(). function () { var c = new Circle({ radius: 5 }). equals(c. "The circumference is the diameter multiplied by Pi. JavaScript Reference on the Mozilla Developer Network: one of the best JavaScript guides online.radius * 2 * Math.radius * Math.circumference(). for (i = 0. . "The area is the square of the radius multiplied by Pi. Code Conventions by Douglas Crockford: the main go-to guide and the inspiration for this guide.

All of our JavaScript code is sent directly to the public. Neatness counts. This reduces the effects of delays imposed by script loading on other page components. a program will be handled by many pairs of hands and eyes. Variable Declarations All variables should be declared before used. not the script tag. Over its lifetime.Code Conventions for the JavaScript Programming Language This is a set of coding conventions and rules for use in JavaScript programming. Generally use line comments. that determines the MIME type. It is inspired by the Sun document Code Conventions for the Java Programming Language. and the difference is eliminated by minification. but the size is not significant over local networks. Code in HTML adds significantly to pageweight with no opportunity for mitigation by caching and compression. ideally after a comma. Place the break after an operator. Implied global variables should never be used. If a program is able to clearly communicate its structure and characteristics. Don't waste the reader's time with stuff like i = 0. The use of spaces can produce a larger filesize. Focus on what is not immediately visible. The comments should be well-written and clear. An occasional nugget of humor might be appreciated. Comments Be generous with comments. It is heavily modified of course because JavaScript is not Java. . Use of tabs should be avoided because (as of this writing in the 21st Century) there still is not a standard for the placement of tabstops. Save block comments for formal documentation and for commenting out. The next line should be indented 8 spaces. it is less likely that it will break when modified in the never-too-distant future. // Set i to zero.js> tags should be placed as late in the body as possible. but doing so makes the program easier to read and makes it easier to detect undeclared variables that may become implied globals. Line Length Avoid lines longer than 80 characters. Code conventions can help in reducing the brittleness of programs. Make comments meaningful. It should always be of publication quality.js files. Frustrations and resentments will not. A break after an operator decreases the likelihood that a copy-paste error will be masked by semicolon insertion. just like the code they are annotating. JavaScript Files JavaScript programs should be stored in and delivered as . it may be necessary to break it. The var statements should be the first statements in the function body. Indentation The unit of indentation is four spaces. There is no need to use the language or type attributes. <script src=filename. It is the server. The long-term value of software to an organization is in direct proportion to the quality of the codebase. JavaScript does not require this. It is important that comments be kept up-to-date. It is useful to leave information that will be read at a later time by people (possibly yourself) who will need to understand what you have done. Erroneous comments can make programs even harder to read and understand. When a statement will not fit on a single line. JavaScript code should not be embedded in HTML files unless the code is specific to a single session.

length. b) { return (e * a) + b. there should be one space between the word function and the omited.push(node). }. so defining variables in blocks can confuse programmers who are experienced with other C family languages. The body itself is indented four spaces. // size of table JavaScript does not have block scope. Inner functions should follow the variables are included in its scope. When a function is to be invoked immediately.split(' '). datum: 0 }. }. // array of class names var c = node. } } } }). } If a function literal is anonymous. then split it into a list of simple names. The } (right curly brace) is aligned with the line containing the beginning of the declaration of the function. // loop counter // If the node has a class name. ( (left parenthesis). return { get: function (key) { . } This convention works well with JavaScript because in JavaScript. function inner(a. values = [].It is preferred that each variable be given its own line and comment. There should be one space between the ) (right parenthesis) and the { (left curly brace) that begins the statement body. Function Declarations All functions should be declared before they are used. function (node) { var a. } return inner(0. that = { method: function () { return this.datum. They should be listed in alphabetical order. d) { var e = c * d. Use of global variables should be minimized. // If any of them match the requested name. functions and object literals can be placed anywhere that an expression is allowed. var statement. var collection = (function () { var keys = []. // the node's classname var i. Define all variables at the top of the function.onclick = function (e) { return false. then append the node to the set of results. walkTheDOM(document. which is an incorrect reading. if (c) { a = c.body. function outer(c. break. the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself. If the space is Use of global functions should be minimized. 1). i < a. This helps make it clear what There should be no space between the name of a function and the ( (left parenthesis) of its parameter list. // currently selected table entry var level. var currentEntry. div. // indentation level var size. then it can appear that the function's name is function. i += 1) { if (a[i] === className) { results. Implied global variables should never be used. return results. for (i = 0. function getElementsByClassName(className) { var results = []. It provides the best readability with inline functions and complex structures.className.

when they are part of a control structure. Put a . 9). Do not use $ (dollar sign) or \ (backslash) in names. The only expressions that should be used as statements are assignments and invocations. The { (left curly brace) should be at the end of the line that begins the compound statement. Constructor functions which must be used with the new prefix should start with a capital letter. JavaScript allows any expression to be used as a statement. }()). Braces should be used around all statements. Z.indexOf(key). switch.length. Only these statements should be labeled: while. 1). Do not use _ (underbar) as the first character of a name. the 10 digits (0 . if (at >= 0) { return values[at]. and _ (underbar). if (at < 0) { at = keys. so the capitalization convention is the only defense we have. JavaScript issues neither a compile-time warning nor a run-time warning if a required new is omitted. This can mask some errors. set: function (key. if (at >= 0) { keys. } keys[at] = key. . }. (left Statement labels are optional. Avoid conventions that demonstrate a lack of competence. particularly in the presence of semicolon insertion. Bad things can happen if newis not used.var at = keys. The } (right curly brace) should begin a line and be indented to align with the beginning of the line containing the matching { curly brace). 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. This makes it easier to add statements without accidentally introducing bugs..splice(at.splice(at. but it does not actually provide privacy. Avoid use of international characters because they may not read well or be understood everywhere. a . do. Most variables and functions should start with a lower case letter. } } }. remove: function (key) { var at = keys. It is sometimes used to indicate privacy. so there isn't much point in using all caps to signify features that JavaScript doesn't have. use the forms that provide private members.) Statements Simple Statements Each line should contain at most one statement. (semicolon) at the end of every simple statement. for.indexOf(key). value) { var at = keys. values.     Labels The enclosed statements should be indented four more spaces. such as an if or for statement. } }. Compound Statements Compound statements are statements that contain lists of statements enclosed in { } (curly braces)... Names Names should be formed from the 26 upper and lower case letters (A . 1). Global variables should be in all caps. (JavaScript does not have macros or constants. values[at] = value.indexOf(key). z). even single statements. If privacy is important.

return Statement A return statement with a value should not use ( ) (parentheses) around the value. update) { for (variable in if (filter) { } } object) { statements The first form should be used with arrays and with loops of a predeterminable number of iterations. statements . The second form should be used with objects. Be aware that members that are added to the prototype of the object will be included in the enumeration. It is wise to program defensively by using the hasOwnProperty method to distinguish the true members of the object: for (variable in if (object. if Statement The if class of statements should have the following form: if (condition) { } statements if (condition) { } else { } statements statements if (condition) { } else if (condition) { } else { } statements statements statements for Statement A for class of statements should have the following form: for (initialization. The return value expression must start on the same line as the return keyword in order to avoid semicolon insertion.hasOwnProperty(variable)) { } object) { statements } while Statement A while statement should have the following form: while (condition) { } statements do Statement A do statement should have the following form: do { } while (condition). } statements condition.

It tends to obscure the control flow of the function. Bonus Suggestions . All binary operators except . or throw. (period) and ( (left parenthesis) and [ (left bracket) should be separated from their operands by a space. (semicolon). return. This avoids over-indentation. Whitespace Blank lines improve readability by setting off sections of code that are logically related. default) Each group of statements (except the try Statement should end with break. Whitespace should follow every . A switch statement should have the following form: switch (expression) { case default: } expression: statements statements Each case is aligned with the switch. Blank spaces should be used in the following circumstances:  A keyword followed by while (true) { ( (left parenthesis) should be separated by a space.      A blank space should not be used between a function value and its ( (left parenthesis). This helps to distinguish between keywords and function invocations. No space should separate a unary operator and its operand except when the operator is a word such as typeof. Each . (comma). The with statement should not be used. Do not fall through. (semicolon) in the control part of a for statement should be followed with a space. The try class of statements should have the following form: try { } catch (variable) { statements statements } try { } catch (variable) { statements statements statements } finally { } continue Statement Avoid use of the with Statement continue statement. the switch Statement do statement always ends with a .Unlike the other compound statements.

{} and [] Use {} instead of new Object(). The == and != operators do type coercion. In particular. array literals. so that the eval is Evil + + is not misread as ++. Use arrays when the member names would be sequential integers. total = subtotal + +myInput. do not use == to Be careful to not follow a + with + or ++.value.value). Insert parens between them to make your intention clear. Use objects when the member names are arbitrary strings or names. Only functions have scope. (This does not apply to the comma separator. Do not use the constructor. . Function has aliases. === and !== Operators. This pattern can be confusing. (comma) Operator Avoid the use of the comma operator except for very disciplined use in the control part of for statements. Avoid it. Use [] instead of new Array(). Do not pass strings to setTimeout or setInterval. which is used in object literals. . Assignment Expressions Avoid doing assignments in the condition part of Is if (a = b) { if and while statements. is better written as total = subtotal + (+myInput. Confusing Pluses and Minuses === and !== operators. var statements. a correct statement? Or was if (a == b) { intended? Avoid constructs that cannot easily be determined to be correct. Do not use blocks except as required by the compound statements. The eval eval function is the most misused feature of JavaScript. It is almost always better to use the compare against falsy values.) Block Scope In JavaScript blocks do not have scope. and parameter lists.

You're Reading a Free Preview

/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->