From 3e9c70e6c39c594389bbced884d7365b05cc98cd Mon Sep 17 00:00:00 2001
From: Mike Frysinger
The term comment always refers to implementation comments. We do not use
the phrase documentation comments
, instead using the common term “JSDoc”
-for both human-readable text and machine-readable annotations within
-/** … */.
/** …
+*/.
This Style Guide uses RFC 2119 terminology when using the phrases must, -must not, should, should not, and may. The terms prefer and -avoid correspond to should and should not, respectively. Imperative +must not, should, should not, and may. The terms prefer and +avoid correspond to should and should not, respectively. Imperative and declarative statements are prescriptive and correspond to must.
.js.
Aside from the line terminator sequence, the ASCII horizontal space character -(0x20) is the only whitespace character that appears anywhere in a source -file. This implies that
+(0x20) is the only whitespace character that appears anywhere in a source file. +This implies thatAll other whitespace characters in string literals are escaped, and
All new source files should either be a goog.module file (a file containing a
-goog.module call) or an ECMAScript (ES) module (uses import and export
-statements). Files consist of the following, in order:
All new source files should either be a goog.module
+file (a file containing a goog.module call) or an ECMAScript (ES) module (uses
+import and export statements).
Files consist of the following, in order:
goog.module declaration must not be wrapped, and are
therefore an exception to the 80-column limit.
-The entire argument to goog.module is what defines a namespace. It is the +
The entire argument to goog.module is what defines a namespace. It is the
package name (an identifier that reflects the fragment of the directory
structure where the code lives) plus, optionally, the main class/enum/interface
-that it defines concatenated to the end.
lowerCamelCase.
-Example
+Example:
-goog.module('search.urlHistory.UrlHistoryService');
+goog.module('search.urlHistory.urlHistoryService');
3.3.1 Hierarchy
@@ -161,7 +163,7 @@ goog.module('foo.bar.baz');
The directory hierarchy reflects the namespace hierarchy, so that deeper-nested -children are subdirectories of higher-level parent directories. Note that this +children are subdirectories of higher-level parent directories. Note that this implies that owners of “parent” namespace groups are necessarily aware of all child namespaces, since they exist in the same directory.
@@ -186,15 +188,14 @@ namespace, this name must not be a child or parent of any othergoog.module('parent.child'); cannot both exist safely, nor can
goog.module('parent'); and goog.module('parent.child.grandchild');).
-goog.module Exportsgoog.module ExportsClasses, enums, functions, constants, and other symbols are exported using the
exports object. Exported symbols may be defined directly on the exports
object, or else declared locally and exported separately. Symbols are only
exported if they are meant to be used outside the module. Non-exported
-module-local symbols are not declared @private nor do their names end with an
-underscore. There is no prescribed ordering for exported and module-local
-symbols.
@private. There is no prescribed
+ordering for exported and module-local symbols.
Examples:
@@ -229,10 +230,18 @@ constant by the compiler. exports = {exportedFunction}; +Do not use default exports as they don't translate easily to ES module +semantics.
+ +exports = FancyClass;
+
+
ES modules are files that use the import and export keywords.
Some libraries might commonly use a namespace import prefix that violates this
+naming scheme, but overbearingly common open source use makes the violating
+style more readable. The only library that currently falls under this exception
+is threejs, using the THREE prefix.
Default import names are derived from the imported file name and follow the @@ -340,9 +354,8 @@ new DomesticatedCat();
Symbols are only exported if they are meant to be used outside the module.
-Non-exported module-local symbols are not declared @private nor do their names
-end with an underscore. There is no prescribed ordering for exported and
-module-local symbols.
@private. There is no
+prescribed ordering for exported and module-local symbols.
Do not export container classes or objects with static methods or properties for -the sake of namespacing.
- -// container.js
-// Bad: Container is an exported class that has only static methods and fields.
-export class Container {
- /** @return {number} */
- static bar() {
- return 1;
- }
-}
-
-/** @const {number} */
-Container.FOO = 1;
-
-
-Instead, export individual constants and functions:
- -/** @return {number} */
-export function bar() {
- return 1;
-}
-
-export const /** number */ FOO = 1;
-
-
-
Exported variables must not be mutated outside of module initialization.
@@ -429,7 +414,7 @@ export function setMutateFoo(newMutateFoo) { // instead make them module scoped and export a getter for foo and a wrapper for // mutateFooFunc. let /** number */ foo = 0; -let /** function(number): number */ mutateFooFunc = foo => foo + 1; +let /** function(number): number */ mutateFooFunc = (foo) => foo + 1; /** @return {number} */ export function getFoo() { @@ -448,7 +433,7 @@ export function setMutateFoo(mutateFoo) {-
export from statements must not be line wrapped and are therefore an
exception to the 80-column limit. This applies to both export from flavors.
import * as goog from '../closure/goog/goog.js';
-const name = goog.require('a.name');
+const {compute} = goog.require('a.name');
-export const CONSTANT = name.compute();
+export const CONSTANT = compute();
goog.js exports only a subset of properties from the global goog that can be
@@ -521,7 +506,7 @@ const myNamespace = goog.require('my.namespace');
goog.declareModuleId can be used within ES modules to declare a
goog.module-like module ID. This means that this module ID can be
-goog.required, goog.module.getd, goog.forwardDeclare'd, etc. as if it were
+goog.required, goog.module.getd etc. as if it were
a goog.module that did not call goog.module.declareLegacyNamespace. It does
not create the module ID as a globally available JavaScript symbol.
goog.setTestOnlyIn a goog.module file the goog.module statement may optionally be followed
-by a call to goog.setTestOnly().
In a goog.module file the goog.module statement and, if present,
+goog.module.declareLegacyNamespace() statement may optionally be followed by a
+call to goog.setTestOnly().
In an ES module the import statements may optionally be followed by a call to
-goog.setTestOnly().
In an ES module the import statements may optionally be
+followed by a call to goog.setTestOnly().
goog.require and goog.requireType statementsImports are done with goog.require and goog.requireType statements. The
names imported by a goog.require statement may be used both in code and in
-type annotations, while those imported by a goog.requireType may be used
-in type annotations only.
goog.requireType may be used in
+type annotations only.
The goog.require and goog.requireType statements form a contiguous block
with no empty lines. This block follows the goog.module declaration separated
@@ -575,8 +561,8 @@ qualified namespaces must not be used anywhere, except as an argument to
Exception: Types, variables, and functions declared in externs files have to use their fully qualified name in type annotations and code.
-Aliases must match the final dot-separated component of the imported module's -namespace.
+When goog.require is assigned to a single constant alias, it must match the
+final dot-separated component of the imported module's namespace.
Exception: In certain cases, additional components of the namespace can be
used to form a longer alias. The resulting alias must retain the original
@@ -584,8 +570,9 @@ identifier's casing such that it still correctly identifies its type. Longer
aliases may be used to disambiguate otherwise identical aliases, or if it
significantly improves readability. In addition, a longer alias must be used to
prevent masking native types such as Element, Event, Error, Map, and
-Promise (for a more complete list, see Standard Built-in Objects and Web
-APIs at MDN). When renaming destructured aliases, a space must follow the colon
+Promise (for a more complete list, see Standard Built-in Objects and
+Web APIs at MDN).
A file should not contain both a goog.require and a goog.requireType
@@ -616,26 +603,24 @@ limit.
Example:
// Standard alias style.
-const MyClass = goog.require('some.package.MyClass');
-const MyType = goog.requireType('some.package.MyType');
-// Namespace-based alias used to disambiguate.
-const NsMyClass = goog.require('other.ns.MyClass');
-// Namespace-based alias used to prevent masking native type.
-const RendererElement = goog.require('web.renderer.Element');
-// Out of sequence namespace-based aliases used to improve readability.
-// Also, require lines longer than 80 columns must not be wrapped.
-const SomeDataStructureModel = goog.requireType('identical.package.identifiers.models.SomeDataStructure');
-const SomeDataStructureProto = goog.require('proto.identical.package.identifiers.SomeDataStructure');
-// Standard alias style.
const asserts = goog.require('goog.asserts');
// Namespace-based alias used to disambiguate.
const testingAsserts = goog.require('goog.testing.asserts');
// Standard destructuring into aliases.
+const {MyClass} = goog.require('some.package');
+const {MyType} = goog.requireType('other.package');
const {clear, clone} = goog.require('goog.array');
const {Rgb} = goog.require('goog.color');
-// Namespace-based destructuring into aliases in order to disambiguate.
+// Namespace-based destructuring into aliases used to disambiguate.
+const {MyClass: NsMyClass} = goog.require('other.ns');
const {SomeType: FooSomeType} = goog.requireType('foo.types');
const {clear: objectClear, clone: objectClone} = goog.require('goog.object');
+// Namespace-based destructuring into aliases used to prevent masking native type.
+const {Element: RendererElement} = goog.require('web.renderer');
+// Out of sequence namespace-based aliases used to improve readability.
+// Also, require lines longer than 80 columns must not be wrapped.
+const {SomeDataStructure: SomeDataStructureModel} = goog.requireType('identical.package.identifiers.models');
+const {SomeDataStructure: SomeDataStructureProto} = goog.require('proto.identical.package.identifiers');
// goog.require without an alias in order to trigger side effects.
/** @suppress {extraRequire} Initializes MyFramework. */
goog.require('my.framework.initialization');
@@ -643,6 +628,13 @@ goog.require('my.framework.initialization');
Discouraged:
+// Some legacy code uses a "default export" style to export a single class, enum,
+// record type, etc. Do not use this pattern in new JS.
+// When using a "default export", prefer destructuring into aliases.
+const MyClass = goog.require('some.package.MyClass');
+const MyType = goog.requireType('some.package.MyType');
+
+
// If necessary to disambiguate, prefer PackageClass over SomeClass as it is
// closer to the format of the module name.
const SomeClass = goog.require('some.package.Class');
@@ -684,20 +676,18 @@ function someFunction(param) {
(separated by at least one blank line).
This may consist of any module-local declarations (constants, variables,
-classes, functions, etc), as well as any exported symbols.
-
+classes, functions, etc), as well as any exported symbols.
4 Formatting
Terminology Note: block-like construct refers to the body of a class,
-function, method, or brace-delimited block of code. Note that, by
+function, method, or brace-delimited block of code. Note that, by
?? and ??, any array or
object literal may optionally be treated as if it were a block-like construct.
Tip: Use clang-format. The JavaScript community has invested effort to make
sure clang-format does the right thing
on JavaScript files. clang-format has
-integration with several popular
-editors.
+integration with several popular editors.
4.1 Braces
@@ -705,7 +695,7 @@ editors.
Braces are required for all control structures (i.e. if, else, for, do,
while, as well as any others), even if the body contains only a single
-statement. The first statement of a non-empty block must begin on its own line.
+statement. The first statement of a non-empty block must begin on its own line.
Disallowed:
@@ -717,7 +707,7 @@ for (let i = 0; i < foo.length; i++) bar(foo[i]);
Exception: A simple if statement that can fit entirely on a single line with
no wrapping (and that doesn’t have an else) may be kept on a single line with no
-braces when it improves readability. This is the only case in which a control
+braces when it improves readability. This is the only case in which a control
structure may omit braces and newlines.
if (shortCondition()) foo();
@@ -734,8 +724,8 @@ structure may omit braces and newlines.
- Line break before the closing brace.
- Line break after the closing brace if that brace terminates a statement or
the body of a function or class statement, or a class method. Specifically,
-there is no line break after the brace if it is followed by
else, catch,
-while, or a comma, semicolon, or right-parenthesis.
+there is no line break after the brace if it is followed by else,
+catch, while, or a comma, semicolon, or right-parenthesis.
Example:
@@ -786,8 +776,8 @@ try {
Each time a new block or block-like construct is opened, the indent increases by
two spaces. When the block ends, the indent returns to the previous indent
-level. The indent level applies to both code and comments throughout the
-block. (See the example in ??).
+level. The indent level applies to both code and comments throughout the block.
+(See the example in ??).
4.2.1 Array literals: optionally block-like
@@ -844,38 +834,44 @@ someMethod(foo, {
Class literals (whether declarations or expressions) are indented as blocks. Do
not add semicolons after methods, or after the closing brace of a class
declaration (statements—such as assignments—that contain class expressions
-are still terminated with a semicolon). Use the extends keyword, but not the
-@extends JSDoc annotation unless the class extends a templatized type.
+are still terminated with a semicolon). For inheritance, the extends keyword
+is sufficient unless the superclass is templatized. Subclasses of templatized
+types must explicitly specify the template type in an @extends JSDoc
+annotation, even if it is just passing along the same template name.
Example:
-class Foo {
- constructor() {
- /** @type {number} */
- this.x = 42;
+/** @template T */
+class Foo {
+ /** @param {T} x */
+ constructor(x) {
+ /** @type {T} */
+ this.x = x;
}
+}
+/** @extends {Foo<number>} */
+class Bar extends Foo {
+ constructor() {
+ super(42);
+ }
+}
+
+exports.Baz = class extends Bar {
/** @return {number} */
method() {
return this.x;
}
-}
-Foo.Empty = class {};
+};
-/** @extends {Foo<string>} */
-foo.Bar = class extends Foo {
- /** @override */
+/** @extends {Bar} */ // <-- unnecessary @extends
+exports.Baz = class extends Bar {
+ /** @return {number} */
method() {
- return super.method() / 2;
+ return this.x;
}
};
-
-/** @interface */
-class Frobnicator {
- /** @param {string} message */
- frobnicate(message) {}
-}
4.2.4 Function expressions
@@ -1020,6 +1016,11 @@ operator.
- A method or constructor name stays attached to the open parenthesis (
()
that follows it.
- A comma (
,) stays attached to the token that precedes it.
+- A line break is never added between a return and the return value as this
+would change the meaning of the code.
+- JSDoc annotations with type names break after
{
. This is necessary as
+annotations with optional types (@const, @private, @param, etc) do not scan
+the next line.
@@ -1034,7 +1035,7 @@ indented at least +4 from the original line, unless it falls under the rules of block indentation.When there are multiple continuation lines, indentation may be varied beyond +4 -as appropriate. In general, continuation lines at a deeper syntactic level are +as appropriate. In general, continuation lines at a deeper syntactic level are indented by larger multiples of 4, and two lines use the same indentation level if and only if they begin with syntactically parallel elements.
@@ -1050,8 +1051,8 @@ using a variable number of spaces to align certain tokens with previous lines.
- Between consecutive methods in a class or object literal
-
- Exception: A blank line between two consecutive properties definitions in -an object literal (with no other code between them) is optional. Such +
- Exception: A blank line between two consecutive properties definitions +in an object literal (with no other code between them) is optional. Such blank lines are used as needed to create logical groupings of fields.
- Within method bodies, sparingly to create logical groupings of statements. @@ -1069,8 +1070,8 @@ encouraged).
variable number of additional spaces in your code with the goal of making certain tokens appear directly below certain other tokens on previous lines. -Use of horizontal whitespace depends on location, and falls into three broad categories: leading (at the start of a line), trailing (at the end of a -line), and internal. Leading whitespace (i.e., indentation) is addressed -elsewhere. Trailing whitespace is forbidden.
+line), and internal. Leading whitespace (i.e., indentation) is addressed +elsewhere. Trailing whitespace is forbidden.Beyond where required by the language or other style rules, and apart from literals, comments, and JSDoc, a single internal ASCII space also appears in the @@ -1107,11 +1108,11 @@ Here, multiple spaces are allowed, but not required.
This practice is permitted, but it is generally discouraged by Google -Style. It is not even required to maintain horizontal alignment in places -where it was already used.
+This practice is permitted, but it is generally discouraged by Google Style. +It is not even required to maintain horizontal alignment in places where it +was already used.
-Here is an example without alignment, followed by one with alignment. Both are +
Here is an example without alignment, followed by one with alignment. Both are allowed, but the latter is discouraged:
{ @@ -1127,16 +1128,21 @@ allowed, but the latter is discouraged:Tip: Alignment can aid readability, but it creates problems for future maintenance. Consider a future change that needs to touch just one line. This -change may leave the formerly-pleasing formatting mangled, and that is -allowed. More often it prompts the coder (perhaps you) to adjust whitespace on -nearby lines as well, possibly triggering a cascading series of -reformattings. That one-line change now has a
+change may leave the formerly-pleasing formatting mangled, and that is allowed. +More often it prompts the coder (perhaps you) to adjust whitespace on nearby +lines as well, possibly triggering a cascading series of reformattings. That +one-line change now has ablast radius.This can at worst -result in pointless busywork, but at best it still corrupts version history -information, slows down reviewers and exacerbates merge conflicts.blast radius.This can at worst result in pointless +busywork, but at best it still corrupts version history information, slows down +reviewers and exacerbates merge conflicts.4.6.4 Function arguments
-Prefer to put all function arguments on the same line as the function name. 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. Indentation should be four spaces. Aligning to the parenthesis is allowed, but discouraged. Below are the most common patterns for argument wrapping:
+Prefer to put all function arguments on the same line as the function name. 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. Indentation should be four +spaces. Aligning to the parenthesis is allowed, but discouraged. Below are the +most common patterns for argument wrapping:
// Arguments start on a new line, indented four spaces. Preferred when the // arguments don't fit on the same line with the function name (or the keyword @@ -1223,17 +1229,20 @@ Their preferred format is before the value with=:5 Language features
-JavaScript includes many dubious (and even dangerous) features. This section +
JavaScript includes many dubious (and even dangerous) features. This section delineates which features may or may not be used, and any additional constraints on their use.
+Language features which are not discussed in this style guide may be used with +no recommendations of their usage.
+5.1 Local variable declarations
5.1.1 Use
-constandletDeclare all local variables with either
+constorlet. Use const by default, -unless a variable needs to be reassigned. Thevar-keyword must not be used.Declare all local variables with either
constorlet. Useconstby +default, unless a variable needs to be reassigned. Thevarkeyword +must not be used.5.1.2 One variable per declaration
@@ -1244,7 +1253,8 @@ aslet a = 1, b = 2;are not used.Local variables are not habitually declared at the start of their containing block or block-like construct. Instead, local variables are declared close to -the point they are first used (within reason), to minimize their scope.
+the point they are first used (within reason), to minimize their scope, and +initialized as soon as possible.5.1.4 Declare types as needed
@@ -1270,10 +1280,10 @@ const /** !Array<number> */ data = [];Tip: There are many cases where the compiler can infer a templatized type but -not its parameters. This is particularly the case when the initializing literal +not its parameters. This is particularly the case when the initializing literal or constructor call does not include any values of the template parameter type (e.g., empty arrays, objects,
Maps, orSets), or if the variable is modified -in a closure. Local variable type annotations are particularly helpful in these +in a closure. Local variable type annotations are particularly helpful in these cases since otherwise the compiler will infer the template parameter as unknown.5.2 Array literals
@@ -1324,14 +1334,14 @@ allowed when appropriate.5.2.3 Non-numeric properties
-Do not define or use non-numeric properties on an array (other than -
+length). Use aMap(orObject) instead.Do not define or use non-numeric properties on an array (other than
length). +Use aMap(orObject) instead.5.2.4 Destructuring
Array literals may be used on the left-hand side of an assignment to perform destructuring (such as when unpacking multiple values from a single array or -iterable). A final
restelement may be included (with no space between the +iterable). A finalrestelement may be included (with no space between the...and the variable name). Elements should be omitted if they are unused.const [a, b, c, ...rest] = generateResults(); @@ -1359,8 +1369,8 @@ naming the individual elements and specifying a different type for each.5.2.5 Spread operator
Array literals may include the spread operator (
...) to flatten elements out -of one or more other iterables. The spread operator should be used instead of -more awkward constructs withArray.prototype. There is no space after the +of one or more other iterables. The spread operator should be used instead of +more awkward constructs withArray.prototype. There is no space after the....Example:
@@ -1484,11 +1494,12 @@ to perform destructuring and unpack multiple values from a single object.Destructured objects may also be used as function parameters, but should be kept as simple as possible: a single level of unquoted shorthand properties. Deeper levels of nesting and computed properties may not be used in parameter -destructuring. Specify any default values in the left-hand-side of the -destructured parameter (
+destructuring. Specify any default values in the left-hand-side of the +destructured parameter ({str = 'some default'} = {}, rather than{str} = {str: 'some default'}), and if a destructured -object is itself optional, it must default to{}. The JSDoc for the -destructured parameter may be given any name (the name is unused but is required -by the compiler).{str = 'some default'} = {}, rather than +{str} = {str: 'some default'}), and if a +destructured object is itself optional, it must default to{}. The JSDoc for +the destructured parameter may be given any name (the name is unused but is +required by the compiler).Example:
@@ -1498,7 +1509,7 @@ by the compiler). * num: The number of times to do something. * str: A string to do stuff to. */ -function destructured(ordinary, {num, str = 'some default'} = {}) +function destructured(ordinary, {num, str = 'some default'} = {}) {}Disallowed:
@@ -1520,8 +1531,11 @@ long it is (see ??).5.3.8 Enums
Enumerations are defined by adding the
+Enums must be module-local or assigned directly on@enumannotation to an object literal. -Additional properties may not be added to an enum after it is defined. Enums -must be constant, and all enum values must be deeply immutable.exports, not nested under a +type or object. + +Additional properties may not be added to an enum after it is defined. Enums +must be constant. All enum values must be either a string literal or a number.
+/** * Supported temperature scales. @@ -1533,17 +1547,41 @@ const TemperatureScale = { }; /** - * An enum with two options. + * An enum with two values. * @enum {number} */ -const Option = { - /** The option used shall have been the first. */ - FIRST_OPTION: 1, - /** The second among two options. */ - SECOND_OPTION: 2, +const Value = { + /** The value used shall have been the first. */ + FIRST_VALUE: 1, + /** The second among two values. */ + SECOND_VALUE: 2, };For string enums, all values must be statically initialized and not computed +using arithmetic operators, template literal substitution, function calls or +even a variable reference.
+ ++ +const ABSOLUTE_ZERO = '-273°F'; + +/** + * Not supported computed values in string enum. + * @enum {string} + */ +const TemperatureInFahrenheit = { + MIN_POSSIBLE: ABSOLUTE_ZERO, + ZERO_FAHRENHEIT: 0 + '°F', + ONE_FAHRENHEIT: `${Values.FIRST_VALUE}°F`, + TWO_FAHRENHEIT: Values.SECOND_VALUE + '°F', + SOME_FAHRENHEIT: getTemperatureInFahrenheit() + '°F', +}; +Note: Although TypeScript supports a few more patterns for enum values (e.g
+A: +'a'+'b', etc), the restriction of only allowing string literals and numbers for +enum values is to aid migration to TypeScript. For complex values consider using +a const object without@enum.5.4 Classes
5.4.1 Constructors
@@ -1554,12 +1592,13 @@ non-method properties in the constructor.5.4.2 Fields
-Set all of a concrete object’s fields (i.e. all properties other than methods) -in the constructor. Annotate fields that are never reassigned with
+@const-(these need not be deeply immutable). Annotate non-public fields with the proper -visibility annotation (@private,@protected,@package), and end all -@privatefields' names with an underscore. Fields are never set on a concrete -class'prototype.Define all of a concrete object’s fields (i.e. all properties other than +methods) in the constructor. Annotate fields that are never reassigned with +
@const(these need not be deeply immutable). Annotate non-public fields with +the proper visibility annotation (@private,@protected,@package). +@privatefields' names may optionally end with an underscore. Fields must not +be defined within a nested scope in the constructor nor on a concrete class's +prototype.Example:
@@ -1576,22 +1615,24 @@ class'prototype.Tip: Properties should never be added to or removed from an instance after the constructor is finished, since it significantly hinders VMs’ ability to -optimize. If necessary, fields that are initialized later should be explicitly +optimize. If necessary, fields that are initialized later should be explicitly set to
+added/accessed. Classes have this added by default.undefinedin the constructor to prevent later shape changes. Adding@structto an object will check that undeclared properties are not -added/accessed. Classes have this added by default.5.4.3 Computed properties
-Computed properties may only be used in classes when the property is a -symbol. Dict-style properties (that is, quoted or computed non-symbol keys, as -defined in ??) are not allowed. A -
+[Symbol.iterator]method should be defined for any classes that are logically -iterable. Beyond this,Symbolshould be used sparingly.Computed properties may only be used in classes when the property is a symbol. +Dict-style properties (that is, quoted or computed non-symbol keys, as defined +in ??) are not allowed. A
-[Symbol.iterator]+method should be defined for any classes that are logically iterable. Beyond +this,Symbolshould be used sparingly.Tip: be careful of using any other built-in symbols (e.g.,
+Symbol.isConcatSpreadable) as they are not polyfilled by the compiler and will therefore not work in older browsers.Tip: be careful of using any other built-in symbols (e.g., +
Symbol.isConcatSpreadable) as they are not polyfilled by the compiler and will +therefore not work in older browsers.5.4.4 Static methods
@@ -1600,24 +1641,41 @@ iterable. Beyond this,Symbolshould be used sparingly.Where it does not interfere with readability, prefer module-local functions over private static methods.
-Static methods should only be called on the base class itself. Static methods -should not be called on variables containing a dynamic instance that may be -either the constructor or a subclass constructor (and must be defined with -
+@nocollapseif this is done), and must not be called directly on a subclass -that doesn’t define the method itself.Code should not rely on dynamic dispatch of static methods, because it +interferes with Closure Compiler optimizations. Static methods should only be +called on the base class itself. Static methods should not be called on +variables containing a dynamic instance that may be either the constructor or a +subclass constructor (and must be defined with
@nocollapseif this is done), +and must not be called directly on a subclass that doesn’t define the method +itself. Do not accessthisin static methods.Disallowed:
--class Base { /** @nocollapse */ static foo() {} } +// Context for the examples below; by itself this code is allowed. +class Base { + /** @nocollapse */ static foo() {} +} class Sub extends Base {} -function callFoo(cls) { cls.foo(); } // discouraged: don't call static methods dynamically -Sub.foo(); // Disallowed: don't call static methods on subclasses that don't define it themselves + +// discouraged: don't call static methods dynamically +function callFoo(cls) { cls.foo(); } + +// Disallowed: don't call static methods on subclasses that don't define it themselves +Sub.foo(); + +// Disallowed: don't access this in static methods. +class Clazz { + static foo() { + return this.staticField; + } +} +Class.staticField = 1;5.4.5 Old-style class declarations
While ES6 classes are preferred, there are cases where ES6 classes may not be -feasible. For example:
+feasible. For example:
If there exist or will exist subclasses, including frameworks that create @@ -1625,8 +1683,8 @@ subclasses, that cannot be immediately changed to use ES6 class syntax. If such a class were to use ES6 syntax, all downstream subclasses not using ES6 class syntax would need to be modified.
- +constructor, since constructors with ES6 super classes do not have access to +the instance
Frameworks that require a known
thisvalue before calling the superclass -constructor, since constructors with ES6 super classes do not have -access to the instancethisvalue until the call tosuperreturns.thisvalue until the call tosuperreturns.In all other ways the style guide still applies to this code:
let,const, @@ -1679,9 +1737,13 @@ C.prototype.method = function(param) { };Per-instance properties should be defined in the constructor after the call to the super class constructor, if there is a super class. Methods should be defined on the prototype of the constructor.
+Per-instance properties should be defined in the constructor after the call to +the super class constructor, if there is a super class. Methods should be +defined on the prototype of the constructor.
-Defining constructor prototype hierarchies correctly is harder than it first appears! For that reason, it is best to use
+goog.inheritsfrom the Closure Library .Defining constructor prototype hierarchies correctly is harder than it first +appears! For that reason, it is best to use
goog.inheritsfrom +the Closure Library .5.4.6 Do not manipulate
@@ -1691,21 +1753,21 @@ manipulating these objects, though they are still useful for defining classes as defined in ??. Mixins and modifying the prototypes of builtin objects are explicitly forbidden. -prototypes directlyException: Framework code (such as Polymer, or Angular) may need to use
+prototypes, and should not -resort to even-worse workarounds to avoid doing so.Exception: Framework code (such as Polymer, or Angular) may need to use
prototypes, and should not resort +to even-worse workarounds to avoid doing so.5.4.7 Getters and Setters
-Do not use JavaScript getter and setter properties. They are potentially +
Do not use JavaScript getter and setter properties. They are potentially surprising and difficult to reason about, and have limited support in the -compiler. Provide ordinary methods instead.
+compiler. Provide ordinary methods instead.Exception: there are situations where defining a getter or setter is unavoidable (e.g. data binding frameworks such as Angular and Polymer, or for -compatibility with external APIs that cannot be adjusted). In these cases only, +compatibility with external APIs that cannot be adjusted). In these cases only, getters and setters may be used with caution, provided they are defined with the
getandsetshorthand method keywords orObject.defineProperties(not -Object.defineProperty, which interferes with property renaming). Getters +Object.defineProperty, which interferes with property renaming). Getters must not change observable state.Disallowed:
@@ -1729,8 +1791,9 @@ exceptional conditions could lead to infinite loops. with@recordcan be explicitly (i.e. via@implements) or implicitly implemented by a class or object literal. -All non-static method bodies on an interface must be empty blocks. Fields must -be declared as uninitialized members in the class constructor.
+All methods on an interface must be non-static and method bodies must be empty +blocks. Fields must be declared as uninitialized members in the class +constructor.
Example:
@@ -1756,8 +1819,96 @@ class Frobnicator {5.4.10 Abstract Classes
Use abstract classes when appropriate. Abstract classes and methods must be -annotated with
+annotated with@abstract. Do not usegoog.abstractMethod. See abstract -classes and methods.@abstract. Do not usegoog.abstractMethod. See +abstract classes and methods. + +5.4.11 Do not create static container classes
+ +Do not use container classes with only static methods or properties for the sake +of namespacing.
+ ++ +// container.js +// Bad: Container is an exported class that has only static methods and fields. +class Container { + /** @return {number} */ + static bar() { + return 1; + } +} + +/** @const {number} */ +Container.FOO = 1; + +exports = {Container}; +Instead, export individual constants and functions:
+ ++ +/** @return {number} */ +exports.bar = () => { + return 1; +} + +/** @const {number} */ +exports.FOO = 1; +5.4.12 Do not define nested namespaces
+ +Do not define a nested type (e.g. class, typedef, enum, interface) on another +module-local name.
+ ++ +// foo.js +goog.module('my.namespace'); + +class Foo {...} + +Foo.Bar = class {...}; + +/** @enum {number} */ +Foo.Baz = {...}; + +/** @typedef {{value: number}} */ +Foo.Qux; + +/** @interface */ +Foo.Quuz = class {...} + +exports.Foo = Foo; +These values should be top-level exports. Choose clear names for these values +(e.g. FooConverter for a Converter that could have been nested on Foo). However, +when the module name is redundant with part of the class name, consider omitting +the redundancy:
+ +foo.Fooandfoo.Converterrather thanfoo.Fooand +foo.FooConverter. Importers can add the prefix when necessary for clarity +(e.g.import {Converter as FooConverter} from './foo';) but cannot easily +remove the redundancy when importing the entire module as a namespace.// foo.js +goog.module('my.namespace'); + +class Foo {...} + +class FooBar {...} + +/** @enum {string} */ +let FooBaz = {...}; + +/** @typedef {{value: number}} */ +let FooQux; + +/** @interface */ +class FooQuuz {...}; + +export = { + Foo, + FooBar, + FooBaz, + FooQux, + FooQuuz, +}; +5.5 Functions
@@ -1785,15 +1936,14 @@ exports = {processString};5.5.2 Nested functions and closures
-Functions may contain nested function definitions. If it is useful to give the +
Functions may contain nested function definitions. If it is useful to give the function a name, it should be assigned to a local
const.5.5.3 Arrow functions
Arrow functions provide a concise function syntax and simplify scoping
+for nested functions. Prefer arrow functions over thethis-for nested functions. Prefer arrow functions over thefunctionkeyword, -particularly for nested functions (but see -??).functionkeyword for +nested functions (but see ??).Prefer arrow functions over other
thisscoping approaches such asf.bind(this),goog.bind(f, this), andconst self = this. Arrow functions @@ -1863,7 +2013,7 @@ const moduleLocalFunc = () => anotherFunction();Generators enable a number of useful abstractions and may be used as needed.
When defining generator functions, attach the
*to thefunctionkeyword when -present, and separate it with a space from the name of the function. When using +present, and separate it with a space from the name of the function. When using delegating yields, attach the*to theyieldkeyword.Example:
@@ -1922,8 +2072,8 @@ class MyInterface {Use default parameters sparingly. Prefer destructuring (as in -??) to create readable APIs when there -are more than a small handful of optional parameters that do not have a natural +??) to create readable APIs when there are +more than a small handful of optional parameters that do not have a natural order.
Note: Unlike Python's default parameters, it is okay to use initializers that @@ -1941,7 +2091,7 @@ coupling between function calls.
Use a rest parameter instead of accessing
arguments. Rest parameters are typed with a...prefix in their JSDoc. The rest parameter must be the last parameter in the list. There is no space between the...and the parameter -name. Do not name the rest parametervar_args. Never name a local variable or +name. Do not name the rest parametervar_args. Never name a local variable or parameterarguments, which confusingly shadows the built-in name.Example:
@@ -1960,9 +2110,9 @@ the JSDoc above the function or method definition.5.5.7 Spread operator
-Function calls may use the spread operator (
...). Prefer the spread operator +Function calls may use the spread operator (
+multiple parameters of a variadic function. There is no space after the...). Prefer the spread operator toFunction.prototype.applywhen an array or iterable is unpacked into -multiple parameters of a variadic function. There is no space after the........Example:
@@ -2026,37 +2176,37 @@ after the slash, and is less obvious to readers.5.7 Number literals
-Numbers may be specified in decimal, hex, octal, or binary. Use exactly
0x, +Numbers may be specified in decimal, hex, octal, or binary. Use exactly
0x,0o, and0bprefixes, with lowercase letters, for hex, octal, and binary, -respectively. Never include a leading zero unless it is immediately followed by +respectively. Never include a leading zero unless it is immediately followed byx,o, orb.5.8 Control structures
5.8.1 For loops
-With ES6, the language now has three different kinds of
forloops. All may be +With ES6, the language now has three different kinds of
forloops. All may be used, thoughfor-ofloops should be preferred when possible.
for-inloops may only be used on dict-style objects (see ??), and should not be used to iterate over an -array.Object.prototype.hasOwnPropertyshould be used infor-inloops to -exclude unwanted prototype properties. Preferfor-ofandObject.keysover +array.Object.prototype.hasOwnPropertyshould be used infor-inloops to +exclude unwanted prototype properties. Preferfor-ofandObject.keysoverfor-inwhen possible.5.8.2 Exceptions
Exceptions are an important part of the language and should be used whenever -exceptional cases occur. Always throw
Errors or subclasses ofError: never -throw string literals or other objects. Always usenewwhen constructing an +exceptional cases occur. Always throwErrors or subclasses ofError: never +throw string literals or other objects. Always usenewwhen constructing anError.This treatment extends to
Promiserejection values asPromise.reject(obj)is equivalent tothrow obj;in async functions.Custom exceptions provide a great way to convey additional error information -from functions. They should be defined and used wherever the native
+from functions. They should be defined and used wherever the nativeError-type is insufficient.Errortype +is insufficient.Prefer throwing exceptions over ad-hoc error-handling approaches (such as passing an error container reference type, or returning an object with an error @@ -2090,16 +2240,18 @@ since this will catch the error thrown by
fail. UseassertThr5.8.3 Switch statements
-Terminology Note: Inside the braces of a switch block are one or more statement groups. Each statement group consists of one or more switch labels (either
+case FOO:ordefault:), followed by one or more statements.Terminology Note: Inside the braces of a switch block are one or more statement +groups. Each statement group consists of one or more switch labels (either
case +FOO:ordefault:), followed by one or more statements.5.8.3.1 Fall-through: commented
Within a switch block, each statement group either terminates abruptly (with a
+indicate that execution will or might continue into the next statement group. +Any comment that communicates the idea of fall-through is sufficient (typically +break,returnorthrown exception), or is marked with a comment to -indicate that execution will or might continue into the next statement -group. Any comment that communicates the idea of fall-through is sufficient -(typically// fall through). This special comment is not required in the last -statement group of the switch block.// fall through). This special comment is not required in the last statement +group of the switch block.Example:
@@ -2149,14 +2301,14 @@ target of an event, or unnecessarilycall()ed orapply()5.11.1 with -+Do not use the
withkeyword. It makes your code harder to understand and has +Do not use the
withkeyword. It makes your code harder to understand and has been banned in strict mode since ES5.5.11.2 Dynamic code evaluation
Do not use
+loaders). These features are potentially dangerous and simply do not work in CSP +environments.evalor theFunction(...string)constructor (except for code -loaders). These features are potentially dangerous and simply do not work in -CSP environments.5.11.3 Automatic semicolon insertion
@@ -2165,13 +2317,13 @@ declarations, as noted above).5.11.4 Non-standard features
-Do not use non-standard features. This includes old features that have been +
Do not use non-standard features. This includes old features that have been removed (e.g.,
@@ -2198,12 +2350,12 @@ if (!x) alert(typeof x); // alerts 'boolean', as expectedWeakMap.clear), new features that are not yet standardized (e.g., the current TC39 working draft, proposals at any stage, or proposed but not-yet-complete web standards), or proprietary features that are only -implemented in some browsers. Use only features defined in the current ECMA-262 -or WHATWG standards. (Note that projects writing against specific APIs, such as -Chrome extensions or Node.js, can obviously use those APIs). Non-standard +implemented in some browsers. Use only features defined in the current ECMA-262 +or WHATWG standards. (Note that projects writing against specific APIs, such as +Chrome extensions or Node.js, can obviously use those APIs). Non-standard language “extensions” (such as those provided by some external transpilers) are forbidden.5.11.6 Modifying builtin objects
Never modify builtin types, either by adding methods to their constructors or to -their prototypes. Avoid depending on libraries that do this. Note that the +their prototypes. Avoid depending on libraries that do this. Note that the JSCompiler’s runtime library will provide standards-compliant polyfills where possible; nothing else may modify builtin objects.
-Do not add symbols to the global object unless absolutely necessary -(e.g. required by a third-party API).
+Do not add symbols to the global object unless absolutely necessary (e.g. +required by a third-party API).
5.11.7 Omitting
@@ -2257,30 +2409,37 @@ cstmrId // Deletes internal letters. kSecondsPerDay // Do not use Hungarian notation.()when invoking a constructorException: Variables that are in scope for 10 lines or fewer, including +arguments that are not part of an exported API, may use short (e.g. single +letter) variable names.
+6.2 Rules by identifier type
6.2.1 Package names
-Package names are all
+lowerCamelCase. For example, -my.exampleCode.deepSpace, but notmy.examplecode.deepspaceormy.example_code.deep_space.Package names are all
+ +lowerCamelCase. For example,my.exampleCode.deepSpace, +but notmy.examplecode.deepspaceor +my.example_code.deep_space.Exception: The package name may conform to TypeScript's path-based pattern. This is +typically all lower case with underscores where present in filenames.
6.2.2 Class names
Class, interface, record, and typedef names are written in
+Unexported classes are simply locals: they are not markedUpperCamelCase. -Unexported classes are simply locals: they are not marked@privateand -therefore are not named with a trailing underscore.@private.Type names are typically nouns or noun phrases. For example,
Request, -ImmutableList, orVisibilityMode. Additionally, interface names may +ImmutableView, orVisibilityMode. Additionally, interface names may sometimes be adjectives or adjective phrases instead (for example,Readable).6.2.3 Method names
-Method names are written in
+lowerCamelCase. Names for@privatemethods must -end with a trailing underscore.Method names are written in
lowerCamelCase. Names for@privatemethods may +optionally end with a trailing underscore.Method names are typically verbs or verb phrases. For example,
@@ -2292,7 +2451,7 @@ components of the name. One typical pattern issendMessageor -stop_. Getter and setter methods for properties are never required, but if +stop_. Getter and setter methods for properties are never required, but if they are used they should be namedgetFoo(or optionallyisFooorhasFoofor booleans), orsetFoo(value)for setters.6.2.4 Enum names
Enum names are written in
UpperCamelCase, similar to classes, and should -generally be singular nouns. Individual items within the enum are named in +generally be singular nouns. Individual items within the enum are named inCONSTANT_CASE.6.2.5 Constant names
@@ -2315,16 +2474,25 @@ intending to never mutate the object is generally not enough.@@ -2333,9 +2501,9 @@ const logger = log.getLogger('loggers.are.not.immutable');// Constants const NUMBER = 5; -/** @const */ exports.NAMES = ImmutableList.of('Ed', 'Ann'); +/** @const */ exports.NAMES = goog.debug.freeze(['Ed', 'Ann']); /** @enum */ exports.SomeEnum = { ENUM_CONSTANT: 'value' }; // Not constants let letVariable = 'non-const'; -class MyClass { constructor() { /** @const {string} */ this.nonStatic = 'non-static'; } }; -/** @type {string} */ MyClass.staticButMutable = 'not @const, can be reassigned'; + +class MyClass { + constructor() { /** @const {string} */ this.nonStatic = 'non-static'; } +}; +/** @type {string} */ +MyClass.staticButMutable = 'not @const, can be reassigned'; + const /** Set<string> */ mutableCollection = new Set(); -const /** ImmutableSet<SomeMutableType> */ mutableElements = ImmutableSet.of(mutable); -const Foo = goog.require('my.Foo'); // mirrors imported name + +const /** MyImmutableContainer<SomeMutableType> */ stillMutable = + new MyImmutableContainer(mutableInner); + +const {Foo} = goog.require('my.foo'); // mirrors imported name + const logger = log.getLogger('loggers.are.not.immutable');6.2.5.2 Local aliases
Local aliases should be used whenever they improve readability over -fully-qualified names. Follow the same rules as
+Aliases may also be used within functions. Aliases must begoog.requires +fully-qualified names. Follow the same rules asgoog.requires (??), maintaining the last part of the aliased name. -Aliases may also be used within functions. Aliases must beconst.const.Examples:
@@ -2347,21 +2515,21 @@ const {assert, assertInstanceof} = asserts;6.2.6 Non-constant field names
Non-constant field names (static or otherwise) are written in
+with an optional trailing underscore for private fields.lowerCamelCase, -with a trailing underscore for private fields.These names are typically nouns or noun phrases. For example,
computedValuesorindex_.6.2.7 Parameter names
-Parameter names are written in
lowerCamelCase. Note that this applies even if +Parameter names are written in
lowerCamelCase. Note that this applies even if the parameter expects a constructor.One-character parameter names should not be used in public methods.
Exception: When required by a third-party framework, parameter names may -begin with a
+begin with a$. This exception does not apply to any other identifiers -(e.g. local variables or properties).$. This exception does not apply to any other identifiers (e.g. +local variables or properties).6.2.8 Local variable names
@@ -2378,8 +2546,8 @@ identifiers, and must be all-caps, such asTYPEorTHIS6.2.10 Module-local namesModule-local names that are not exported are implicitly private. They are not -marked
+marked@privateand do not end in an underscore. This applies to classes, -functions, variables, constants, enums, and other module-local identifiers.@private. This applies to classes, functions, variables, constants, +enums, and other module-local identifiers.6.3 Camel case: defined
@@ -2405,15 +2573,15 @@ recommendation does not apply.- Now lowercase everything (including acronyms), then uppercase only the first character of:
-
- … each word, to yield upper camel case, or
-- … each word except the first, to yield lower camel case
+- … each word, to yield
+UpperCamelCase, or- … each word except the first, to yield
lowerCamelCase- Finally, join all the words into a single identifier.
Note that the casing of the original words is almost entirely disregarded.
-Examples:
+Examples of
lowerCamelCase:@@ -2427,39 +2595,44 @@ character of:
- XML HTTP requestXmlHttpRequest -XMLHTTPRequest ++ xmlHttpRequestXMLHTTPRequest- new customer IDnewCustomerId -newCustomerID ++ newCustomerIdnewCustomerID- inner stopwatchinnerStopwatch -innerStopWatch ++ innerStopwatchinnerStopWatch- supports IPv6 on iOS?supportsIpv6OnIos -supportsIPv6OnIOS ++ supportsIpv6OnIossupportsIPv6OnIOS- YouTube importerYouTubeImporter -YoutubeImporter* ++ youTubeImporteryoutubeImporter**Acceptable, but not recommended.
-Note: Some words are ambiguously hyphenated in the English language: for example
+nonemptyandnon-emptyare both correct, so the method names checkNonempty and checkNonEmpty are likewise both correct.For examples of
+ +UpperCamelCase, uppercase the first letter of each correct +lowerCamelCaseexample.Note: Some words are ambiguously hyphenated in the English language: for example +
nonemptyandnon-emptyare both correct, so the method namescheckNonempty+andcheckNonEmptyare likewise both correct.7 JSDoc
-JSDoc is used on all classes, fields, and methods.
+JSDoc is used on all classes, fields, and methods.
7.1 General form
@@ -2483,7 +2656,7 @@ this.foo_ = foo; multi-line style with/**and*/on their own lines.Many tools extract metadata from JSDoc comments to perform code validation and -optimization. As such, these comments must be well-formed.
+optimization. As such, these comments must be well-formed.7.2 Markdown
@@ -2518,8 +2691,8 @@ ignore plain text formatting, so if you did this:7.3 JSDoc tags
-Google style allows a subset of JSDoc tags. See -?? for the complete list. Most tags must +
Google style allows a subset of JSDoc tags. See +?? for the complete list. Most tags must occupy their own line, with the tag at the beginning of the line.
Disallowed:
@@ -2537,7 +2710,7 @@ optional type when appropriate./** * Place more complex annotations (like "implements" and "template") - * on their own lines. Multiple simple tags (like "export" and "final") + * on their own lines. Multiple simple tags (like "export" and "final") * may be combined in one line. * @export @final * @implements {Iterable<TYPE>} @@ -2559,12 +2732,12 @@ class MyClass { consistent.For general information about annotating types in JavaScript see -Annotating JavaScript for the Closure Compiler and Types in the Closure Type -System.
+Annotating JavaScript for the Closure Compiler and +Types in the Closure Type System.7.4 Line wrapping
-Line-wrapped block tags are indented four spaces. Wrapped description text may +
Line-wrapped block tags are indented four spaces. Wrapped description text may be lined up with the description on previous lines, but this horizontal alignment is discouraged.
@@ -2584,8 +2757,9 @@ exports.method = function(foo) {7.5 Top/file-level comments
-A file may have a top-level file overview. A copyright notice , author information, and -default visibility level are optional. File overviews are generally recommended whenever a +
A file may have a top-level file overview. A copyright notice, author information, +and default visibility level 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 may provide a description of the file's contents and any @@ -2607,9 +2781,10 @@ template parameters, implemented interfaces, visibility, or other appropriate tags. The class description should provide the reader with enough information to know how and when to use the class, as well as any additional considerations necessary to correctly use the class. Textual descriptions may be omitted on the -constructor.
+constructor. When defining a class@constructorand@extendsannotations are not used with the -classkeyword unless the class is being used to declare an@interfaceor -it extends a generic class.@constructorand@extendsannotations are +not used with theclasskeyword unless it extends a generic class. When +defining an@interfaceor a@record, the@extendsannotation is used when +defining a subclass and theextendskeyword is never used./** * A fancier event target that does cool things. @@ -2664,18 +2839,17 @@ const BandersnatchType = {Typedefs are useful for defining short record types, or aliases for unions, -complex functions, or generic types. -Typedefs should be avoided for record types with many fields, since they do not -allow documenting individual fields, nor using templates or recursive -references. -For large record types, prefer
+complex functions, or generic types. Typedefs should be avoided for record types +with many fields, since they do not allow documenting individual fields, nor +using templates or recursive references. For large record types, prefer +@record.@record.7.8 Method and function comments
In methods and named functions, parameter and return types must be documented, -except in the case of same-signature
+even in the case of same-signature@overrides, where all types are omitted. -Thethistype should be documented when necessary. Return type may be omitted -if the function has no non-emptyreturnstatements.@overrides. Thethistype should be +documented when necessary. Return type may be omitted if the function has no +non-emptyreturnstatements.Method, parameter, and return descriptions (but not types) may be omitted if they are obvious from the rest of the method’s JSDoc or from its signature.
@@ -2685,10 +2859,9 @@ does. This phrase is not an imperative sentence, but instead is written in the third person, as if there is an impliedThis method ...before it.If a method overrides a superclass method, it must include an
+annotation. For overridden methods, all@override-annotation. Overridden methods inherit all JSDoc annotations from the super -class method (including visibility annotations) and they should be omitted in -the overridden method. However, if any type is refined in type annotations, all -@paramand@returnannotations must be specified explicitly.@paramand@returnannotations must +be specified explicitly even if no type from the superclass method is refined. +This is to align with TypeScript.@@ -2795,8 +2974,8 @@ MyClass.RETRY_COUNT = 33;/** A class that does something. */ class SomeClass extends SomeBaseClass { @@ -2701,7 +2874,11 @@ class SomeClass extends SomeBaseClass { */ someMethod(obj, obviousOtherClass) { ... } - /** @override */ + /** + * @param {string} param + * @return {string} + * @override + */ overriddenMethod(param) { ... } } @@ -2740,7 +2917,9 @@ class MyClass { /** @return {string} */ foo() {...} } -/** Function description. */ bar() {...} +/** No function description allowed inline here. */ function bar() {...} + +function /** Function description is also illegal here. */ baz() {...}7.10 Type annotations
Type annotations are found on
+and optionally on@param,@return,@this, and@typetags, -and optionally on@const,@export, and any visibility tags. Type -annotations attached to JSDoc tags must always be enclosed in braces.@const,@export, and any visibility tags. Type annotations +attached to JSDoc tags must always be enclosed in braces.7.10.1 Nullability
@@ -2847,9 +3026,9 @@ const /** ?SomeCamelCaseName */ n = ...;In cases where the compiler doesn't accurately infer the type of an expression, and the assertion functions in goog.asserts -cannot remedy it , it is possible to -tighten the type by adding a type annotation comment and enclosing the -expression in parentheses. Note that the parentheses are required.
+cannot remedy it, it is +possible to tighten the type by adding a type annotation comment and enclosing +the expression in parentheses. Note that the parentheses are required.@@ -2975,9 +3154,9 @@ annotations./** @type {number} */ (x)7.11 Visibility annotations
Visibility annotations (
+level of a module.@private,@package,@protected) may be specified -in a@fileoverviewblock, or on any exported symbol or property. Do not +in a@fileoverviewblock, or on any exported symbol or property. Do not specify visibility for local variables, whether within a function or at the top -level of a module. All@privatenames must end with an underscore.@privatenames may optionally end with an underscore.8 Policies
@@ -2992,9 +3171,8 @@ package.8.2.1 Use a standard warning set
--As far as possible projects should use
+--warning_level=VERBOSE. -As far as possible projects should use +
--warning_level=VERBOSE.8.2.2 How to handle a warning
@@ -3012,14 +3190,17 @@ the situation entirely. the warning is invalid and that the code is actually safe and correct, add a comment to convince the reader of this fact and apply the@suppressannotation. -- Otherwise, leave a TODO comment. This is a last resort. If you do -this, do not suppress the warning. The warning should be visible until -it can be taken care of properly.
+- Otherwise, leave a TODO comment. This is a last resort. + If you do this, do +not suppress the warning. The warning should be visible until it can be +taken care of properly.
Warnings are suppressed at the narrowest reasonable scope, usually that of a single local variable or very small method. Often a variable or method is extracted for that reason alone.
+Warnings are suppressed at the narrowest reasonable scope, usually that of a +single local variable or very small method. Often a variable or method is +extracted for that reason alone.
Example
@@ -3052,9 +3233,9 @@ for any other reason.JSDoc serves multiple purposes in JavaScript. In addition to being used to -generate documentation it is also used to control tooling. The best known are +
JSDoc serves multiple purposes in JavaScript. In addition to being used to +generate documentation it is also used to control tooling. The best known are the Closure Compiler type annotations.
Documentation for JSDoc used by the Closure Compiler is described in -Annotating JavaScript for the Closure Compiler and Types in the Closure Type -System.
+Annotating JavaScript for the Closure Compiler and +Types in the Closure Type System.In addition to the JSDoc described in Annotating JavaScript for the Closure -Compiler the following tags are common and well supported by various -documentation generation tools (such as JsDossier) for purely documentation -purposes.
- -You may also see other types of JSDoc annotations in third-party code. These -annotations appear in the JSDoc Toolkit Tag Reference but are not considered -part of valid Google style.
+In addition to the JSDoc described in +Annotating JavaScript for the Closure Compiler the following tags are common +and well supported by various documentation generation tools (such as +JsDossier) for purely documentation purposes.
You may also see other types of JSDoc annotations in third-party code. These +annotations appear in the JSDoc Toolkit Tag Reference but are not considered +part of valid Google style.
+The following annotations are specific to a particular framework.
@@ -3302,30 +3483,6 @@ class ApplicationEvent {} -Here is a collection of lesser-known or commonly misunderstood facts about @@ -3341,8 +3498,8 @@ class (??).
This program performs type checking and other checks, -optimizations and other transformations (such as ECMAScript 6 to ECMAScript 5 -code lowering).
+This program performs type checking and +other checks, optimizations and other transformations (such as lowering code to +ECMAScript 5).
clang-formatThis program reformats
JavaScript source code into Google Style, and also follows a number of
-non-required but frequently readability-enhancing formatting practices.
-The output produced by clang-format is compliant with the style guide.
+non-required but frequently readability-enhancing formatting practices. The
+output produced by clang-format is compliant with the style guide.
clang-format is not required. Authors are allowed to change its output, and
@@ -3371,14 +3528,13 @@ usual way. However, subtrees may choose to opt in to such enforcement locally.
This program checks for a -variety of missteps and anti-patterns. -
+variety of missteps and anti-patterns.The JS Conformance Framework is a tool that is part of the Closure Compiler that provides developers a simple means to specify a set of additional checks to be -run against their code base above the standard checks. Conformance checks can, +run against their code base above the standard checks. Conformance checks can, for example, forbid access to a certain property, or calls to a certain function, or missing type information (unknowns).
@@ -3394,8 +3550,8 @@ globals, which could break the codebase) and security patterns (such as usingThis section describes exceptions and additional rules to be followed when -modern ECMAScript 6 syntax is not available to the code authors. Exceptions to -the recommended style are required when ECMAScript 6 syntax is not possible and +modern ECMAScript syntax is not available to the code authors. Exceptions to the +recommended style are required when modern ECMAScript syntax is not possible and are outlined here:
For global declarations where the const keyword would be used, if it were
-available, annotate the var declaration with @const instead (this is optional
-for local variables).
var declaration with @const instead (this is
+optional for local variables).
While most JavaScript VMs implemented before ECMAScript 6 support function declarations within blocks it was not standardized. Implementations were -inconsistent with each other and with the now-standard ECMAScript 6 behavior for -block scoped function declaration. ECMAScript 5 and prior only allow for -function declarations in the root statement list of a script or function and -explicitly ban them in block scopes in strict mode.
+inconsistent with each other and with the now-standard ECMAScript behavior for +block scoped function declaration. The ECMAScript 5 standard and prior only +allow for function declarations in the root statement list of a script or +function and explicitly ban them in block scopes in strict mode.To get consistent behavior, instead use a var initialized with a function
expression to define a function within a block:
WARNING: goog.scope is deprecated. New files should not use goog.scope
even in projects with existing goog.scope usage.
goog.scope may be used to shorten references to namespaced symbols in
-code using goog.provide/goog.require dependency management.
goog.scope may be used to shorten references to namespaced symbols in code
+using goog.provide/goog.require dependency management.
Only one goog.scope invocation may be added per file. Always place it in
-the global scope.
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,
@@ -3566,7 +3722,8 @@ Button = function() { ... };
...
-
Names must be the same as the last property of the global that they are aliasing.
+Names must be the same as the last property of the global that they are +aliasing.
goog.provide('my.module.SomeType');
@@ -3597,15 +3754,48 @@ circular dependencies between files in the same library. Unlike goog.requi
a goog.requireType statement is allowed to import a namespace before it is
defined.
-goog.forwardDeclare may still be used in legacy code to break circular
-references spanning across library boundaries, but newer code should be
-structured to avoid it.
-
goog.forwardDeclare statements must follow the same style rules as
goog.require and goog.requireType. The entire block of
goog.forwardDeclare, goog.require and goog.requireType statements is
sorted alphabetically.
+goog.forwardDeclare is used in legacy code to break circular references
+spanning across library boundaries. This pattern however is poorly supported
+by build tools and should not be used. Code should be organized to avoid
+circular dependencies across libraries (by splitting/merging libraries).
+
+9.4.4.4 goog.module.get(name)
+
+If a goog.provide file depends on a goog.module file, the goog.provide
+file can not normally refer to the module's exports via a global name. Instead,
+in addition to goog.require()ing the module, the goog.provide file must
+fetch the module's export object by calling goog.module.get('module.name').
+
+Note: Only calling goog.module.get('module.name') does not create a build-time
+dependency of your code on the module. The goog.require is needed for the
+build dependency.
+
+9.4.4.5 goog.module.declareLegacyNamespace()
+
+WARNING: goog.module.declareLegacyNamespace is only for transitional use.
+
+goog.module.declareLegacyNamespace is only for use while migrating a
+JavaScript file and its consumers from goog.provide to goog.module
+. Update consumers of
+your goog.module to use goog.module themselves.
+Remove calls to goog.module.declareLegacyNamespace whenever possible.
+
+
+If you can't update consumers of a legacy namespace from goog.provide to
+goog.module soon, please wrap the contents of your file in a call to
+goog.scope, use goog.module.get to import the legacy namespace--and then
+delete the call to goog.module.declareLegacyNamespace in your goog.module.
+
+Calling goog.module.declareLegacyNamespace() inside a goog.module(name) will
+declare the module's namespace as a global name just like a goog.provide()
+call does. This allows a non goog.module namespace to access the module's
+exports without calling goog.module.get(name).
+