Aaron Whyte
Bob Jervis
Dan Pupius
Erik Arvidsson
Fritz Schneider
Robby Walker
This style guide contains many details that are initially
hidden from view. They are marked by the triangle icon, which you
see here on your left. Click it now.
You should see "Hooray" appear below.

Hooray! Now you know you can expand points to get more
details. Alternatively, there's a "toggle all" at the
top of this document.

JavaScript is the main client-side scripting language used
by many of Google's open-source
projects.
This style guide is a list of dos and don'ts for
JavaScript programs.

Declarations with var: Always
When you fail to specify var,
the variable gets placed in the global context, potentially clobbering
existing values. Also, if there's no declaration, it's hard to tell in
what scope a variable lives (e.g., it could be in the Document or
Window just as easily as in the local scope). So always declare with
var.

Use NAMES_LIKE_THIS for constant values.

Use @const to indicate a constant (non-overwritable)
pointer (a variable or property).

Never use the
const keyword
as it's not supported in Internet Explorer.

If a value is intended to be constant
and immutable, it should be given a name
in CONSTANT_VALUE_CASE.
ALL_CAPS additionally implies @const
(that the value is not overwritable).

Primitive types (number, string,
boolean) are constant values.

Objects'
immutability is more subjective — objects should be
considered immutable only if they do not demonstrate observable
state change. This is not enforced by the compiler.

The @const annotation on a variable or property
implies that it is not overwritable. This is enforced by the
compiler at build time. This behavior is consistent with the
const keyword (which we do not use due to the
lack of support in Internet Explorer).

A @const annotation on a method additionally
implies that the method cannot not be overridden in subclasses.

A @const annotation on a constructor implies the
class cannot be subclassed (akin to final in Java).

Note that @const does not necessarily imply
CONSTANT_VALUES_CASE.
However, CONSTANT_VALUES_CASEdoes imply @const.

JavaScript error - first the function returning 42 is called
with the second function as a parameter, then the number 42 is
"called" resulting in an error.

You will most likely get a 'no such property in undefined'
error at runtime as it tries to call
x[ffVersion, ieVersion][isIE]().

die is always called since the array minus 1 is
NaN which is never equal to anything (not even if
resultOfOperation() returns NaN) and
THINGS_TO_EAT gets assigned the result of
die().

JavaScript requires statements to end with a semicolon, except when
it thinks it can safely infer their existence. In each of these
examples, a function declaration or object or array literal is used
inside a statement. The closing brackets are not enough to signal
the end of the statement. Javascript never ends a statement if the
next token is an infix or bracket operator.

This has really surprised people, so make sure your assignments end
with semicolons.

Semicolons should be included at the end of function expressions,
but not at the end of function declarations. The distinction is
best illustrated with an example:

Nested functions can be very useful, for example in the creation of
continuations and for the task of hiding helper functions. Feel free
to use them.

No

Do not do this:

if (x) {
function foo() {}
}

While most script engines support Function Declarations within blocks
it is not part of ECMAScript (see
ECMA-262,
clause 13 and 14). Worse implementations are inconsistent with each
other and with future EcmaScript proposals. ECMAScript only allows for
Function Declarations in the root statement list of a script or
function. Instead use a variable initialized with a Function
Expression to define a function within a block:

Without custom exceptions, returning error information from a
function that also returns a value can be tricky, not to mention
inelegant. Bad solutions include passing in a reference type to hold
error information or always returning Objects with a potential
error member. These basically amount to a primitive exception
handling hack. Feel free to use custom exceptions when
appropriate.

Always preferred over non-standards features

For maximum portability and compatibility, always prefer standards
features over non-standards features (e.g.,
string.charAt(3) over string[3] and element
access with DOM functions instead of using an application-specific
shorthand).

No

There's no reason to use wrapper objects for primitive types, plus
they're dangerous:

Multi-level prototype hierarchies are how JavaScript implements
inheritance. You have a multi-level hierarchy if you have a
user-defined class D with another user-defined class B as its
prototype. These hierarchies are much harder to get right than they
first appear!

For that reason, it is best to use goog.inherits() from
the Closure Library
or a similar library function.

In modern JavaScript engines, changing the number of properties on an
object is much slower than reassigning the values. The delete keyword
should be avoided except when it is necessary to remove a property
from an object's iterated list of keys, or to change the result of
if (key in obj).

One thing to keep in mind, however, is that a closure keeps a pointer
to its enclosing scope. As a result, attaching a closure to a DOM
element can create a circular reference and thus, a memory leak. For
example, in the following code:

the function closure keeps a reference to element,
a, and b even if it never uses
element. Since element also keeps a
reference to the closure, we have a cycle that won't be cleaned up by
garbage collection. In these situations, the code can be structured
as follows:

eval() makes for confusing semantics and is dangerous
to use if the string being eval()'d contains user input.
There's usually a better, clearer, and safer way to write your code,
so its use is generally not permitted.

For RPC you can always use JSON and read the result using
JSON.parse() instead of eval().

If the feed was modified to include malicious JavaScript code, then
if we use eval then that code will be executed.

var userInfo = JSON.parse(feed);
var email = userInfo['email'];

With JSON.parse, invalid JSON (including all executable
JavaScript) will cause an exception to be thrown.

No

Using with clouds the semantics of your program.
Because the object of the with can have properties that
collide with local variables, it can drastically change the meaning
of your program. For example, what does this do?

with (foo) {
var x = 3;
return x;
}

Answer: anything. The local variable x could be
clobbered by a property of foo and perhaps it even has
a setter, in which case assigning 3 could cause lots of
other code to execute. Don't use with.

Only in object constructors, methods, and in setting up closures

The semantics of this can be tricky. At times it refers
to the global object (in most places), the scope of the caller (in
eval), a node in the DOM tree (when attached using an
event handler HTML attribute), a newly created object (in a
constructor), or some other object (if function was
call()ed or apply()ed).

Because this is so easy to get wrong, limit its use to those places
where it is required:

in constructors

in methods of objects (including in the creation of closures)

Only for iterating over keys in an object/map/hash

for-in loops are often incorrectly used to loop over
the elements in an Array. This is however very error
prone because it does not loop from 0 to
length - 1 but over all the present keys in the object
and its prototype chain. Here are a few cases where it fails:

Associative Arrays are not allowed... or more precisely
you are not allowed to use non number indexes for arrays. If you need
a map/hash use Object instead of Array in
these cases because the features that you want are actually features
of Object and not of Array.
Array just happens to extend Object (like
any other object in JS and therefore you might as well have used
Date, RegExp or String).

No

Do not do this:

var myString = 'A rather long string of English text, an error message \
actually that just keeps going and going -- an error \
message to make the Energizer bunny blush (right through \
those Schwarzenegger shades)! Where was I? Oh yes, \
you\'ve got an error and all the extraneous whitespace is \
just gravy. Have a nice day.';

The whitespace at the beginning of each line can't be safely stripped
at compile time; whitespace after the slash will result in tricky
errors; and while most script engines support this, it is not part
of ECMAScript.

Use string concatenation instead:

var myString = 'A rather long string of English text, an error message ' +
'actually that just keeps going and going -- an error ' +
'message to make the Energizer bunny blush (right through ' +
'those Schwarzenegger shades)! Where was I? Oh yes, ' +
'you\'ve got an error and all the extraneous whitespace is ' +
'just gravy. Have a nice day.';
Yes

Use Array and Object literals instead of
Array and Object constructors.

Array constructors are error-prone due to their arguments.

// Length is 3.
var a1 = new Array(x1, x2, x3);
// Length is 2.
var a2 = new Array(x1, x2);
// If x1 is a number and it is a natural number the length will be x1.
// If x1 is a number but not a natural number this will throw an exception.
// Otherwise the array will have one element with x1 as its value.
var a3 = new Array(x1);
// Length is 0.
var a4 = new Array();

Because of this, if someone changes the code to pass 1 argument
instead of 2 arguments, the array might not have the expected
length.

To avoid these kinds of weird cases, always use the more readable
array literal.

var a = [x1, x2, x3];
var a2 = [x1, x2];
var a3 = [x1];
var a4 = [];

Object constructors don't have the same problems, but for readability
and consistency object literals should be used.

Modifying builtins like Object.prototype and
Array.prototype are strictly forbidden. Modifying other
builtins like Function.prototype is less dangerous but
still leads to hard to debug issues in production and should be
avoided.

Getters and setters methods for properties are not required.
However, if they are used, then getters must be named
getFoo() and setters must be named
setFoo(value). (For boolean getters,
isFoo() is also acceptable, and often sounds more
natural.)

JavaScript has no inherent packaging or namespacing support.

Global name conflicts are difficult to debug, and can cause
intractable problems when two projects try to integrate. In order
to make it possible to share common JavaScript code, we've adopted
conventions to prevent collisions.

ALWAYS prefix identifiers in the global scope with a
unique pseudo namespace related to the project or library. If you
are working on "Project Sloth", a reasonable pseudo namespace
would be sloth.*.

var sloth = {};
sloth.sleep = function() {
...
};

Many JavaScript libraries, including
the Closure Library
and
Dojo toolkit
give you high-level functions for declaring your namespaces.
Be consistent about how you declare your namespaces.

goog.provide('sloth');
sloth.sleep = function() {
...
};

When choosing a child-namespace, make sure that the owners of the
parent namespace know what you are doing. If you start a project
that creates hats for sloths, make sure that the Sloth team knows
that you're using sloth.hats.

"External code" is code that comes from outside your codebase,
and is compiled independently. Internal and external names should
be kept strictly separate. If you're using an external library
that makes things available in foo.hats.*, your
internal code should not define all its symbols in
foo.hats.*, because it will break if the other
team defines new symbols.

If you need to define new APIs on an external namespace, then you
should explicitly export the public API functions, and only those
functions. Your internal code should call the internal APIs by
their internal names, for consistency and so that the compiler
can optimize them better.

Never create aliases in the global scope. Use them only in
function blocks.

Filenames should be all lowercase in order to avoid confusion on
case-sensitive platforms. Filenames should end in .js,
and should contain no punctuation except for - or
_ (prefer - to _).

Must always succeed without side effects.

You can control how your objects string-ify themselves by defining a
custom toString() method. This is fine, but you need
to ensure that your method (1) always succeeds and (2) does not have
side-effects. If your method doesn't meet these criteria, it's very
easy to run into serious problems. For example, if
toString() calls a method that does an
assert, assert might try to output the name
of the object in which it failed, which of course requires calling
toString().

OK

It isn't always possible to initialize variables at the point of
declaration, so deferred initialization is fine.

Always

Always use explicit scope - doing so increases portability and
clarity. For example, don't rely on window being in the
scope chain. You might want to use your function in another
application for which window is not the content
window.

When possible, all function arguments should be listed on the same
line. If doing so would exceed the 80-column limit, the arguments
must be line-wrapped in a readable way. To save space, you may wrap
as close to 80 as possible, or put each argument on its own line to
enhance readability. The indentation may be either four spaces, or
aligned to the parenthesis. Below are the most common patterns for
argument wrapping:

When the function call is itself indented, you're free to start the
4-space indent relative to the beginning of the original statement
or relative to the beginning of the current function call.
The following are all acceptable indentation styles.

When declaring an anonymous function in the list of arguments for
a function call, the body of the function is indented two spaces
from the left edge of the statement, or two spaces from the left
edge of the function keyword. This is to make the body of the
anonymous function easier to read (i.e. not be all squished up into
the right half of the screen).

Only one goog.scope invocation may be added per
file. Always place it in the global scope.

The opening goog.scope(function() { invocation
must be preceded by exactly one blank line and follow any
goog.provide statements, goog.require
statements, or top-level comments. The invocation must be closed on
the last line in the file. Append // goog.scope to the
closing statement of the scope. Separate the comment from the
semicolon by two spaces.

Similar to C++ namespaces, do not indent under goog.scope
declarations. Instead, continue from the 0 column.

Only alias names that will not be re-assigned to another object
(e.g., most constructors, enums, and namespaces). Do not do
this (see below for how to alias a constructor):

Except for array literals,
object literals, and anonymous functions, all wrapped lines
should be indented either left-aligned to a sibling expression
above, or four spaces (not two spaces) deeper than a parent
expression (where "sibling" and "parent" refer to parenthesis
nesting level).

Always put the operator on the preceding line. Otherwise,
line breaks and indentation follow the same rules as in other
Google style guides. This operator placement was initially agreed
upon out of concerns about automatic semicolon insertion. In fact,
semicolon insertion cannot happen before a binary operator, but new
code should stick to this style for consistency.

var x = a ? b : c; // All on one line if it will fit.
// Indentation +4 is OK.
var y = a ?
longButSimpleOperandB : longButSimpleOperandC;
// Indenting to the line position of the first operand is also OK.
var z = a ?
moreComplicatedB :
moreComplicatedC;

@private global variables and functions are only
accessible to code in the same file.

Constructors marked @private may only be instantiated by
code in the same file and by their static and instance members.
@private constructors may also be accessed anywhere in the
same file for their public static properties and by the
instanceof operator.

Global variables, functions, and constructors should never be
annotated @protected.

@private properties are accessible to all code in the
same file, plus all static methods and instance methods of that class
that "owns" the property, if the property belongs to a class. They
cannot be accessed or overridden from a subclass in a different file.

@protected properties are accessible to all code in the
same file, plus any static methods and instance methods of any subclass
of a class that "owns" the property.

Note that these semantics differ from those of C++ and Java, in that
they grant private and protected access to all code in the same file,
not just in the same class or class hierarchy. Also, unlike in C++,
private properties cannot be overridden by a subclass.

Notice that in JavaScript, there is no distinction between a type
(like AA_PrivateClass_) and the constructor for that
type. There is no way to express both that a type is public and its
constructor is private (because the constructor could easily be aliased
in a way that would defeat the privacy check).

Encouraged and enforced by the compiler.

When documenting a type in JSDoc, be as specific and accurate as
possible. The types we support are based on the
EcmaScript 4 spec.

The ES4 proposal contained a language for specifying JavaScript
types. We use this language in JsDoc to express the types of
function parameters and return values.

As the ES4 proposal has evolved, this language has changed. The
compiler still supports old syntaxes for types, but those syntaxes
are deprecated.

Syntax Name

Syntax

Description

Deprecated Syntaxes

Primitive Type

There are 5 primitive types in JavaScript:
{null},
{undefined},
{boolean},
{number}, and
{string}.

Simply the name of a type.

Instance Type

{Object}
An instance of Object or null.

{Function}
An instance of Function or null.

{EventTarget}
An instance of a constructor that implements the EventTarget
interface, or null.

An instance of a constructor or interface function.

Constructor functions are functions defined with the
@constructor JSDoc tag.
Interface functions are functions defined with the
@interface JSDoc tag.

By default, instance types will accept null. This is the only
type syntax that makes the type nullable. Other type syntaxes
in this table will not accept null.

Enum Type

{goog.events.EventType}
One of the properties of the object literal initializer
of goog.events.EventType.

An enum must be initialized as an object literal, or as
an alias of another enum, annotated with the @enum
JSDoc tag. The properties of this literal are the instances
of the enum. The syntax of the enum is defined
below.

Note that this is one of the few things in our type system
that were not in the ES4 spec.

Type Application

{Array.<string>}An array of strings.

{Object.<string, number>}An object in which the keys are strings and the values
are numbers.

Parameterizes a type, by applying a set of type arguments
to that type. The idea is analogous to generics in Java.

Type Union

{(number|boolean)}A number or a boolean.

Indicates that a value might have type A OR type B.

The parentheses may be omitted at the top-level
expression, but the parentheses should be included in
sub-expressions to avoid ambiguity.{number|boolean}{function(): (number|boolean)}

{(number,boolean)},{(number||boolean)}

Nullable type

{?number} A number or null.

Shorthand for the union of the null type with any
other type. This is just syntactic sugar.

{number?}

Non-nullable type

{!Object} An Object, but never the
null value.

Filters null out of nullable types. Most often used
with instance types, which are nullable by default.

{Object!}

Record Type

{{myNum: number, myObject}}An anonymous type with the given type members.

Indicates that the value has the specified members with the
specified types. In this case, myNum with a
type number and myObject with any
type.

Notice that the braces are part of the type syntax. For
example, to denote an Array of objects that
have a length property, you might write
Array.<{length}>.

Function Type

{function(string, boolean)}
A function that takes two arguments (a string and a boolean),
and has an unknown return value.

Specifies a function.

Function Return Type

{function(): number}
A function that takes no arguments and returns a number.

Specifies a function return type.

Function this Type

{function(this:goog.ui.Menu, string)}
A function that takes one argument (a string), and executes
in the context of a goog.ui.Menu.

Specifies the context type of a function type.

Function new Type

{function(new:goog.ui.Menu, string)}
A constructor that takes one argument (a string), and
creates a new instance of goog.ui.Menu when called
with the 'new' keyword.

Specifies the constructed type of a constructor.

Variable arguments

{function(string, ...[number]): number}
A function that takes one argument (a string), and then a
variable number of arguments that must be numbers.

Specifies variable arguments to a function.

Variable arguments (in @param annotations)

@param {...number} var_args
A variable number of arguments to an annotated function.

Specifies that the annotated function accepts a variable
number of arguments.

Note that in JavaScript, the keys are always
implicitly converted to strings, so
obj['1'] == obj[1].
So the key will always be a string in for...in loops. But the
compiler will verify the type of the key when indexing into
the object.

In cases where type-checking doesn't accurately infer the type of
an expression, it is possible to add a type cast comment by adding a
type annotation comment and enclosing the expression in
parentheses. The parentheses are required.

/** @type {number} */ (x)

Because JavaScript is a loosely-typed language, it is very
important to understand the subtle differences between optional,
nullable, and undefined function parameters and class
properties.

Instances of classes and interfaces are nullable by default.
For example, the following declaration

This tells the compiler that myValue_ may hold an
Object, null, or remain undefined.

Note that the optional parameter opt_value is declared
to be of type {Object=}, not
{Object|undefined}. This is because optional
parameters may, by definition, be undefined. While there is no harm
in explicitly declaring an optional parameter as possibly undefined,
it is both unnecessary and makes the code harder to read.

Finally, note that being nullable and being optional are orthogonal
properties. The following four declarations are all different:

/**
* Takes four arguments, two of which are nullable, and two of which are
* optional.
* @param {!Object} nonNull Mandatory (must not be undefined), must not be null.
* @param {Object} mayBeNull Mandatory (must not be undefined), may be null.
* @param {!Object=} opt_nonNull Optional (may be undefined), but if present,
* must not be null!
* @param {Object=} opt_mayBeNull Optional (may be undefined), may be null.
*/
function strangeButTrue(nonNull, mayBeNull, opt_nonNull, opt_mayBeNull) {
// ...
};

Sometimes types can get complicated. A function that accepts
content for an Element might look like:

The compiler has limited support for template types. It can only
infer the type of this inside an anonymous function
literal from the type of the this argument and whether the
this argument is missing.

All files, classes, methods and properties should be documented with
JSDoc
comments with the appropriate tags
and types. Textual descriptions for properties,
methods, method parameters and method return values should be included
unless obvious from the property, method, or parameter name.

Inline comments should be of the // variety.

Complete sentences are recommended but not required.
Complete sentences should use appropriate capitalization
and punctuation.

The JSDoc syntax is based on
JavaDoc. Many tools extract metadata from JSDoc comments to
perform code validation and optimizations. These comments must be
well-formed.

/**
* A JSDoc comment should begin with a slash and 2 asterisks.
* Inline tags should be enclosed in braces like {@code this}.
* @desc Block tags should always start on their own line.
*/

If you have to line break a block tag, you should treat this as
breaking a code statement and indent it four spaces.

/**
* Illustrates line wrapping for long param/return descriptions.
* @param {string} foo This is a param with a description too long to fit in
* one line.
* @return {number} This returns something that has a description too long to
* fit in one line.
*/
project.MyClass.prototype.method = function(foo) {
return 5;
};

You should not indent the @fileoverview command. You do not have to
indent the @desc command.

Even though it is not preferred, it is also acceptable to line up
the description.

/**
* This is NOT the preferred indentation method.
* @param {string} foo This is a param with a description too long to fit in
* one line.
* @return {number} This returns something that has a description too long to
* fit in one line.
*/
project.MyClass.prototype.method = function(foo) {
return 5;
};

A copyright notice and author information are optional.
File overviews are generally recommended whenever a file consists of
more than a single class definition. The top level comment is
designed to orient readers unfamiliar with the code to what is in
this file. If present, it should provide a description of the
file's contents and any dependencies or compatibility information.
As an example:

/**
* @fileoverview Description of file, its uses and information
* about its dependencies.
*/

Parameter and return types should be documented. The method
description may be omitted if it is obvious from the parameter
or return type descriptions. Method descriptions should start
with a sentence written in the third person declarative voice.

/**
* Moves to the next position in the selection.
* Throws {@code goog.iter.StopIteration} when it
* passes the end of the range.
* @return {Node} The node at the next position.
*/
goog.dom.RangeIterator.prototype.next = function() {
// ...
};

Indicates that a term in a JSDoc description is code so it may
be correctly formatted in generated documentation.

Indicates a constant that can be overridden by the compiler at
compile-time. In the example, the compiler flag
--define='goog.userAgent.ASSUME_IE=true'
could be specified in the BUILD file to indicate that the
constant goog.userAgent.ASSUME_IE should be replaced
with true.

When a constructor (Foo in the example) is
annotated with @dict, you can only use the
bracket notation to access the properties of Foo
objects.
The annotation can also be used directly on object literals.

Declares an exposed property. Exposed properties
will not be removed, or renamed, or collapsed,
or optimized in any way by the compiler. No properties
with the same name will be able to be optimized either.

@expose should never be used in library code,
because it will prevent that property from ever getting
removed.

Indicates that the keys of an object literal should
be treated as properties of some other object. This annotation
should only appear on object literals.

Notice that the name in braces is not a type name like
in other annotations. It's an object name. It names
the object on which the properties are "lent".
For example, @type {Foo} means "an instance of Foo",
but @lends {Foo} means "the constructor Foo".

/**
* @preserve Copyright 2009 SomeThirdParty.
* Here is the full license text and copyright
* notice for this file. Note that the notice can span several
* lines and is only terminated by the closing star and slash:
*/

Anything marked by @license or
@preserve will be retained by the compiler and
output at the top of the compiled code for that file. This
annotation allows important notices (such as legal licenses or
copyright text) to survive compilation unchanged. Line breaks
are preserved.

Used at the top of a file to tell the compiler to parse this
file but not compile it.
Code that is not meant for compilation and should be omitted
from compilation tests (such as bootstrap code) uses this
annotation.
Use sparingly.

This annotation can be used as part of function and
constructor declarations to indicate that calls to the
declared function have no side-effects. This annotation
allows the compiler to remove calls to these functions if the
return value is not used.

Indicates that a method or property of a subclass
intentionally hides a method or property of the superclass. If
no other documentation is included, the method or property
also inherits documentation from its superclass.

Used to indicate that the member or property is public. Variables and
properties are public by default, so this annotation is rarely necessary.
Should only be used in legacy code that cannot be easily changed to
override the visibility of members that were named as private variables.

Used with method and function calls to document the return
type. When writing descriptions for boolean parameters,
prefer "Whether the component is visible" to "True if the
component is visible, false otherwise". If there is no return
value, do not use an @return tag.

Type
names must be enclosed in curly braces. If the type
is omitted, the compiler will not type-check the return value.

When a constructor (Foo in the example) is
annotated with @struct, you can only use the dot
notation to access the properties of Foo objects.
Also, you cannot add new properties to Foo
objects after they have been created.
The annotation can also be used directly on object literals.

This annotation can be used to declare an alias of a more
complex type.

You may also see other types of JSDoc annotations in third-party
code. These annotations appear in the
JSDoc Toolkit Tag Reference
but are currently discouraged in Google code. You should consider
them "reserved" names for future use. These include:

@augments

@argument

@borrows

@class

@constant

@constructs

@default

@event

@example

@field

@function

@ignore

@inner

@link

@memberOf

@name

@namespace

@property

@public

@requires

@returns

@since

@static

@version

Only provide top-level symbols.

All members defined on a class should be in the same file. So, only
top-level classes should be provided in a file that contains multiple
members defined on the same class (e.g. enums, inner classes, etc).

If you're editing code, take a few minutes to look at the code
around you and determine its style. If they use spaces around
all their arithmetic operators, you should too. If their
comments have little boxes of hash marks around them, make your
comments have little boxes of hash marks around them too.

The point of having style guidelines is to have a common vocabulary
of coding so people can concentrate on what you're saying rather
than on how you're saying it. We present global style rules here so
people know the vocabulary, but local style is also important. If
code you add to a file looks drastically different from the existing
code around it, it throws readers out of their rhythm when they go to
read it. Avoid this.