| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <title>Google JavaScript Style Guide</title> |
| <link rel="stylesheet" href="javaguide.css"> |
| <script src="include/styleguide.js"></script> |
| <link rel="shortcut icon" href="/styleguide/favicon.ico"> |
| <script src="include/jsguide.js"></script> |
| </head> |
| <body onload="initStyleGuide();"> |
| <div id="content"> |
| <h1>Google JavaScript Style Guide</h1> |
| |
| <p style="position: fixed; left: 0; top: 0; padding: 0.5em; margin: 0; background-color: #fef6e0; text-align: center; width: 100%; font-weight: bold; z-index: 1;"> |
| Please note: This guide is no longer being updated. Google recommends migrating |
| to TypeScript, and following the <a href="tsguide.html">TypeScript guide</a>. |
| </p> |
| |
| <h2 id="introduction">1 Introduction</h2> |
| |
| <p>This document serves as the <strong>complete</strong> definition of Google’s coding standards |
| for source code in the JavaScript programming language. A JavaScript source file |
| is described as being <em>in Google Style</em> if and only if it adheres to the rules |
| herein.</p> |
| |
| <p>Like other programming style guides, the issues covered span not only aesthetic |
| issues of formatting, but other types of conventions or coding standards as |
| well. However, this document focuses primarily on the hard-and-fast rules that |
| we follow universally, and avoids giving advice that isn't clearly enforceable |
| (whether by human or tool).</p> |
| |
| <h3 id="terminology-notes">1.1 Terminology notes</h3> |
| |
| <p>In this document, unless otherwise clarified:</p> |
| |
| <ol> |
| <li><p>The term <em>comment</em> always refers to <em>implementation</em> comments. We do not use |
| the phrase <q>documentation comments</q>, instead using the common term “JSDoc” |
| for both human-readable text and machine-readable annotations within <code>/** … |
| */</code>.</p></li> |
| <li><p>This Style Guide uses <a href="http://tools.ietf.org/html/rfc2119">RFC 2119</a> terminology when using the phrases <em>must</em>, |
| <em>must not</em>, <em>should</em>, <em>should not</em>, and <em>may</em>. The terms <em>prefer</em> and |
| <em>avoid</em> correspond to <em>should</em> and <em>should not</em>, respectively. Imperative |
| and declarative statements are prescriptive and correspond to <em>must</em>.</p></li> |
| </ol> |
| |
| <p>Other <q>terminology notes</q> will appear occasionally throughout the document.</p> |
| |
| <h3 id="guide-notes">1.2 Guide notes</h3> |
| |
| <p>Example code in this document is <strong>non-normative</strong>. That is, while the examples |
| are in Google Style, they may not illustrate the <em>only</em> stylish way to represent |
| the code. Optional formatting choices made in examples must not be enforced as |
| rules.</p> |
| |
| <h2 id="source-file-basics">2 Source file basics</h2> |
| |
| <h3 id="file-name">2.1 File name</h3> |
| |
| <p>File names must be all lowercase and may include underscores (<code>_</code>) or dashes |
| (<code>-</code>), but no additional punctuation. Follow the convention that your project |
| uses. Filenames’ extension must be <code>.js</code>.</p> |
| |
| <h3 id="file-encoding">2.2 File encoding: UTF-8</h3> |
| |
| <p>Source files are encoded in <strong>UTF-8</strong>.</p> |
| |
| <h3 id="special-characters">2.3 Special characters</h3> |
| |
| <h4 id="whitespace-characters">2.3.1 Whitespace characters</h4> |
| |
| <p>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</p> |
| |
| <ol> |
| <li><p>All other whitespace characters in string literals are escaped, and</p></li> |
| <li><p>Tab characters are <strong>not</strong> used for indentation.</p></li> |
| </ol> |
| |
| <h4 id="special-escape-sequences">2.3.2 Special escape sequences</h4> |
| |
| <p>For any character that has a special escape sequence (<code>\'</code>, <code>\"</code>, <code>\\</code>, <code>\b</code>, |
| <code>\f</code>, <code>\n</code>, <code>\r</code>, <code>\t</code>, <code>\v</code>), that sequence is used rather than the |
| corresponding numeric escape (e.g <code>\x0a</code>, <code>\u000a</code>, or <code>\u{a}</code>). Legacy octal |
| escapes are never used.</p> |
| |
| <h4 id="non-ascii-characters">2.3.3 Non-ASCII characters</h4> |
| |
| <p>For the remaining non-ASCII characters, either the actual Unicode character |
| (e.g. <code>∞</code>) or the equivalent hex or Unicode escape (e.g. <code>\u221e</code>) is used, |
| depending only on which makes the code <strong>easier to read and understand</strong>.</p> |
| |
| <p>Tip: In the Unicode escape case, and occasionally even when actual Unicode |
| characters are used, an explanatory comment can be very helpful.</p> |
| |
| <pre><code class="language-js prettyprint good">/* Best: perfectly clear even without a comment. */ |
| const units = 'μs'; |
| |
| /* Allowed: but unnecessary as μ is a printable character. */ |
| const units = '\u03bcs'; // 'μs' |
| |
| /* Good: use escapes for non-printable characters with a comment for clarity. */ |
| return '\ufeff' + content; // Prepend a byte order mark. |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint bad">/* Poor: the reader has no idea what character this is. */ |
| const units = '\u03bcs'; |
| </code></pre> |
| |
| <p>Tip: Never make your code less readable simply out of fear that some programs |
| might not handle non-ASCII characters properly. If that happens, those programs |
| are <strong>broken</strong> and they must be <strong>fixed</strong>.</p> |
| |
| <h2 id="source-file-structure">3 Source file structure</h2> |
| |
| <p>All new source files should either be a <code>goog.module</code> |
| file (a file containing a <code>goog.module</code> call) or an ECMAScript (ES) module (uses |
| <code>import</code> and <code>export</code> statements).</p> |
| |
| <p>Files consist of the following, <strong>in order</strong>:</p> |
| |
| <ol> |
| <li>License or copyright information, if present</li> |
| <li><code>@fileoverview</code> JSDoc, if present</li> |
| <li><code>goog.module</code> statement, if a <code>goog.module</code> file</li> |
| <li>ES <code>import</code> statements, if an ES module</li> |
| <li><code>goog.require</code> and <code>goog.requireType</code> statements</li> |
| <li>The file’s implementation</li> |
| </ol> |
| |
| <p><strong>Exactly one blank line</strong> separates each section that is present, except the |
| file's implementation, which may be preceded by 1 or 2 blank lines.</p> |
| |
| <h3 id="file-copyright">3.1 License or copyright information, if present</h3> |
| |
| <p>If license or copyright information belongs in a file, it belongs here.</p> |
| |
| <h3 id="file-fileoverview">3.2 <code>@fileoverview</code> JSDoc, if present</h3> |
| |
| <p>See <a href="#jsdoc-top-file-level-comments">??</a> for formatting rules.</p> |
| |
| <h3 id="file-goog-module">3.3 <code>goog.module</code> statement</h3> |
| |
| <p>All <code>goog.module</code> files must declare exactly one <code>goog.module</code> name on a single |
| line: lines containing a <code>goog.module</code> declaration must not be wrapped, and are |
| therefore an exception to the 80-column limit.</p> |
| |
| <p>The entire argument to <code>goog.module</code> 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 in <code>lowerCamelCase</code>.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">goog.module('search.urlHistory.urlHistoryService'); |
| </code></pre> |
| |
| <h4 id="naming-hierarchy">3.3.1 Hierarchy</h4> |
| |
| <p>Module namespaces may never be named as a <em>direct</em> child of another module's |
| namespace.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though |
| goog.module('foo.bar.baz'); |
| </code></pre> |
| |
| <p>The directory hierarchy reflects the namespace hierarchy, so that deeper-nested |
| 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.</p> |
| |
| <h4 id="file-declare-legacy-namespace">3.3.2 <code>goog.module.declareLegacyNamespace</code></h4> |
| |
| <p>The single <code>goog.module</code> statement may optionally be followed by a call to |
| <code>goog.module.declareLegacyNamespace();</code>. Avoid |
| <code>goog.module.declareLegacyNamespace()</code> when possible.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">goog.module('my.test.helpers'); |
| goog.module.declareLegacyNamespace(); |
| goog.setTestOnly(); |
| </code></pre> |
| |
| <p><code>goog.module.declareLegacyNamespace</code> exists to ease the transition from |
| traditional object hierarchy-based namespaces but comes with some naming |
| restrictions. As the child module name must be created after the parent |
| namespace, this name <strong>must not</strong> be a child or parent of any other |
| <code>goog.module</code> (for example, <code>goog.module('parent');</code> and |
| <code>goog.module('parent.child');</code> cannot both exist safely, nor can |
| <code>goog.module('parent');</code> and <code>goog.module('parent.child.grandchild');</code>).</p> |
| |
| <h4 id="file-goog-module-exports">3.3.3 <code>goog.module</code> Exports</h4> |
| |
| <p>Classes, enums, functions, constants, and other symbols are exported using the |
| <code>exports</code> object. Exported symbols may be defined directly on the <code>exports</code> |
| 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 <code>@private</code>. There is no prescribed |
| ordering for exported and module-local symbols.</p> |
| |
| <p>Examples:</p> |
| |
| <pre><code class="language-js prettyprint good">const /** !Array<number> */ exportedArray = [1, 2, 3]; |
| |
| const /** !Array<number> */ moduleLocalArray = [4, 5, 6]; |
| |
| /** @return {number} */ |
| function moduleLocalFunction() { |
| return moduleLocalArray.length; |
| } |
| |
| /** @return {number} */ |
| function exportedFunction() { |
| return moduleLocalFunction() * 2; |
| } |
| |
| exports = {exportedArray, exportedFunction}; |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint good">/** @const {number} */ |
| exports.CONSTANT_ONE = 1; |
| |
| /** @const {string} */ |
| exports.CONSTANT_TWO = 'Another constant'; |
| </code></pre> |
| |
| <p>Do not annotate the <code>exports</code> object as <code>@const</code> as it is already treated as a |
| constant by the compiler.</p> |
| |
| <pre><code class="language-js prettyprint bad">/** @const */ |
| exports = {exportedFunction}; |
| </code></pre> |
| |
| <p>Do not use default exports as they don't translate easily to ES module |
| semantics.</p> |
| |
| <pre><code class="language-js prettyprint bad">exports = FancyClass; |
| </code></pre> |
| |
| <p><span id="file-es6-modules"></span></p> |
| |
| <h3 id="file-es-modules">3.4 ES modules</h3> |
| |
| <p>ES modules are files that use the <code>import</code> and <code>export</code> keywords.</p> |
| |
| <p><span id="es6-module-imports"></span></p> |
| |
| <h4 id="es-module-imports">3.4.1 Imports</h4> |
| |
| <p>Import statements must not be line wrapped and are therefore an exception to the |
| 80-column limit.</p> |
| |
| <p><span id="es6-import-paths"></span></p> |
| |
| <h5 id="esm-import-paths">3.4.1.1 Import paths</h5> |
| |
| <p>ES module files must use the <code>import</code> statement to import other ES module |
| files. Do not <code>goog.require</code> another ES module.</p> |
| |
| <pre><code class="language-js prettyprint good">import './sideeffects.js'; |
| |
| import * as goog from '../closure/goog/goog.js'; |
| import * as parent from '../parent.js'; |
| |
| import {name} from './sibling.js'; |
| </code></pre> |
| |
| <p><span id="es6-import-paths-file-extension"></span></p> |
| |
| <h6 id="esm-import-paths-file-extension">3.4.1.1.1 File extensions in import paths</h6> |
| |
| <p>The <code>.js</code> file extension is not optional in import paths and must always be |
| included.</p> |
| |
| <pre><code class="language-js prettyprint bad">import '../directory/file'; |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint good">import '../directory/file.js'; |
| </code></pre> |
| |
| <h5 id="importing-the-same-file-multiple-times">3.4.1.2 Importing the same file multiple times</h5> |
| |
| <p>Do not import the same file multiple times. This can make it hard to determine |
| the aggregate imports of a file.</p> |
| |
| <pre><code class="language-js prettyprint bad">// Imports have the same path, but since it doesn't align it can be hard to see. |
| import {short} from './long/path/to/a/file.js'; |
| import {aLongNameThatBreaksAlignment} from './long/path/to/a/file.js'; |
| </code></pre> |
| |
| <p><span id="naming-es6-imports"></span></p> |
| |
| <h5 id="naming-esm-imports">3.4.1.3 Naming imports</h5> |
| |
| <h6 id="naming-module-imports">3.4.1.3.1 Naming module imports</h6> |
| |
| <p>Module import names (<code>import * as name</code>) are <code>lowerCamelCase</code> names that are |
| derived from the imported file name.</p> |
| |
| <pre><code class="language-js prettyprint good">import * as fileOne from '../file-one.js'; |
| import * as fileTwo from '../file_two.js'; |
| import * as fileThree from '../filethree.js'; |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint good">import * as libString from './lib/string.js'; |
| import * as math from './math/math.js'; |
| import * as vectorMath from './vector/math.js'; |
| </code></pre> |
| |
| <p>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 <a href="https://threejs.org/">threejs</a>, using the <code>THREE</code> prefix.</p> |
| |
| <h6 id="naming-default-imports">3.4.1.3.2 Naming default imports</h6> |
| |
| <p>Default import names are derived from the imported file name and follow the |
| rules in <a href="#naming-rules-by-identifier-type">??</a>.</p> |
| |
| <pre><code class="language-js prettyprint good">import MyClass from '../my-class.js'; |
| import myFunction from '../my_function.js'; |
| import SOME_CONSTANT from '../someconstant.js'; |
| </code></pre> |
| |
| <p>Note: In general this should not happen as default exports are banned by this |
| style guide, see <a href="#named-vs-default-exports">??</a>. Default imports are only used |
| to import modules that do not conform to this style guide.</p> |
| |
| <h6 id="naming-named-imports">3.4.1.3.3 Naming named imports</h6> |
| |
| <p>In general symbols imported via the named import (<code>import {name}</code>) should keep |
| the same name. Avoid aliasing imports (<code>import {SomeThing as SomeOtherThing}</code>). |
| Prefer fixing name collisions by using a module import (<code>import *</code>) or renaming |
| the exports themselves.</p> |
| |
| <pre><code class="language-js prettyprint good">import * as bigAnimals from './biganimals.js'; |
| import * as domesticatedAnimals from './domesticatedanimals.js'; |
| |
| new bigAnimals.Cat(); |
| new domesticatedAnimals.Cat(); |
| </code></pre> |
| |
| <p>If renaming a named import is needed then use components of the imported |
| module's file name or path in the resulting alias.</p> |
| |
| <pre><code class="language-js prettyprint good">import {Cat as BigCat} from './biganimals.js'; |
| import {Cat as DomesticatedCat} from './domesticatedanimals.js'; |
| |
| new BigCat(); |
| new DomesticatedCat(); |
| </code></pre> |
| |
| <p><span id="es6-module-exports"></span></p> |
| |
| <h4 id="es-module-exports">3.4.2 Exports</h4> |
| |
| <p>Symbols are only exported if they are meant to be used outside the module. |
| Non-exported module-local symbols are not declared <code>@private</code>. There is no |
| prescribed ordering for exported and module-local symbols.</p> |
| |
| <h5 id="named-vs-default-exports">3.4.2.1 Named vs default exports</h5> |
| |
| <p>Use named exports in all code. You can apply the <code>export</code> keyword to a |
| declaration, or use the <code>export {name};</code> syntax.</p> |
| |
| <p>Do not use default exports. Importing modules must give a name to these values, |
| which can lead to inconsistencies in naming across modules.</p> |
| |
| <pre><code class="language-js prettyprint bad">// Do not use default exports: |
| export default class Foo { ... } // BAD! |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint good">// Use named exports: |
| export class Foo { ... } |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint good">// Alternate style named exports: |
| class Foo { ... } |
| |
| export {Foo}; |
| </code></pre> |
| |
| <p><span id="es6-exports-mutability"></span></p> |
| |
| <h5 id="esm-exports-mutability">3.4.2.2 Mutability of exports</h5> |
| |
| <p>Exported variables must not be mutated outside of module initialization.</p> |
| |
| <p>There are alternatives if mutation is needed, including exporting a constant |
| reference to an object that has mutable fields or exporting accessor functions for |
| mutable data.</p> |
| |
| <pre><code class="language-js prettyprint bad">// Bad: both foo and mutateFoo are exported and mutated. |
| export let /** number */ foo = 0; |
| |
| /** |
| * Mutates foo. |
| */ |
| export function mutateFoo() { |
| ++foo; |
| } |
| |
| /** |
| * @param {function(number): number} newMutateFoo |
| */ |
| export function setMutateFoo(newMutateFoo) { |
| // Exported classes and functions can be mutated! |
| mutateFoo = () => { |
| foo = newMutateFoo(foo); |
| }; |
| } |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint good">// Good: Rather than export the mutable variables foo and mutateFoo directly, |
| // 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; |
| |
| /** @return {number} */ |
| export function getFoo() { |
| return foo; |
| } |
| |
| export function mutateFoo() { |
| foo = mutateFooFunc(foo); |
| } |
| |
| /** @param {function(number): number} mutateFoo */ |
| export function setMutateFoo(mutateFoo) { |
| mutateFooFunc = mutateFoo; |
| } |
| </code></pre> |
| |
| <p><span id="es6-module-circular-dependencies"></span></p> |
| |
| <h5 id="es-module-export-from">3.4.2.3 export from</h5> |
| |
| <p><code>export from</code> statements must not be line wrapped and are therefore an |
| exception to the 80-column limit. This applies to both <code>export from</code> flavors.</p> |
| |
| <pre><code class="language-js prettyprint good">export {specificName} from './other.js'; |
| export * from './another.js'; |
| </code></pre> |
| |
| <h4 id="es-module-circular-dependencies">3.4.3 Circular Dependencies in ES modules</h4> |
| |
| <p>Do not create cycles between ES modules, even though the ECMAScript |
| specification allows this. Note that it is possible to create cycles with both |
| the <code>import</code> and <code>export</code> statements.</p> |
| |
| <pre><code class="language-js prettyprint bad">// a.js |
| import './b.js'; |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint bad">// b.js |
| import './a.js'; |
| |
| // `export from` can cause circular dependencies too! |
| export {x} from './c.js'; |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint bad">// c.js |
| import './b.js'; |
| |
| export let x; |
| </code></pre> |
| |
| <p><span id="es6-module-closure-interop"></span></p> |
| |
| <h4 id="es-module-closure-interop">3.4.4 Interoperating with Closure</h4> |
| |
| <p><span id="es6-module-referencing-goog"></span></p> |
| |
| <h5 id="es-module-referencing-goog">3.4.4.1 Referencing goog</h5> |
| |
| <p>To reference the Closure <code>goog</code> namespace, import Closure's <code>goog.js</code>.</p> |
| |
| <pre><code class="language-js prettyprint good">import * as goog from '../closure/goog/goog.js'; |
| |
| const {compute} = goog.require('a.name'); |
| |
| export const CONSTANT = compute(); |
| </code></pre> |
| |
| <p><code>goog.js</code> exports only a subset of properties from the global <code>goog</code> that can be |
| used in ES modules.</p> |
| |
| <p><span id="goog-require-in-es6-module"></span></p> |
| |
| <h5 id="goog-require-in-es-module">3.4.4.2 goog.require in ES modules</h5> |
| |
| <p><code>goog.require</code> in ES modules works as it does in <code>goog.module</code> files. You can |
| require any Closure namespace symbol (i.e., symbols created by <code>goog.provide</code> or |
| <code>goog.module</code>) and <code>goog.require</code> will return the value.</p> |
| |
| <pre><code class="language-js prettyprint good">import * as goog from '../closure/goog/goog.js'; |
| import * as anEsModule from './anEsModule.js'; |
| |
| const GoogPromise = goog.require('goog.Promise'); |
| const myNamespace = goog.require('my.namespace'); |
| </code></pre> |
| |
| <p><span id="closure-module-id-in-es6-module"></span></p> |
| |
| <h5 id="closure-module-id-in-es-module">3.4.4.3 Declaring Closure Module IDs in ES modules</h5> |
| |
| <p><code>goog.declareModuleId</code> can be used within ES modules to declare a |
| <code>goog.module</code>-like module ID. This means that this module ID can be |
| <code>goog.require</code>d, <code>goog.module.get</code>d etc. as if it were |
| a <code>goog.module</code> that did not call <code>goog.module.declareLegacyNamespace</code>. It does |
| not create the module ID as a globally available JavaScript symbol.</p> |
| |
| <p>A <code>goog.require</code> (or <code>goog.module.get</code>) for a module ID from |
| <code>goog.declareModuleId</code> will always return the module object (as if it was |
| <code>import *</code>'d). As a result, the argument to <code>goog.declareModuleId</code> should always |
| end with a <code>lowerCamelCaseName</code>.</p> |
| |
| <p>Note: It is an error to call <code>goog.module.declareLegacyNamespace</code> in an ES |
| module, it can only be called from <code>goog.module</code> files. There is no direct way |
| to associate a <q>legacy</q> namespace with an ES module.</p> |
| |
| <p><code>goog.declareModuleId</code> should only be used to upgrade Closure files to ES |
| modules in place, where named exports are used.</p> |
| |
| <pre><code class="language-js prettyprint good">import * as goog from '../closure/goog.js'; |
| |
| goog.declareModuleId('my.esm'); |
| |
| export class Class {}; |
| </code></pre> |
| |
| <h3 id="file-set-test-only">3.5 <code>goog.setTestOnly</code></h3> |
| |
| <p>In a <code>goog.module</code> file the <code>goog.module</code> statement and, if present, |
| <code>goog.module.declareLegacyNamespace()</code> statement may optionally be followed by a |
| call to <code>goog.setTestOnly()</code>.</p> |
| |
| <p>In an ES module the <code>import</code> statements may optionally be |
| followed by a call to <code>goog.setTestOnly()</code>.</p> |
| |
| <h3 id="file-goog-require">3.6 <code>goog.require</code> and <code>goog.requireType</code> statements</h3> |
| |
| <p>Imports are done with <code>goog.require</code> and <code>goog.requireType</code> statements. The |
| names imported by a <code>goog.require</code> statement may be used both in code and in |
| type annotations, while those imported by a <code>goog.requireType</code> may be used in |
| type annotations only.</p> |
| |
| <p>The <code>goog.require</code> and <code>goog.requireType</code> statements form a contiguous block |
| with no empty lines. This block follows the <code>goog.module</code> declaration separated |
| <a href="#source-file-structure">by a single empty line</a>. The entire argument to |
| <code>goog.require</code> or <code>goog.requireType</code> is a namespace defined by a <code>goog.module</code> |
| in a separate file. <code>goog.require</code> and <code>goog.requireType</code> statements may not |
| appear anywhere else in the file.</p> |
| |
| <p>Each <code>goog.require</code> or <code>goog.requireType</code> is assigned to a single constant |
| alias, or else destructured into several constant aliases. These aliases are the |
| only acceptable way to refer to dependencies in type annotations or code. Fully |
| qualified namespaces must not be used anywhere, except as an argument to |
| <code>goog.require</code> or <code>goog.requireType</code>.</p> |
| |
| <p><strong>Exception</strong>: Types, variables, and functions declared in externs files have to |
| use their fully qualified name in type annotations and code.</p> |
| |
| <p>When <code>goog.require</code> is assigned to a single constant alias, it must match the |
| final dot-separated component of the imported module's namespace.</p> |
| |
| <p><strong>Exception</strong>: In certain cases, additional components of the namespace can be |
| used to form a longer alias. The resulting alias must retain the original |
| 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 <code>Element</code>, <code>Event</code>, <code>Error</code>, <code>Map</code>, and |
| <code>Promise</code> (for a more complete list, see <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects">Standard Built-in Objects</a> and |
| <a href="https://developer.mozilla.org/en-US/docs/Web/API">Web APIs</a> at MDN).</p> |
| When renaming destructured aliases, a space must follow the colon |
| as required in <a href="#formatting-horizontal-whitespace">??</a>.</p> |
| |
| <p>A file should not contain both a <code>goog.require</code> and a <code>goog.requireType</code> |
| statement for the same namespace. If the imported name is used both in code and |
| in type annotations, it should be imported by a single <code>goog.require</code> statement.</p> |
| |
| <p>If a module is imported only for its side effects, the call must be a |
| <code>goog.require</code> (not a <code>goog.requireType</code>) and assignment may be omitted. A |
| comment is required to explain why this is needed and suppress a compiler |
| warning.</p> |
| |
| |
| |
| <p>The lines are sorted according to the following rules: All requires with a name |
| on the left hand side come first, sorted alphabetically by those names. Then |
| destructuring requires, again sorted by the names on the left hand side. |
| Finally, any require calls that are standalone (generally these are for modules |
| imported just for their side effects).</p> |
| |
| <p>Tip: There’s no need to memorize this order and enforce it manually. You can |
| rely on your IDE to report requires |
| that are not sorted correctly.</p> |
| |
| <p>If a long alias or module name would cause a line to exceed the 80-column limit, |
| it <strong>must not</strong> be wrapped: require lines are an exception to the 80-column |
| limit.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">// 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 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'); |
| </code></pre> |
| |
| <p>Discouraged:</p> |
| |
| <pre><code class="language-js prettyprint bad">// 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'); |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint bad">// 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'); |
| </code></pre> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">// Extra terms must come from the namespace. |
| const MyClassForBizzing = goog.require('some.package.MyClass'); |
| // Alias must include the entire final namespace component. |
| const MyClass = goog.require('some.package.MyClassForBizzing'); |
| // Alias must not mask native type (should be `const JspbMap` here). |
| const Map = goog.require('jspb.Map'); |
| // Don't break goog.require lines over 80 columns. |
| const SomeDataStructure = |
| goog.require('proto.identical.package.identifiers.SomeDataStructure'); |
| // Alias must be based on the namespace. |
| const randomName = goog.require('something.else'); |
| // Missing a space after the colon. |
| const {Foo:FooProto} = goog.require('some.package.proto.Foo'); |
| // goog.requireType without an alias. |
| goog.requireType('some.package.with.a.Type'); |
| |
| |
| /** |
| * @param {!some.unimported.Dependency} param All external types used in JSDoc |
| * annotations must be goog.require'd, unless declared in externs. |
| */ |
| function someFunction(param) { |
| // goog.require lines must be at the top level before any other code. |
| const alias = goog.require('my.long.name.alias'); |
| // ... |
| } |
| </code></pre> |
| |
| <h3 id="file-implementation">3.7 The file’s implementation</h3> |
| |
| <p>The actual implementation follows after all dependency information is declared |
| (separated by at least one blank line).</p> |
| |
| <p>This may consist of any module-local declarations (constants, variables, |
| classes, functions, etc), as well as any exported symbols.</p> |
| |
| <h2 id="formatting">4 Formatting</h2> |
| |
| <p><strong>Terminology Note</strong>: <em>block-like construct</em> refers to the body of a class, |
| function, method, or brace-delimited block of code. Note that, by |
| <a href="#features-array-literals">??</a> and <a href="#features-object-literals">??</a>, any array or |
| object literal may optionally be treated as if it were a block-like construct.</p> |
| |
| <p>Tip: Use <code>clang-format</code>. The JavaScript community has invested effort to make |
| sure clang-format <q>does the right thing</q> on JavaScript files. <code>clang-format</code> has |
| integration with several popular editors.</p> |
| |
| <h3 id="formatting-braces">4.1 Braces</h3> |
| |
| <h4 id="formatting-braces-all">4.1.1 Braces are used for all control structures</h4> |
| |
| <p>Braces are required for all control structures (i.e. <code>if</code>, <code>else</code>, <code>for</code>, <code>do</code>, |
| <code>while</code>, 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.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">if (someVeryLongCondition()) |
| doSomething(); |
| |
| for (let i = 0; i < foo.length; i++) bar(foo[i]); |
| </code></pre> |
| |
| <p><strong>Exception</strong>: 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 |
| structure may omit braces and newlines.</p> |
| |
| <pre><code class="language-js prettyprint good">if (shortCondition()) foo(); |
| </code></pre> |
| |
| <h4 id="formatting-nonempty-blocks">4.1.2 Nonempty blocks: K&R style</h4> |
| |
| <p>Braces follow the Kernighan and Ritchie style (<q><a href="https://blog.codinghorror.com/new-programming-jargon/#3">Egyptian brackets</a></q>) for |
| <em>nonempty</em> blocks and block-like constructs:</p> |
| |
| <ul> |
| <li>No line break before the opening brace.</li> |
| <li>Line break after the opening brace.</li> |
| <li>Line break before the closing brace.</li> |
| <li>Line break after the closing brace <em>if</em> that brace terminates a statement or |
| the body of a function or class statement, or a class method. Specifically, |
| there is <em>no</em> line break after the brace if it is followed by <code>else</code>, |
| <code>catch</code>, <code>while</code>, or a comma, semicolon, or right-parenthesis.</li> |
| </ul> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">class InnerClass { |
| constructor() {} |
| |
| /** @param {number} foo */ |
| method(foo) { |
| if (condition(foo)) { |
| try { |
| // Note: this might fail. |
| something(); |
| } catch (err) { |
| recover(); |
| } |
| } |
| } |
| } |
| </code></pre> |
| |
| <h4 id="formatting-empty-blocks">4.1.3 Empty blocks: may be concise</h4> |
| |
| <p>An empty block or block-like construct <em>may</em> be closed immediately after it is |
| opened, with no characters, space, or line break in between (i.e. <code>{}</code>), |
| <strong>unless</strong> it is a part of a <em>multi-block statement</em> (one that directly contains |
| multiple blocks: <code>if</code>/<code>else</code> or <code>try</code>/<code>catch</code>/<code>finally</code>).</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">function doNothing() {} |
| </code></pre> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">if (condition) { |
| // … |
| } else if (otherCondition) {} else { |
| // … |
| } |
| |
| try { |
| // … |
| } catch (e) {} |
| </code></pre> |
| |
| <h3 id="formatting-block-indentation">4.2 Block indentation: +2 spaces</h3> |
| |
| <p>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 <a href="#formatting-nonempty-blocks">??</a>).</p> |
| |
| <h4 id="formatting-array-literals">4.2.1 Array literals: optionally <q>block-like</q></h4> |
| |
| <p>Any array literal may optionally be formatted as if it were a “block-like |
| construct.” For example, the following are all valid (<strong>not</strong> an exhaustive |
| list):</p> |
| |
| <pre><code class="language-js prettyprint good">const a = [ |
| 0, |
| 1, |
| 2, |
| ]; |
| |
| const b = |
| [0, 1, 2]; |
| |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint good">const c = [0, 1, 2]; |
| |
| someMethod(foo, [ |
| 0, 1, 2, |
| ], bar); |
| </code></pre> |
| |
| <p>Other combinations are allowed, particularly when emphasizing semantic groupings |
| between elements, but should not be used only to reduce the vertical size of |
| larger arrays.</p> |
| |
| <h4 id="formatting-object-literals">4.2.2 Object literals: optionally <q>block-like</q></h4> |
| |
| <p>Any object literal may optionally be formatted as if it were a “block-like |
| construct.” The same examples apply as <a href="#formatting-array-literals">??</a>. For |
| example, the following are all valid (<strong>not</strong> an exhaustive list):</p> |
| |
| <pre><code class="language-js prettyprint good">const a = { |
| a: 0, |
| b: 1, |
| }; |
| |
| const b = |
| {a: 0, b: 1}; |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint good">const c = {a: 0, b: 1}; |
| |
| someMethod(foo, { |
| a: 0, b: 1, |
| }, bar); |
| </code></pre> |
| |
| <h4 id="formatting-class-literals">4.2.3 Class literals</h4> |
| |
| <p>Class literals (whether declarations or expressions) are indented as blocks. Do |
| not add semicolons after methods, or after the closing brace of a class |
| <em>declaration</em> (statements—such as assignments—that contain class <em>expressions</em> |
| are still terminated with a semicolon). For inheritance, the <code>extends</code> keyword |
| is sufficient unless the superclass is templatized. Subclasses of templatized |
| types must explicitly specify the template type in an <code>@extends</code> JSDoc |
| annotation, even if it is just passing along the same template name.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">/** @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; |
| } |
| }; |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint bad">/** @extends {Bar} */ // <-- unnecessary @extends |
| exports.Baz = class extends Bar { |
| /** @return {number} */ |
| method() { |
| return this.x; |
| } |
| }; |
| </code></pre> |
| |
| <h4 id="formatting-function-expressions">4.2.4 Function expressions</h4> |
| |
| <p>When declaring an anonymous function in the list of arguments for a function |
| call, the body of the function is indented two spaces more than the preceding |
| indentation depth.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">prefix.something.reallyLongFunctionName('whatever', (a1, a2) => { |
| // Indent the function body +2 relative to indentation depth |
| // of the 'prefix' statement one line above. |
| if (a1.equals(a2)) { |
| someOtherLongFunctionName(a1); |
| } else { |
| andNowForSomethingCompletelyDifferent(a2.parrot); |
| } |
| }); |
| |
| some.reallyLongFunctionCall(arg1, arg2, arg3) |
| .thatsWrapped() |
| .then((result) => { |
| // Indent the function body +2 relative to the indentation depth |
| // of the '.then()' call. |
| if (result) { |
| result.use(); |
| } |
| }); |
| </code></pre> |
| |
| <h4 id="formatting-switch-statements">4.2.5 Switch statements</h4> |
| |
| <p>As with any other block, the contents of a switch block are indented +2.</p> |
| |
| |
| |
| <p>After a switch label, a newline appears, and the indentation level is increased |
| +2, exactly as if a block were being opened. An explicit block may be used if |
| required by lexical scoping. The following switch label returns to the previous |
| indentation level, as if a block had been closed.</p> |
| |
| <p>A blank line is optional between a <code>break</code> and the following case.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">switch (animal) { |
| case Animal.BANDERSNATCH: |
| handleBandersnatch(); |
| break; |
| |
| case Animal.JABBERWOCK: |
| handleJabberwock(); |
| break; |
| |
| default: |
| throw new Error('Unknown animal'); |
| } |
| </code></pre> |
| |
| <h3 id="formatting-statements">4.3 Statements</h3> |
| |
| <h4 id="formatting-one-statement-perline">4.3.1 One statement per line</h4> |
| |
| <p>Each statement is followed by a line-break.</p> |
| |
| <h4 id="formatting-semicolons-are-required">4.3.2 Semicolons are required</h4> |
| |
| <p>Every statement must be terminated with a semicolon. Relying on automatic |
| semicolon insertion is forbidden.</p> |
| |
| <h3 id="formatting-column-limit">4.4 Column limit: 80</h3> |
| |
| <p>JavaScript code has a column limit of 80 characters. Except as noted below, any |
| line that would exceed this limit must be line-wrapped, as explained in |
| <a href="#formatting-line-wrapping">??</a>.</p> |
| |
| <p><strong>Exceptions:</strong></p> |
| |
| <ol> |
| <li><code>goog.module</code>, <code>goog.require</code> and <code>goog.requireType</code> statements (see |
| <a href="#file-goog-module">??</a> and <a href="#file-goog-require">??</a>).</li> |
| <li>ES module <code>import</code> and <code>export from</code> statements (see |
| <a href="#es-module-imports">??</a> and <a href="#es-module-export-from">??</a>).</li> |
| <li>Lines where obeying the column limit is not possible or would hinder |
| discoverability. Examples include: |
| <ul> |
| <li>A long URL which should be clickable in source.</li> |
| <li>A shell command intended to be copied-and-pasted.</li> |
| <li>A long string literal which may need to be copied or searched for wholly |
| (e.g., a long file path).</li> |
| </ul></li> |
| </ol> |
| |
| <h3 id="formatting-line-wrapping">4.5 Line-wrapping</h3> |
| |
| <p><strong>Terminology Note</strong>: <em>Line wrapping</em> is breaking a chunk of code into multiple |
| lines to obey column limit, where the chunk could otherwise legally fit in a |
| single line.</p> |
| |
| <p>There is no comprehensive, deterministic formula showing <em>exactly</em> how to |
| line-wrap in every situation. Very often there are several valid ways to |
| line-wrap the same piece of code.</p> |
| |
| <p>Note: While the typical reason for line-wrapping is to avoid overflowing the |
| column limit, even code that would in fact fit within the column limit may be |
| line-wrapped at the author's discretion.</p> |
| |
| <p>Tip: Extracting a method or local variable may solve the problem without the |
| need to line-wrap.</p> |
| |
| <h4 id="formatting-where-to-break">4.5.1 Where to break</h4> |
| |
| <p>The prime directive of line-wrapping is: prefer to break at a <strong>higher syntactic |
| level</strong>. </p> |
| |
| <p>Preferred:</p> |
| |
| <pre><code class="language-js prettyprint good">currentEstimate = |
| calc(currentEstimate + x * currentEstimate) / |
| 2.0; |
| </code></pre> |
| |
| <p>Discouraged:</p> |
| |
| <pre><code class="language-js prettyprint bad">currentEstimate = calc(currentEstimate + x * |
| currentEstimate) / 2.0; |
| </code></pre> |
| |
| <p>In the preceding example, the syntactic levels from highest to lowest are as |
| follows: assignment, division, function call, parameters, number constant.</p> |
| |
| <p>Operators are wrapped as follows:</p> |
| |
| <ol> |
| <li>When a line is broken at an operator the break comes after the symbol. (Note |
| that this is not the same practice used in Google style for Java.) |
| <ol> |
| <li>This does not apply to the <q>dot</q> (<code>.</code>), which is not actually an |
| operator.</li> |
| </ol></li> |
| <li>A method or constructor name stays attached to the open parenthesis (<code>(</code>) |
| that follows it.</li> |
| <li>A comma (<code>,</code>) stays attached to the token that precedes it.</li> |
| <li>A line break is never added between a return and the return value as this |
| would change the meaning of the code.</li> |
| <li>JSDoc annotations with type names break after <q>{</q>. This is necessary as |
| annotations with optional types (@const, @private, @param, etc) do not scan |
| the next line.</li> |
| </ol> |
| |
| <blockquote> |
| <p>Note: The primary goal for line wrapping is to have clear code, not |
| necessarily code that fits in the smallest number of lines.</p> |
| </blockquote> |
| |
| <h4 id="formatting-indent">4.5.2 Indent continuation lines at least +4 spaces</h4> |
| |
| <p>When line-wrapping, each line after the first (each <em>continuation line</em>) is |
| indented at least +4 from the original line, unless it falls under the rules of |
| block indentation.</p> |
| |
| <p>When there are multiple continuation lines, indentation may be varied beyond +4 |
| 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.</p> |
| |
| <p><a href="#formatting-horizontal-alignment">??</a> addresses the discouraged practice of |
| using a variable number of spaces to align certain tokens with previous lines.</p> |
| |
| <h3 id="formatting-whitespace">4.6 Whitespace</h3> |
| |
| <h4 id="formatting-vertical-whitespace">4.6.1 Vertical whitespace</h4> |
| |
| <p>A single blank line appears:</p> |
| |
| <ol> |
| <li>Between consecutive methods in a class or object literal |
| <ol> |
| <li>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 <em>logical groupings</em> of fields.</li> |
| </ol></li> |
| <li>Within method bodies, sparingly to create <em>logical groupings</em> of statements. |
| Blank lines at the start or end of a function body are not allowed.</li> |
| <li><em>Optionally</em> before the first or after the last method in a class or object |
| literal (neither encouraged nor discouraged).</li> |
| <li>As required by other sections of this document (e.g. |
| <a href="#file-goog-require">??</a>).</li> |
| </ol> |
| |
| <p><em>Multiple</em> consecutive blank lines are permitted, but never required (nor |
| encouraged).</p> |
| |
| <h4 id="formatting-horizontal-whitespace">4.6.2 Horizontal whitespace</h4> |
| |
| <p>Use of horizontal whitespace depends on location, and falls into three broad |
| categories: <em>leading</em> (at the start of a line), <em>trailing</em> (at the end of a |
| line), and <em>internal</em>. Leading whitespace (i.e., indentation) is addressed |
| elsewhere. Trailing whitespace is forbidden.</p> |
| |
| <p>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 |
| following places <strong>only</strong>.</p> |
| |
| <ol> |
| <li>Separating any reserved word (such as <code>if</code>, <code>for</code>, or <code>catch</code>) except for |
| <code>function</code> and <code>super</code>, from an open parenthesis (<code>(</code>) that follows it on |
| that line.</li> |
| <li>Separating any reserved word (such as <code>else</code> or <code>catch</code>) from a closing |
| curly brace (<code>}</code>) that precedes it on that line.</li> |
| <li>Before any open curly brace (<code>{</code>), with two exceptions: |
| <ol> |
| <li>Before an object literal that is the first argument of a function or the |
| first element in an array literal (e.g. <code>foo({a: [{c: d}]})</code>).</li> |
| <li>In a template expansion, as it is forbidden by the language (e.g. valid: |
| <code>`ab${1 + 2}cd`</code>, invalid: <code class="badcode">`xy$ {3}z`</code>).</li> |
| </ol></li> |
| <li>On both sides of any binary or ternary operator.</li> |
| <li>After a comma (<code>,</code>) or semicolon (<code>;</code>). Note that spaces are <em>never</em> allowed |
| before these characters.</li> |
| <li>After the colon (<code>:</code>) in an object literal.</li> |
| <li>On both sides of the double slash (<code>//</code>) that begins an end-of-line comment. |
| Here, multiple spaces are allowed, but not required.</li> |
| <li>After an open-block comment character and on both sides of close characters |
| (e.g. for short-form type declarations, casts, and parameter name comments: |
| <code>this.foo = /** @type {number} */ (bar)</code>; or <code>function(/** string */ foo) |
| {</code>; or <code>baz(/* buzz= */ true)</code>).</li> |
| </ol> |
| |
| <h4 id="formatting-horizontal-alignment">4.6.3 Horizontal alignment: discouraged</h4> |
| |
| <p><strong>Terminology Note</strong>: <em>Horizontal alignment</em> is the practice of adding a |
| variable number of additional spaces in your code with the goal of making |
| certain tokens appear directly below certain other tokens on previous lines.</p> |
| |
| <p>This practice is permitted, but it is <strong>generally discouraged</strong> by Google Style. |
| It is not even required to <em>maintain</em> horizontal alignment in places where it |
| was already used.</p> |
| |
| <p>Here is an example without alignment, followed by one with alignment. Both are |
| allowed, but the latter is discouraged:</p> |
| |
| <pre><code class="language-js prettyprint good">{ |
| tiny: 42, // this is great |
| longer: 435, // this too |
| }; |
| |
| { |
| tiny: 42, // permitted, but future edits |
| longer: 435, // may leave it unaligned |
| }; |
| </code></pre> |
| |
| <p>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 <q>blast radius.</q> This can at worst result in pointless |
| busywork, but at best it still corrupts version history information, slows down |
| reviewers and exacerbates merge conflicts.</p> |
| |
| <h4 id="formatting-function-arguments">4.6.4 Function arguments</h4> |
| |
| <p>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:</p> |
| |
| <pre><code class="language-js prettyprint good">// 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 |
| // "function") but fit entirely on the second line. Works with very long |
| // function names, survives renaming without reindenting, low on space. |
| doSomething( |
| descriptiveArgumentOne, descriptiveArgumentTwo, descriptiveArgumentThree) { |
| // … |
| } |
| |
| // If the argument list is longer, wrap at 80. Uses less vertical space, |
| // but violates the rectangle rule and is thus not recommended. |
| doSomething(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, |
| tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) { |
| // … |
| } |
| |
| // Four-space, one argument per line. Works with long function names, |
| // survives renaming, and emphasizes each argument. |
| doSomething( |
| veryDescriptiveArgumentNumberOne, |
| veryDescriptiveArgumentTwo, |
| tableModelEventHandlerProxy, |
| artichokeDescriptorAdapterIterator) { |
| // … |
| } |
| </code></pre> |
| |
| <h3 id="formatting-grouping-parentheses">4.7 Grouping parentheses: recommended</h3> |
| |
| <p>Optional grouping parentheses are omitted only when the author and reviewer |
| agree that there is no reasonable chance that the code will be misinterpreted |
| without them, nor would they have made the code easier to read. It is <em>not</em> |
| reasonable to assume that every reader has the entire operator precedence table |
| memorized.</p> |
| |
| <p>Do not use unnecessary parentheses around the entire expression following |
| <code>delete</code>, <code>typeof</code>, <code>void</code>, <code>return</code>, <code>throw</code>, <code>case</code>, <code>in</code>, <code>of</code>, or <code>yield</code>.</p> |
| |
| <p>Parentheses are required for type casts: <code>/** @type {!Foo} */ (foo)</code>.</p> |
| |
| <h3 id="formatting-comments">4.8 Comments</h3> |
| |
| <p>This section addresses <em>implementation comments</em>. JSDoc is addressed separately |
| in <a href="#jsdoc">??</a>.</p> |
| |
| <h4 id="formatting-block-comment-style">4.8.1 Block comment style</h4> |
| |
| <p>Block comments are indented at the same level as the surrounding code. They may |
| be in <code>/* … */</code> or <code>//</code>-style. For multi-line <code>/* … */</code> comments, subsequent |
| lines must start with <code>*</code> aligned with the <code>*</code> on the previous line, to make |
| comments obvious with no extra context.</p> |
| |
| <pre><code class="language-js prettyprint good">/* |
| * This is |
| * okay. |
| */ |
| |
| // And so |
| // is this. |
| |
| /* This is fine, too. */ |
| </code></pre> |
| |
| <p>Comments are not enclosed in boxes drawn with asterisks or other characters.</p> |
| |
| <p>Do not use JSDoc (<code>/** … */</code>) for implementation comments.</p> |
| |
| <h4 id="formatting-param-name-comments">4.8.2 Parameter Name Comments</h4> |
| |
| <p>“Parameter name” comments should be used whenever the value and method name do |
| not sufficiently convey the meaning, and refactoring the method to be clearer is |
| infeasible . |
| Their preferred format is before the value with <q>=</q>:</p> |
| |
| <pre><code class="language-js prettyprint good">someFunction(obviousParam, /* shouldRender= */ true, /* name= */ 'hello'); |
| </code></pre> |
| |
| <p>For consistency with surrounding code you may put them after the value without |
| <q>=</q>:</p> |
| |
| <pre><code class="language-js prettyprint good">someFunction(obviousParam, true /* shouldRender */, 'hello' /* name */); |
| </code></pre> |
| |
| <h2 id="language-features">5 Language features</h2> |
| |
| <p>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.</p> |
| |
| <p>Language features which are not discussed in this style guide may be used with |
| no recommendations of their usage.</p> |
| |
| <h3 id="features-local-variable-declarations">5.1 Local variable declarations</h3> |
| |
| <h4 id="features-use-const-and-let">5.1.1 Use <code>const</code> and <code>let</code></h4> |
| |
| <p>Declare all local variables with either <code>const</code> or <code>let</code>. Use <code>const</code> by |
| default, unless a variable needs to be reassigned. The <code class="badcode">var</code> keyword |
| must not be used.</p> |
| |
| <h4 id="features-one-variable-per-declaration">5.1.2 One variable per declaration</h4> |
| |
| <p>Every local variable declaration declares only one variable: declarations such |
| as <code class="badcode">let a = 1, b = 2;</code> are not used.</p> |
| |
| <h4 id="features-declared-when-needed">5.1.3 Declared when needed, initialized as soon as possible</h4> |
| |
| <p>Local variables are <strong>not</strong> 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, and |
| initialized as soon as possible.</p> |
| |
| <h4 id="features-declare-types-as-needed">5.1.4 Declare types as needed</h4> |
| |
| <p>JSDoc type annotations may be added either on the line above the declaration, or |
| else inline before the variable name if no other JSDoc is present.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">const /** !Array<number> */ data = []; |
| |
| /** |
| * Some description. |
| * @type {!Array<number>} |
| */ |
| const data = []; |
| </code></pre> |
| |
| <p>Mixing inline and JSDoc styles is not allowed: the compiler will only process |
| the first JsDoc and the inline annotations will be lost.</p> |
| |
| <pre><code class="language-js prettyprint bad">/** Some description. */ |
| const /** !Array<number> */ data = []; |
| </code></pre> |
| |
| <p>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 |
| or constructor call does not include any values of the template parameter type |
| (e.g., empty arrays, objects, <code>Map</code>s, or <code>Set</code>s), or if the variable is modified |
| in a closure. Local variable type annotations are particularly helpful in these |
| cases since otherwise the compiler will infer the template parameter as unknown.</p> |
| |
| <h3 id="features-array-literals">5.2 Array literals</h3> |
| |
| <h4 id="features-arrays-trailing-comma">5.2.1 Use trailing commas</h4> |
| |
| |
| |
| <p>Include a trailing comma whenever there is a line break between the final |
| element and the closing bracket.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">const values = [ |
| 'first value', |
| 'second value', |
| ]; |
| </code></pre> |
| |
| <h4 id="features-arrays-ctor">5.2.2 Do not use the variadic <code>Array</code> constructor</h4> |
| |
| <p>The constructor is error-prone if arguments are added or removed. Use a literal |
| instead.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">const a1 = new Array(x1, x2, x3); |
| const a2 = new Array(x1, x2); |
| const a3 = new Array(x1); |
| const a4 = new Array(); |
| </code></pre> |
| |
| <p>This works as expected except for the third case: if <code>x1</code> is a whole number then |
| <code>a3</code> is an array of size <code>x1</code> where all elements are <code>undefined</code>. If <code>x1</code> is any |
| other number, then an exception will be thrown, and if it is anything else then |
| it will be a single-element array.</p> |
| |
| <p>Instead, write</p> |
| |
| <pre><code class="language-js prettyprint good">const a1 = [x1, x2, x3]; |
| const a2 = [x1, x2]; |
| const a3 = [x1]; |
| const a4 = []; |
| </code></pre> |
| |
| <p>Explicitly allocating an array of a given length using <code>new Array(length)</code> is |
| allowed when appropriate.</p> |
| |
| <h4 id="features-arrays-non-numeric-properties">5.2.3 Non-numeric properties</h4> |
| |
| <p>Do not define or use non-numeric properties on an array (other than <code>length</code>). |
| Use a <code>Map</code> (or <code>Object</code>) instead.</p> |
| |
| <h4 id="features-arrays-destructuring">5.2.4 Destructuring</h4> |
| |
| <p>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 <q>rest</q> element may be included (with no space between the |
| <code>...</code> and the variable name). Elements should be omitted if they are unused.</p> |
| |
| <pre><code class="language-js prettyprint good">const [a, b, c, ...rest] = generateResults(); |
| let [, b,, d] = someArray; |
| </code></pre> |
| |
| <p>Destructuring may also be used for function parameters (note that a parameter |
| name is required but ignored). Always specify <code>[]</code> as the default value if a |
| destructured array parameter is optional, and provide default values on the left |
| hand side:</p> |
| |
| <pre><code class="language-js prettyprint good">/** @param {!Array<number>=} param1 */ |
| function optionalDestructuring([a = 4, b = 2] = []) { … }; |
| </code></pre> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">function badDestructuring([a, b] = [4, 2]) { … }; |
| </code></pre> |
| |
| <p>Tip: For (un)packing multiple values into a function’s parameter or return, |
| prefer object destructuring to array destructuring when possible, as it allows |
| naming the individual elements and specifying a different type for each.</p> |
| |
| <h4 id="features-arrays-spread-operator">5.2.5 Spread operator</h4> |
| |
| <p>Array literals may include the spread operator (<code>...</code>) to flatten elements out |
| of one or more other iterables. The spread operator should be used instead of |
| more awkward constructs with <code>Array.prototype</code>. There is no space after the |
| <code>...</code>.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">[...foo] // preferred over Array.prototype.slice.call(foo) |
| [...foo, ...bar] // preferred over foo.concat(bar) |
| </code></pre> |
| |
| <h3 id="features-object-literals">5.3 Object literals</h3> |
| |
| <h4 id="features-objects-use-trailing-comma">5.3.1 Use trailing commas</h4> |
| |
| <p>Include a trailing comma whenever there is a line break between the final |
| property and the closing brace.</p> |
| |
| <h4 id="features-objects-ctor">5.3.2 Do not use the <code>Object</code> constructor</h4> |
| |
| <p>While <code>Object</code> does not have the same problems as <code>Array</code>, it is still |
| disallowed for consistency. Use an object literal (<code>{}</code> or <code>{a: 0, b: 1, c: 2}</code>) |
| instead.</p> |
| |
| <h4 id="features-objects-mixing-keys">5.3.3 Do not mix quoted and unquoted keys</h4> |
| |
| <p>Object literals may represent either <em>structs</em> (with unquoted keys and/or |
| symbols) or <em>dicts</em> (with quoted and/or computed keys). Do not mix these key |
| types in a single object literal.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">{ |
| width: 42, // struct-style unquoted key |
| 'maxWidth': 43, // dict-style quoted key |
| } |
| </code></pre> |
| |
| <p>This also extends to passing the property name to functions, like |
| <code>hasOwnProperty</code>. In particular, doing so will break in compiled code because |
| the compiler cannot rename/obfuscate the string literal.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">/** @type {{width: number, maxWidth: (number|undefined)}} */ |
| const o = {width: 42}; |
| if (o.hasOwnProperty('maxWidth')) { |
| ... |
| } |
| </code></pre> |
| |
| <p>This is best implemented as:</p> |
| |
| <pre><code class="language-js prettyprint good">/** @type {{width: number, maxWidth: (number|undefined)}} */ |
| const o = {width: 42}; |
| if (o.maxWidth != null) { |
| ... |
| } |
| </code></pre> |
| |
| <h4 id="features-objects-computed-property-names">5.3.4 Computed property names</h4> |
| |
| <p>Computed property names (e.g., <code>{['key' + foo()]: 42}</code>) are allowed, and are |
| considered dict-style (quoted) keys (i.e., must not be mixed with non-quoted |
| keys) unless the computed property is a |
| <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol">symbol</a> |
| (e.g., <code>[Symbol.iterator]</code>). Enum values may also be used for computed keys, but |
| should not be mixed with non-enum keys in the same literal.</p> |
| |
| <h4 id="features-objects-method-shorthand">5.3.5 Method shorthand</h4> |
| |
| <p>Methods can be defined on object literals using the method shorthand (<code>{method() |
| {… }}</code>) in place of a colon immediately followed by a <code>function</code> or arrow |
| function literal.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">return { |
| stuff: 'candy', |
| method() { |
| return this.stuff; // Returns 'candy' |
| }, |
| }; |
| </code></pre> |
| |
| <p>Note that <code>this</code> in a method shorthand or <code>function</code> refers to the object |
| literal itself whereas <code>this</code> in an arrow function refers to the scope outside |
| the object literal.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">class { |
| getObjectLiteral() { |
| this.stuff = 'fruit'; |
| return { |
| stuff: 'candy', |
| method: () => this.stuff, // Returns 'fruit' |
| }; |
| } |
| } |
| </code></pre> |
| |
| <h4 id="features-objects-shorthand-properties">5.3.6 Shorthand properties</h4> |
| |
| <p>Shorthand properties are allowed on object literals.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">const foo = 1; |
| const bar = 2; |
| const obj = { |
| foo, |
| bar, |
| method() { return this.foo + this.bar; }, |
| }; |
| assertEquals(3, obj.method()); |
| </code></pre> |
| |
| <h4 id="features-objects-destructuring">5.3.7 Destructuring</h4> |
| |
| <p>Object destructuring patterns may be used on the left-hand side of an assignment |
| to perform destructuring and unpack multiple values from a single object.</p> |
| |
| <p>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 (<code>{str = 'some default'} = {}</code>, rather than |
| <code class="badcode">{str} = {str: 'some default'}</code>), and if a |
| destructured object is itself optional, it must default to <code>{}</code>. The JSDoc for |
| the destructured parameter may be given any name (the name is unused but is |
| required by the compiler).</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * @param {string} ordinary |
| * @param {{num: (number|undefined), str: (string|undefined)}=} param1 |
| * num: The number of times to do something. |
| * str: A string to do stuff to. |
| */ |
| function destructured(ordinary, {num, str = 'some default'} = {}) {} |
| </code></pre> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">/** @param {{x: {num: (number|undefined), str: (string|undefined)}}} param1 */ |
| function nestedTooDeeply({x: {num, str}}) {}; |
| /** @param {{num: (number|undefined), str: (string|undefined)}=} param1 */ |
| function nonShorthandProperty({num: a, str: b} = {}) {}; |
| /** @param {{a: number, b: number}} param1 */ |
| function computedKey({a, b, [a + b]: c}) {}; |
| /** @param {{a: number, b: string}=} param1 */ |
| function nontrivialDefault({a, b} = {a: 2, b: 4}) {}; |
| </code></pre> |
| |
| <p>Destructuring may also be used for <code>goog.require</code> statements, and in this case |
| must not be wrapped: the entire statement occupies one line, regardless of how |
| long it is (see <a href="#file-goog-require">??</a>).</p> |
| |
| <h4 id="features-objects-enums">5.3.8 Enums</h4> |
| |
| <p>Enumerations are defined by adding the <code>@enum</code> annotation to an object literal. |
| Enums must be module-local or assigned directly on <code>exports</code>, not nested under a |
| type or object.</p> |
| |
| <p>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.</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * Supported temperature scales. |
| * @enum {string} |
| */ |
| const TemperatureScale = { |
| CELSIUS: 'celsius', |
| FAHRENHEIT: 'fahrenheit', |
| }; |
| |
| /** |
| * An enum with two values. |
| * @enum {number} |
| */ |
| const Value = { |
| /** The value used shall have been the first. */ |
| FIRST_VALUE: 1, |
| /** The second among two values. */ |
| SECOND_VALUE: 2, |
| }; |
| </code></pre> |
| |
| <p>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.</p> |
| |
| <pre><code class="language-js prettyprint bad">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', |
| }; |
| </code></pre> |
| |
| <p>Note: Although TypeScript supports a few more patterns for enum values (e.g <code>A: |
| 'a'+'b'</code>, 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 <code>@enum</code>. </p> |
| |
| <h3 id="features-classes">5.4 Classes</h3> |
| |
| <h4 id="features-classes-constructors">5.4.1 Constructors</h4> |
| |
| <p>Constructors are optional. Subclass constructors must call <code>super()</code> before |
| setting any fields or otherwise accessing <code>this</code>. Interfaces should declare |
| non-method properties in the constructor.</p> |
| |
| <h4 id="features-classes-fields">5.4.2 Fields</h4> |
| |
| <p>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 |
| <code>@const</code> (these need not be deeply immutable). Annotate non-public fields with |
| the proper visibility annotation (<code>@private</code>, <code>@protected</code>, <code>@package</code>). |
| <code>@private</code> fields' 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 |
| <code>prototype</code>.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">class Foo { |
| constructor() { |
| /** @private @const {!Bar} */ |
| this.bar_ = computeBar(); |
| |
| /** @protected @const {!Baz} */ |
| this.baz = computeBaz(); |
| } |
| } |
| </code></pre> |
| |
| <p>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 |
| set to <code>undefined</code> in the constructor to prevent later shape changes. Adding |
| <code>@struct</code> to an object will check that undeclared properties are not |
| added/accessed. Classes have this added by default.</p> |
| |
| <h4 id="features-classes-computed-properties">5.4.3 Computed properties</h4> |
| |
| |
| |
| <p>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 <a href="#features-objects-mixing-keys">??</a>) are not allowed. A <code>[Symbol.iterator]</code> |
| method should be defined for any classes that are logically iterable. Beyond |
| this, <code>Symbol</code> should be used sparingly.</p> |
| |
| <p>Tip: be careful of using any other built-in symbols (e.g., |
| <code>Symbol.isConcatSpreadable</code>) as they are not polyfilled by the compiler and will |
| therefore not work in older browsers.</p> |
| |
| <h4 id="features-classes-static-methods">5.4.4 Static methods</h4> |
| |
| |
| |
| <p>Where it does not interfere with readability, prefer module-local functions over |
| private static methods.</p> |
| |
| <p>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 <code>@nocollapse</code> if this is done), |
| and must not be called directly on a subclass that doesn’t define the method |
| itself. Do not access <code>this</code> in static methods.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">// Context for the examples below; by itself this code is allowed. |
| class Base { |
| /** @nocollapse */ static foo() {} |
| } |
| class Sub extends Base {} |
| |
| // 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; |
| </code></pre> |
| |
| <h4 id="features-classes-old-style">5.4.5 Old-style class declarations</h4> |
| |
| <p>While ES6 classes are preferred, there are cases where ES6 classes may not be |
| feasible. For example:</p> |
| |
| <ol> |
| <li><p>If there exist or will exist subclasses, including frameworks that create |
| 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.</p></li> |
| <li><p>Frameworks that require a known <code>this</code> value before calling the superclass |
| constructor, since constructors with ES6 super classes do not have access to |
| the instance <code>this</code> value until the call to <code>super</code> returns.</p></li> |
| </ol> |
| |
| <p>In all other ways the style guide still applies to this code: <code>let</code>, <code>const</code>, |
| default parameters, rest, and arrow functions should all be used when |
| appropriate.</p> |
| |
| <p><code>goog.defineClass</code> allows for a class-like definition similar to ES6 class |
| syntax:</p> |
| |
| <pre><code class="language-js prettyprint good">let C = goog.defineClass(S, { |
| /** |
| * @param {string} value |
| */ |
| constructor(value) { |
| S.call(this, 2); |
| /** @const */ |
| this.prop = value; |
| }, |
| |
| /** |
| * @param {string} param |
| * @return {number} |
| */ |
| method(param) { |
| return 0; |
| }, |
| }); |
| </code></pre> |
| |
| <p>Alternatively, while <code>goog.defineClass</code> should be preferred for all new code, |
| more traditional syntax is also allowed.</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * @constructor @extends {S} |
| * @param {string} value |
| */ |
| function C(value) { |
| S.call(this, 2); |
| /** @const */ |
| this.prop = value; |
| } |
| goog.inherits(C, S); |
| |
| /** |
| * @param {string} param |
| * @return {number} |
| */ |
| C.prototype.method = function(param) { |
| return 0; |
| }; |
| </code></pre> |
| |
| <p>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.</p> |
| |
| <p>Defining constructor prototype hierarchies correctly is harder than it first |
| appears! For that reason, it is best to use <code>goog.inherits</code> from |
| <a href="http://code.google.com/closure/library/">the Closure Library </a>.</p> |
| |
| <h4 id="features-classes-prototypes">5.4.6 Do not manipulate <code>prototype</code>s directly</h4> |
| |
| <p>The <code>class</code> keyword allows clearer and more readable class definitions than |
| defining <code>prototype</code> properties. Ordinary implementation code has no business |
| manipulating these objects, though they are still useful for defining classes as |
| defined in <a href="#features-classes-old-style">??</a>. Mixins and modifying the |
| prototypes of builtin objects are explicitly forbidden.</p> |
| |
| <p><strong>Exception</strong>: Framework code (such as Polymer, or Angular) may need to use <code>prototype</code>s, and should not resort |
| to even-worse workarounds to avoid doing so.</p> |
| |
| <h4 id="features-classes-getters-and-setters">5.4.7 Getters and Setters</h4> |
| |
| <p>Do not use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get">JavaScript getter and setter properties</a>. They are potentially |
| surprising and difficult to reason about, and have limited support in the |
| compiler. Provide ordinary methods instead.</p> |
| |
| <p><strong>Exception</strong>: 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, |
| getters and setters may be used <em>with caution</em>, provided they are defined with |
| the <code>get</code> and <code>set</code> shorthand method keywords or <code>Object.defineProperties</code> (not |
| <code>Object.defineProperty</code>, which interferes with property renaming). Getters |
| <strong>must not</strong> change observable state.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">class Foo { |
| get next() { return this.nextId++; } |
| } |
| </code></pre> |
| |
| <h4 id="features-classes-overriding-tostring">5.4.8 Overriding toString</h4> |
| |
| <p>The <code>toString</code> method may be overridden, but must always succeed and never have |
| visible side effects.</p> |
| |
| <p>Tip: Beware, in particular, of calling other methods from toString, since |
| exceptional conditions could lead to infinite loops.</p> |
| |
| <h4 id="features-classes-interfaces">5.4.9 Interfaces</h4> |
| |
| <p>Interfaces may be declared with <code>@interface</code> or <code>@record</code>. Interfaces declared |
| with <code>@record</code> can be explicitly (i.e. via <code>@implements</code>) or implicitly |
| implemented by a class or object literal.</p> |
| |
| <p>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.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * Something that can frobnicate. |
| * @record |
| */ |
| class Frobnicator { |
| constructor() { |
| /** @type {number} The number of attempts before giving up. */ |
| this.attempts; |
| } |
| |
| /** |
| * Performs the frobnication according to the given strategy. |
| * @param {!FrobnicationStrategy} strategy |
| */ |
| frobnicate(strategy) {} |
| } |
| |
| </code></pre> |
| |
| <h4 id="features-classes-abstract-classes">5.4.10 Abstract Classes</h4> |
| |
| <p>Use abstract classes when appropriate. Abstract classes and methods must be |
| annotated with <code>@abstract</code>. Do not use <code>goog.abstractMethod</code>. See |
| <a href="https://github.com/google/closure-compiler/wiki/@abstract-classes-and-methods">abstract classes and methods</a>.</p> |
| |
| <h4 id="static-containers">5.4.11 Do not create static container classes</h4> |
| |
| <p>Do not use container classes with only static methods or properties for the sake |
| of namespacing.</p> |
| |
| <pre><code class="language-js prettyprint bad">// 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}; |
| </code></pre> |
| |
| <p>Instead, export individual constants and functions:</p> |
| |
| <pre><code class="language-js prettyprint good">/** @return {number} */ |
| exports.bar = () => { |
| return 1; |
| } |
| |
| /** @const {number} */ |
| exports.FOO = 1; |
| </code></pre> |
| |
| <h4 id="nested-namespaces">5.4.12 Do not define nested namespaces</h4> |
| |
| <p>Do not define a nested type (e.g. class, typedef, enum, interface) on another |
| module-local name. </p> |
| |
| <pre><code class="language-js prettyprint bad">// 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; |
| </code></pre> |
| |
| <p>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: <code>foo.Foo</code> and <code>foo.Converter</code> rather than <code>foo.Foo</code> and |
| <code>foo.FooConverter</code>. Importers can add the prefix when necessary for clarity |
| (e.g. <code>import {Converter as FooConverter} from './foo';</code>) but cannot easily |
| remove the redundancy when importing the entire module as a namespace.</p> |
| |
| <pre><code class="language-js prettyprint good">// 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, |
| }; |
| </code></pre> |
| |
| <h3 id="features-functions">5.5 Functions</h3> |
| |
| <h4 id="features-functions-top-level-functions">5.5.1 Top-level functions</h4> |
| |
| <p>Top-level functions may be defined directly on the <code>exports</code> object, or else |
| declared locally and optionally exported. See <a href="#file-goog-module-exports">??</a> |
| for more on exports.</p> |
| |
| <p>Examples:</p> |
| |
| <pre><code class="language-js prettyprint good">/** @param {string} str */ |
| exports.processString = (str) => { |
| // Process the string. |
| }; |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint good">/** @param {string} str */ |
| const processString = (str) => { |
| // Process the string. |
| }; |
| |
| exports = {processString}; |
| </code></pre> |
| |
| <h4 id="features-functions-nested-functions">5.5.2 Nested functions and closures</h4> |
| |
| <p>Functions may contain nested function definitions. If it is useful to give the |
| function a name, it should be assigned to a local <code>const</code>.</p> |
| |
| <h4 id="features-functions-arrow-functions">5.5.3 Arrow functions</h4> |
| |
| <p>Arrow functions provide a concise function syntax and simplify scoping <code>this</code> |
| for nested functions. Prefer arrow functions over the <code>function</code> keyword for |
| nested functions (but see <a href="#features-objects-method-shorthand">??</a>).</p> |
| |
| <p>Prefer arrow functions over other <code>this</code> scoping approaches such as |
| <code>f.bind(this)</code>, <code>goog.bind(f, this)</code>, and <code>const self = this</code>. Arrow functions |
| are particularly useful for calling into callbacks as they permit explicitly |
| specifying which parameters to pass to the callback whereas binding will blindly |
| pass along all parameters.</p> |
| |
| <p>The left-hand side of the arrow contains zero or more parameters. Parentheses |
| around the parameters are optional if there is only a single non-destructured |
| parameter. When parentheses are used, inline parameter types may be specified |
| (see <a href="#jsdoc-method-and-function-comments">??</a>).</p> |
| |
| <p>Tip: Always using parentheses even for single-parameter arrow functions can |
| avoid situations where adding parameters, but forgetting to add parentheses, may |
| result in parseable code which no longer works as intended.</p> |
| |
| <p>The right-hand side of the arrow contains the body of the function. By default |
| the body is a block statement (zero or more statements surrounded by curly |
| braces). The body may also be an implicitly returned single expression if |
| either: the program logic requires returning a value, or the <code>void</code> operator |
| precedes a single function or method call (using <code>void</code> ensures <code>undefined</code> is |
| returned, prevents leaking values, and communicates intent). The single |
| expression form is preferred if it improves readability (e.g., for short or |
| simple expressions).</p> |
| |
| <p>Examples:</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * Arrow functions can be documented just like normal functions. |
| * @param {number} numParam A number to add. |
| * @param {string} strParam Another number to add that happens to be a string. |
| * @return {number} The sum of the two parameters. |
| */ |
| const moduleLocalFunc = (numParam, strParam) => numParam + Number(strParam); |
| |
| // Uses the single expression syntax with `void` because the program logic does |
| // not require returning a value. |
| getValue((result) => void alert(`Got ${result}`)); |
| |
| class CallbackExample { |
| constructor() { |
| /** @private {number} */ |
| this.cachedValue_ = 0; |
| |
| // For inline callbacks, you can use inline typing for parameters. |
| // Uses a block statement because the value of the single expression should |
| // not be returned and the expression is not a single function call. |
| getNullableValue((/** ?number */ result) => { |
| this.cachedValue_ = result == null ? 0 : result; |
| }); |
| } |
| } |
| </code></pre> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">/** |
| * A function with no params and no returned value. |
| * This single expression body usage is illegal because the program logic does |
| * not require returning a value and we're missing the `void` operator. |
| */ |
| const moduleLocalFunc = () => anotherFunction(); |
| </code></pre> |
| |
| <h4 id="features-functions-generators">5.5.4 Generators</h4> |
| |
| <p>Generators enable a number of useful abstractions and may be used as needed.</p> |
| |
| <p>When defining generator functions, attach the <code>*</code> to the <code>function</code> keyword when |
| present, and separate it with a space from the name of the function. When using |
| delegating yields, attach the <code>*</code> to the <code>yield</code> keyword.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">/** @return {!Iterator<number>} */ |
| function* gen1() { |
| yield 42; |
| } |
| |
| /** @return {!Iterator<number>} */ |
| const gen2 = function*() { |
| yield* gen1(); |
| } |
| |
| class SomeClass { |
| /** @return {!Iterator<number>} */ |
| * gen() { |
| yield 42; |
| } |
| } |
| </code></pre> |
| |
| <h4 id="features-functions-parameter-return-types">5.5.5 Parameter and return types</h4> |
| |
| <p>Function parameters and return types should usually be documented with JSDoc |
| annotations. See <a href="#jsdoc-method-and-function-comments">??</a> for more information.</p> |
| |
| <h5 id="features-functions-default-parameters">5.5.5.1 Default parameters</h5> |
| |
| <p>Optional parameters are permitted using the equals operator in the parameter |
| list. Optional parameters must include spaces on both sides of the equals |
| operator, be named exactly like required parameters (i.e., not prefixed with |
| <code>opt_</code>), use the <code>=</code> suffix in their JSDoc type, come after required parameters, |
| and not use initializers that produce observable side effects. All optional |
| parameters for concrete functions must have default values, even if that value |
| is <code>undefined</code>. In contrast to concrete functions, abstract and interface |
| methods must omit default parameter values.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * @param {string} required This parameter is always needed. |
| * @param {string=} optional This parameter can be omitted. |
| * @param {!Node=} node Another optional parameter. |
| */ |
| function maybeDoSomething(required, optional = '', node = undefined) {} |
| |
| /** @interface */ |
| class MyInterface { |
| /** |
| * Interface and abstract methods must omit default parameter values. |
| * @param {string=} optional |
| */ |
| someMethod(optional) {} |
| } |
| </code></pre> |
| |
| <p>Use default parameters sparingly. Prefer destructuring (as in |
| <a href="#features-objects-destructuring">??</a>) to create readable APIs when there are |
| more than a small handful of optional parameters that do not have a natural |
| order.</p> |
| |
| <p>Note: Unlike Python's default parameters, it is okay to use initializers that |
| return new mutable objects (such as <code>{}</code> or <code>[]</code>) because the initializer is |
| evaluated each time the default value is used, so a single object won't be |
| shared across invocations.</p> |
| |
| <p>Tip: While arbitrary expressions including function calls may be used as |
| initializers, these should be kept as simple as possible. Avoid initializers |
| that expose shared mutable state, as that can easily introduce unintended |
| coupling between function calls.</p> |
| |
| <h5 id="features-functions-rest-parameters">5.5.5.2 Rest parameters</h5> |
| |
| <p>Use a <em>rest</em> parameter instead of accessing <code>arguments</code>. Rest parameters are |
| typed with a <code>...</code> prefix in their JSDoc. The rest parameter must be the last |
| parameter in the list. There is no space between the <code>...</code> and the parameter |
| name. Do not name the rest parameter <code>var_args</code>. Never name a local variable or |
| parameter <code>arguments</code>, which confusingly shadows the built-in name.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * @param {!Array<string>} array This is an ordinary parameter. |
| * @param {...number} numbers The remainder of arguments are all numbers. |
| */ |
| function variadic(array, ...numbers) {} |
| </code></pre> |
| |
| <h4 id="features-functions-generics">5.5.6 Generics</h4> |
| |
| <p>Declare generic functions and methods when necessary with <code>@template TYPE</code> in |
| the JSDoc above the function or method definition.</p> |
| |
| <h4 id="features-functions-spread-operator">5.5.7 Spread operator</h4> |
| |
| <p>Function calls may use the spread operator (<code>...</code>). Prefer the spread operator |
| to <code>Function.prototype.apply</code> when an array or iterable is unpacked into |
| multiple parameters of a variadic function. There is no space after the <code>...</code>.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">function myFunction(...elements) {} |
| myFunction(...array, ...iterable, ...generator()); |
| </code></pre> |
| |
| <h3 id="features-string-literals">5.6 String literals</h3> |
| |
| <h4 id="features-strings-use-single-quotes">5.6.1 Use single quotes</h4> |
| |
| <p>Ordinary string literals are delimited with single quotes (<code>'</code>), rather than |
| double quotes (<code>"</code>).</p> |
| |
| <p>Tip: if a string contains a single quote character, consider using a template |
| string to avoid having to escape the quote.</p> |
| |
| <p>Ordinary string literals may not span multiple lines.</p> |
| |
| <h4 id="features-strings-template-strings">5.6.2 Template literals</h4> |
| |
| <p>Use template literals (delimited with <code>`</code>) over complex string |
| concatenation, particularly if multiple string literals are involved. Template |
| literals may span multiple lines.</p> |
| |
| <p>If a template literal spans multiple lines, it does not need to follow the |
| indentation of the enclosing block, though it may if the added whitespace does |
| not matter.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">function arithmetic(a, b) { |
| return `Here is a table of arithmetic operations: |
| ${a} + ${b} = ${a + b} |
| ${a} - ${b} = ${a - b} |
| ${a} * ${b} = ${a * b} |
| ${a} / ${b} = ${a / b}`; |
| } |
| </code></pre> |
| |
| <h4 id="features-strings-no-line-continuations">5.6.3 No line continuations</h4> |
| |
| <p>Do not use <em>line continuations</em> (that is, ending a line inside a string literal |
| with a backslash) in either ordinary or template string literals. Even though |
| ES5 allows this, it can lead to tricky errors if any trailing whitespace comes |
| after the slash, and is less obvious to readers.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">const longString = 'This is a very long string that far exceeds the 80 \ |
| column limit. It unfortunately contains long stretches of spaces due \ |
| to how the continued lines are indented.'; |
| </code></pre> |
| |
| <p>Instead, write</p> |
| |
| <pre><code class="language-js prettyprint good">const longString = 'This is a very long string that far exceeds the 80 ' + |
| 'column limit. It does not contain long stretches of spaces since ' + |
| 'the concatenated strings are cleaner.'; |
| </code></pre> |
| |
| <h3 id="features-number-literals">5.7 Number literals</h3> |
| |
| <p>Numbers may be specified in decimal, hex, octal, or binary. Use exactly <code>0x</code>, |
| <code>0o</code>, and <code>0b</code> prefixes, with lowercase letters, for hex, octal, and binary, |
| respectively. Never include a leading zero unless it is immediately followed by |
| <code>x</code>, <code>o</code>, or <code>b</code>.</p> |
| |
| <h3 id="features-control-structures">5.8 Control structures</h3> |
| |
| <h4 id="features-for-loops">5.8.1 For loops</h4> |
| |
| <p>With ES6, the language now has three different kinds of <code>for</code> loops. All may be |
| used, though <code>for</code>-<code>of</code> loops should be preferred when possible.</p> |
| |
| <p><code>for</code>-<code>in</code> loops may only be used on dict-style objects (see |
| <a href="#features-objects-mixing-keys">??</a>), and should not be used to iterate over an |
| array. <code>Object.prototype.hasOwnProperty</code> should be used in <code>for</code>-<code>in</code> loops to |
| exclude unwanted prototype properties. Prefer <code>for</code>-<code>of</code> and <code>Object.keys</code> over |
| <code>for</code>-<code>in</code> when possible.</p> |
| |
| <h4 id="features-exceptions">5.8.2 Exceptions</h4> |
| |
| <p>Exceptions are an important part of the language and should be used whenever |
| exceptional cases occur. Always throw <code>Error</code>s or subclasses of <code>Error</code>: never |
| throw string literals or other objects. Always use <code>new</code> when constructing an |
| <code>Error</code>.</p> |
| |
| <p>This treatment extends to <code>Promise</code> rejection values as <code>Promise.reject(obj)</code> is |
| equivalent to <code>throw obj;</code> in async functions.</p> |
| |
| <p>Custom exceptions provide a great way to convey additional error information |
| from functions. They should be defined and used wherever the native <code>Error</code> type |
| is insufficient.</p> |
| |
| <p>Prefer throwing exceptions over ad-hoc error-handling approaches (such as |
| passing an error container reference type, or returning an object with an error |
| property).</p> |
| |
| <h5 id="features-empty-catch-blocks">5.8.2.1 Empty catch blocks</h5> |
| |
| <p>It is very rarely correct to do nothing in response to a caught exception. When |
| it truly is appropriate to take no action whatsoever in a catch block, the |
| reason this is justified is explained in a comment.</p> |
| |
| <pre><code class="language-js prettyprint good">try { |
| return handleNumericResponse(response); |
| } catch (ok) { |
| // it's not numeric; that's fine, just continue |
| } |
| return handleTextResponse(response); |
| </code></pre> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad"> try { |
| shouldFail(); |
| fail('expected an error'); |
| } catch (expected) { |
| } |
| </code></pre> |
| |
| <p>Tip: Unlike in some other languages, patterns like the above simply don’t work |
| since this will catch the error thrown by <code>fail</code>. Use <code>assertThrows()</code> instead.</p> |
| |
| <h4 id="features-switch-statements">5.8.3 Switch statements</h4> |
| |
| <p>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 <code>case |
| FOO:</code> or <code>default:</code>), followed by one or more statements.</p> |
| |
| <h5 id="features-switch-fall-through">5.8.3.1 Fall-through: commented</h5> |
| |
| <p>Within a switch block, each statement group either terminates abruptly (with a |
| <code>break</code>, <code>return</code> or <code>throw</code>n 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 |
| <code>// fall through</code>). This special comment is not required in the last statement |
| group of the switch block.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">switch (input) { |
| case 1: |
| case 2: |
| prepareOneOrTwo(); |
| // fall through |
| case 3: |
| handleOneTwoOrThree(); |
| break; |
| default: |
| handleLargeNumber(input); |
| } |
| </code></pre> |
| |
| <h5 id="features-switch-default-case">5.8.3.2 The <code>default</code> case is present</h5> |
| |
| <p>Each switch statement includes a <code>default</code> statement group, even if it contains |
| no code. The <code>default</code> statement group must be last.</p> |
| |
| <h3 id="features-this">5.9 this</h3> |
| |
| <p>Only use <code>this</code> in class constructors and methods, in arrow functions defined |
| within class constructors and methods, or in functions that have an explicit |
| <code>@this</code> declared in the immediately-enclosing function’s JSDoc.</p> |
| |
| <p>Never use <code>this</code> to refer to the global object, the context of an <code>eval</code>, the |
| target of an event, or unnecessarily <code>call()</code>ed or <code>apply()</code>ed functions.</p> |
| |
| <h3 id="features-equality-checks">5.10 Equality Checks</h3> |
| |
| <p>Use identity operators (<code>===</code>/<code>!==</code>) except in the cases documented below.</p> |
| |
| <h4 id="features-equality-checks-exceptions">5.10.1 Exceptions Where Coercion is Desirable</h4> |
| |
| <p>Catching both <code>null</code> and <code>undefined</code> values:</p> |
| |
| <pre><code class="language-js prettyprint good">if (someObjectOrPrimitive == null) { |
| // Checking for null catches both null and undefined for objects and |
| // primitives, but does not catch other falsy values like 0 or the empty |
| // string. |
| } |
| </code></pre> |
| |
| <h3 id="disallowed-features">5.11 Disallowed features</h3> |
| |
| <h4 id="disallowed-features-with">5.11.1 with</h4> |
| |
| <p>Do not use the <code>with</code> keyword. It makes your code harder to understand and has |
| been banned in strict mode since ES5.</p> |
| |
| <h4 id="disallowed-features-dynamic-code-evaluation">5.11.2 Dynamic code evaluation</h4> |
| |
| <p>Do not use <code>eval</code> or the <code>Function(...string)</code> constructor (except for code |
| loaders). These features are potentially dangerous and simply do not work in CSP |
| environments.</p> |
| |
| <h4 id="disallowed-features-automatic-semicolon-insertion">5.11.3 Automatic semicolon insertion</h4> |
| |
| <p>Always terminate statements with semicolons (except function and class |
| declarations, as noted above).</p> |
| |
| <h4 id="disallowed-features-non-standard-features">5.11.4 Non-standard features</h4> |
| |
| <p>Do not use non-standard features. This includes old features that have been |
| removed (e.g., <code>WeakMap.clear</code>), 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 |
| language “extensions” (such as those provided by some external transpilers) are |
| forbidden.</p> |
| |
| <h4 id="disallowed-features-wrapper-objects">5.11.5 Wrapper objects for primitive types</h4> |
| |
| <p>Never use <code>new</code> on the primitive object wrappers (<code>Boolean</code>, <code>Number</code>, <code>String</code>, |
| <code>Symbol</code>), nor include them in type annotations.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">const /** Boolean */ x = new Boolean(false); |
| if (x) alert(typeof x); // alerts 'object' - WAT? |
| </code></pre> |
| |
| <p>The wrappers may be called as functions for coercing (which is preferred over |
| using <code>+</code> or concatenating the empty string) or creating symbols.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">const /** boolean */ x = Boolean(0); |
| if (!x) alert(typeof x); // alerts 'boolean', as expected |
| </code></pre> |
| |
| <h4 id="disallowed-features-modifying-builtin-objects">5.11.6 Modifying builtin objects</h4> |
| |
| <p>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 |
| JSCompiler’s runtime library will provide standards-compliant polyfills where |
| possible; nothing else may modify builtin objects.</p> |
| |
| <p>Do not add symbols to the global object unless absolutely necessary (e.g. |
| required by a third-party API).</p> |
| |
| <h4 id="disallowed-features-omitting-parents-with-new">5.11.7 Omitting <code>()</code> when invoking a constructor</h4> |
| |
| <p>Never invoke a constructor in a <code>new</code> statement without using parentheses <code>()</code>.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">new Foo; |
| </code></pre> |
| |
| <p>Use instead:</p> |
| |
| <pre><code class="language-js prettyprint good">new Foo(); |
| </code></pre> |
| |
| <p>Omitting parentheses can lead to subtle mistakes. These two lines are not |
| equivalent:</p> |
| |
| <pre><code class="language-js prettyprint good">new Foo().Bar(); |
| new Foo.Bar(); |
| </code></pre> |
| |
| <h2 id="naming">6 Naming</h2> |
| |
| <h3 id="naming-rules-common-to-all-identifiers">6.1 Rules common to all identifiers</h3> |
| |
| <p>Identifiers use only ASCII letters and digits, and, in a small number of cases |
| noted below, underscores and very rarely (when required by frameworks like |
| Angular) dollar signs.</p> |
| |
| <p>Give as descriptive a name as possible, within reason. Do not worry about saving |
| horizontal space as it is far more important to make your code immediately |
| understandable by a new reader. Do not use abbreviations that are ambiguous or |
| unfamiliar to readers outside your project, and do not abbreviate by deleting |
| letters within a word.</p> |
| |
| <pre><code class="language-js prettyprint good">errorCount // No abbreviation. |
| dnsConnectionIndex // Most people know what "DNS" stands for. |
| referrerUrl // Ditto for "URL". |
| customerId // "Id" is both ubiquitous and unlikely to be misunderstood. |
| </code></pre> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">n // Meaningless. |
| nErr // Ambiguous abbreviation. |
| nCompConns // Ambiguous abbreviation. |
| wgcConnections // Only your group knows what this stands for. |
| pcReader // Lots of things can be abbreviated "pc". |
| cstmrId // Deletes internal letters. |
| kSecondsPerDay // Do not use Hungarian notation. |
| </code></pre> |
| |
| <p><strong>Exception</strong>: Variables that are in scope for 10 lines or fewer, including |
| arguments that are <em>not</em> part of an exported API, <em>may</em> use short (e.g. single |
| letter) variable names.</p> |
| |
| <h3 id="naming-rules-by-identifier-type">6.2 Rules by identifier type</h3> |
| |
| <h4 id="naming-package-names">6.2.1 Package names</h4> |
| |
| <p>Package names are all <code>lowerCamelCase</code>. For example, <code>my.exampleCode.deepSpace</code>, |
| but not <code class="badcode">my.examplecode.deepspace</code> or |
| <code class="badcode">my.example_code.deep_space</code>.</p> |
| |
| <p><strong>Exception</strong>: The package name may conform to TypeScript's path-based pattern. This is |
| typically all lower case with underscores where present in filenames.</p> |
| |
| <h4 id="naming-class-names">6.2.2 Class names</h4> |
| |
| <p>Class, interface, record, and typedef names are written in <code>UpperCamelCase</code>. |
| Unexported classes are simply locals: they are not marked <code>@private</code>.</p> |
| |
| <p>Type names are typically nouns or noun phrases. For example, <code>Request</code>, |
| <code>ImmutableView</code>, or <code>VisibilityMode</code>. Additionally, interface names may |
| sometimes be adjectives or adjective phrases instead (for example, <code>Readable</code>).</p> |
| |
| <h4 id="naming-method-names">6.2.3 Method names</h4> |
| |
| <p>Method names are written in <code>lowerCamelCase</code>. Names for <code>@private</code> methods may |
| optionally end with a trailing underscore.</p> |
| |
| <p>Method names are typically verbs or verb phrases. For example, <code>sendMessage</code> or |
| <code>stop_</code>. Getter and setter methods for properties are never required, but if |
| they are used they should be named <code>getFoo</code> (or optionally <code>isFoo</code> or <code>hasFoo</code> |
| for booleans), or <code>setFoo(value)</code> for setters.</p> |
| |
| <p>Underscores may also appear in JsUnit test method names to separate logical |
| components of the name. One typical pattern is |
| <code>test<MethodUnderTest>_<state>_<expectedOutcome></code>, for example |
| <code>testPop_emptyStack_throws</code>. There is no One Correct Way to name test methods.</p> |
| |
| <h4 id="naming-enum-names">6.2.4 Enum names</h4> |
| |
| <p>Enum names are written in <code>UpperCamelCase</code>, similar to classes, and should |
| generally be singular nouns. Individual items within the enum are named in |
| <code>CONSTANT_CASE</code>.</p> |
| |
| <h4 id="naming-constant-names">6.2.5 Constant names</h4> |
| |
| <p>Constant names use <code>CONSTANT_CASE</code>: all uppercase letters, with words separated |
| by underscores. There is no reason for a constant to be named with a trailing |
| underscore, since private static properties can be replaced by (implicitly |
| private) module locals.</p> |
| |
| <h5 id="naming-definition-of-constant">6.2.5.1 Definition of “constant”</h5> |
| |
| <p>Every constant is a <code>@const</code> static property or a module-local <code>const</code> |
| declaration, but not all <code>@const</code> static properties and module-local <code>const</code>s |
| are constants. Before choosing constant case, consider whether the field really |
| feels like a <em>deeply immutable</em> constant. For example, if any of that instance's |
| observable state can change, it is almost certainly not a constant. Merely |
| intending to never mutate the object is generally not enough.</p> |
| |
| <p>Examples:</p> |
| |
| <pre><code class="language-js prettyprint good">// Constants |
| const NUMBER = 5; |
| /** @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'; |
| |
| const /** Set<string> */ mutableCollection = new Set(); |
| |
| const /** MyImmutableContainer<SomeMutableType> */ stillMutable = |
| new MyImmutableContainer(mutableInner); |
| |
| const {Foo} = goog.require('my.foo'); // mirrors imported name |
| |
| const logger = log.getLogger('loggers.are.not.immutable'); |
| </code></pre> |
| |
| <p>Constants’ names are typically nouns or noun phrases.</p> |
| |
| <h5 id="naming-local-aliases">6.2.5.2 Local aliases</h5> |
| |
| <p>Local aliases should be used whenever they improve readability over |
| fully-qualified names. Follow the same rules as <code>goog.require</code>s |
| (<a href="#file-goog-require">??</a>), maintaining the last part of the aliased name. |
| Aliases may also be used within functions. Aliases must be <code>const</code>.</p> |
| |
| <p>Examples:</p> |
| |
| <pre><code class="language-js prettyprint good">const staticHelper = importedNamespace.staticHelper; |
| const CONSTANT_NAME = ImportedClass.CONSTANT_NAME; |
| const {assert, assertInstanceof} = asserts; |
| </code></pre> |
| |
| <h4 id="naming-non-constant-field-names">6.2.6 Non-constant field names</h4> |
| |
| <p>Non-constant field names (static or otherwise) are written in <code>lowerCamelCase</code>, |
| with an optional trailing underscore for private fields.</p> |
| |
| <p>These names are typically nouns or noun phrases. For example, <code>computedValues</code> |
| or <code>index_</code>.</p> |
| |
| <h4 id="naming-parameter-names">6.2.7 Parameter names</h4> |
| |
| <p>Parameter names are written in <code>lowerCamelCase</code>. Note that this applies even if |
| the parameter expects a constructor.</p> |
| |
| <p>One-character parameter names should not be used in public methods.</p> |
| |
| <p><strong>Exception</strong>: When required by a third-party framework, parameter names may |
| begin with a <code>$</code>. This exception does not apply to any other identifiers (e.g. |
| local variables or properties).</p> |
| |
| <h4 id="naming-local-variable-names">6.2.8 Local variable names</h4> |
| |
| <p>Local variable names are written in <code>lowerCamelCase</code>, except for module-local |
| (top-level) constants, as described above. Constants in function scopes are |
| still named in <code>lowerCamelCase</code>. Note that <code>lowerCamelCase</code> is used |
| even if the variable holds a constructor.</p> |
| |
| <h4 id="naming-template-parameter-names">6.2.9 Template parameter names</h4> |
| |
| <p>Template parameter names should be concise, single-word or single-letter |
| identifiers, and must be all-caps, such as <code>TYPE</code> or <code>THIS</code>.</p> |
| |
| <h4 id="naming-module-local-names">6.2.10 Module-local names</h4> |
| |
| <p>Module-local names that are not exported are implicitly private. They are not |
| marked <code>@private</code>. This applies to classes, functions, variables, constants, |
| enums, and other module-local identifiers.</p> |
| |
| <h3 id="naming-camel-case-defined">6.3 Camel case: defined</h3> |
| |
| <p>Sometimes there is more than one reasonable way to convert an English phrase |
| into camel case, such as when acronyms or unusual constructs like <q>IPv6</q> or |
| <q>iOS</q> are present. To improve predictability, Google Style specifies the |
| following (nearly) deterministic scheme.</p> |
| |
| <p>Beginning with the prose form of the name:</p> |
| |
| <ol> |
| <li>Convert the phrase to plain ASCII and remove any apostrophes. For example, |
| <q>Müller's algorithm</q> might become <q>Muellers algorithm</q>.</li> |
| <li>Divide this result into words, splitting on spaces and any remaining |
| punctuation (typically hyphens). |
| <ol> |
| <li>Recommended: if any word already has a conventional camel case |
| appearance in common usage, split this into its constituent parts (e.g., |
| <q>AdWords</q> becomes <q>ad words</q>). Note that a word such as <q>iOS</q> is not |
| really in camel case per se; it defies any convention, so this |
| recommendation does not apply.</li> |
| </ol></li> |
| <li>Now lowercase everything (including acronyms), then uppercase only the first |
| character of: |
| <ol> |
| <li>… each word, to yield <code>UpperCamelCase</code>, or</li> |
| <li>… each word except the first, to yield <code>lowerCamelCase</code></li> |
| </ol></li> |
| <li>Finally, join all the words into a single identifier.</li> |
| </ol> |
| |
| <p>Note that the casing of the original words is almost entirely disregarded.</p> |
| |
| <p>Examples of <code>lowerCamelCase</code>:</p> |
| |
| <table> |
| <thead> |
| <tr> |
| <th style="text-align: center">Prose form</th> |
| <th style="text-align: center">Correct</th> |
| <th style="text-align: center">Incorrect</th> |
| </tr> |
| </thead> |
| |
| <tbody> |
| <tr> |
| <td style="text-align: center"><q>XML HTTP request</q></td> |
| <td style="text-align: center"><code>xmlHttpRequest</code></td> |
| <td style="text-align: center"><code>XMLHTTPRequest</code></td> |
| </tr> |
| <tr> |
| <td style="text-align: center"><q>new customer ID</q></td> |
| <td style="text-align: center"><code>newCustomerId</code></td> |
| <td style="text-align: center"><code>newCustomerID</code></td> |
| </tr> |
| <tr> |
| <td style="text-align: center"><q>inner stopwatch</q></td> |
| <td style="text-align: center"><code>innerStopwatch</code></td> |
| <td style="text-align: center"><code>innerStopWatch</code></td> |
| </tr> |
| <tr> |
| <td style="text-align: center"><q>supports IPv6 on iOS?</q></td> |
| <td style="text-align: center"><code>supportsIpv6OnIos</code></td> |
| <td style="text-align: center"><code>supportsIPv6OnIOS</code></td> |
| </tr> |
| <tr> |
| <td style="text-align: center"><q>YouTube importer</q></td> |
| <td style="text-align: center"><code>youTubeImporter</code></td> |
| <td style="text-align: center"><code>youtubeImporter</code>*</td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <p>*Acceptable, but not recommended.</p> |
| |
| <p>For examples of <code>UpperCamelCase</code>, uppercase the first letter of each correct |
| <code>lowerCamelCase</code> example.</p> |
| |
| <p>Note: Some words are ambiguously hyphenated in the English language: for example |
| <q>nonempty</q> and <q>non-empty</q> are both correct, so the method names <code>checkNonempty</code> |
| and <code>checkNonEmpty</code> are likewise both correct.</p> |
| |
| <h2 id="jsdoc">7 JSDoc</h2> |
| |
| <p><a href="https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler">JSDoc</a> is used on all classes, fields, and methods.</p> |
| |
| <h3 id="jsdoc-general-form">7.1 General form</h3> |
| |
| <p>The basic formatting of JSDoc blocks is as seen in this example:</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * Multiple lines of JSDoc text are written here, |
| * wrapped normally. |
| * @param {number} arg A number to do something to. |
| */ |
| function doSomething(arg) { … } |
| </code></pre> |
| |
| <p>or in this single-line example:</p> |
| |
| <pre><code class="language-js prettyprint good">/** @const @private {!Foo} A short bit of JSDoc. */ |
| this.foo_ = foo; |
| </code></pre> |
| |
| <p>If a single-line comment overflows into multiple lines, it must use the |
| multi-line style with <code>/**</code> and <code>*/</code> on their own lines.</p> |
| |
| <p>Many tools extract metadata from JSDoc comments to perform code validation and |
| optimization. As such, these comments <strong>must</strong> be well-formed.</p> |
| |
| <h3 id="jsdoc-markdown">7.2 Markdown</h3> |
| |
| <p>JSDoc is written in Markdown, though it may include HTML when necessary.</p> |
| |
| <p>Note that tools that automatically extract JSDoc (e.g. <a href="https://github.com/jleyba/js-dossier">JsDossier</a>) will often |
| ignore plain text formatting, so if you did this:</p> |
| |
| <pre><code class="language-js prettyprint bad">/** |
| * Computes weight based on three factors: |
| * items sent |
| * items received |
| * last timestamp |
| */ |
| </code></pre> |
| |
| <p>it would come out like this:</p> |
| |
| <pre><code>Computes weight based on three factors: items sent items received last timestamp |
| </code></pre> |
| |
| <p>Instead, write a Markdown list:</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * Computes weight based on three factors: |
| * |
| * - items sent |
| * - items received |
| * - last timestamp |
| */ |
| </code></pre> |
| |
| <h3 id="jsdoc-tags">7.3 JSDoc tags</h3> |
| |
| <p>Google style allows a subset of JSDoc tags. See |
| <a href="#appendices-jsdoc-tag-reference">??</a> for the complete list. Most tags must |
| occupy their own line, with the tag at the beginning of the line.</p> |
| |
| <p>Disallowed:</p> |
| |
| <pre><code class="language-js prettyprint bad">/** |
| * The "param" tag must occupy its own line and may not be combined. |
| * @param {number} left @param {number} right |
| */ |
| function add(left, right) { ... } |
| </code></pre> |
| |
| <p>Simple tags that do not require any additional data (such as <code>@private</code>, |
| <code>@const</code>, <code>@final</code>, <code>@export</code>) may be combined onto the same line, along with an |
| optional type when appropriate.</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * Place more complex annotations (like "implements" and "template") |
| * on their own lines. Multiple simple tags (like "export" and "final") |
| * may be combined in one line. |
| * @export @final |
| * @implements {Iterable<TYPE>} |
| * @template TYPE |
| */ |
| class MyClass { |
| /** |
| * @param {!ObjType} obj Some object. |
| * @param {number=} num An optional number. |
| */ |
| constructor(obj, num = 42) { |
| /** @private @const {!Array<!ObjType|number>} */ |
| this.data_ = [obj, num]; |
| } |
| } |
| </code></pre> |
| |
| <p>There is no hard rule for when to combine tags, or in which order, but be |
| consistent.</p> |
| |
| <p>For general information about annotating types in JavaScript see |
| <a href="https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler">Annotating JavaScript for the Closure Compiler</a> and |
| <a href="https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System">Types in the Closure Type System</a>.</p> |
| |
| <h3 id="jsdoc-line-wrapping">7.4 Line wrapping</h3> |
| |
| <p>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.</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * 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. |
| */ |
| exports.method = function(foo) { |
| return 5; |
| }; |
| </code></pre> |
| |
| <p>Do not indent when wrapping a <code>@desc</code> or <code>@fileoverview</code> description.</p> |
| |
| <h3 id="jsdoc-top-file-level-comments">7.5 Top/file-level comments</h3> |
| |
| <p>A file may have a top-level file overview. A copyright notice, author information, |
| and default <a href="#jsdoc-visibility-annotations">visibility level</a> 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 |
| dependencies or compatibility information. Wrapped lines are not indented.</p> |
| |
| <p>Example:</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * @fileoverview Description of file, its uses and information |
| * about its dependencies. |
| * @package |
| */ |
| </code></pre> |
| |
| <h3 id="jsdoc-class-comments">7.6 Class comments</h3> |
| |
| <p>Classes, interfaces and records must be documented with a description and any |
| 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. When defining a class <code>@constructor</code> and <code>@extends</code> annotations are |
| not used with the <code>class</code> keyword unless it extends a generic class. When |
| defining an <code>@interface</code> or a <code>@record</code>, the <code>@extends</code> annotation is used when |
| defining a subclass and the <code>extends</code> keyword is never used.</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * A fancier event target that does cool things. |
| * @implements {Iterable<string>} |
| */ |
| class MyFancyTarget extends EventTarget { |
| /** |
| * @param {string} arg1 An argument that makes this more interesting. |
| * @param {!Array<number>} arg2 List of numbers to be processed. |
| */ |
| constructor(arg1, arg2) { |
| // ... |
| } |
| }; |
| |
| /** |
| * Records are also helpful. |
| * @extends {Iterator<TYPE>} |
| * @record |
| * @template TYPE |
| */ |
| class Listable { |
| /** @return {TYPE} The next item in line to be returned. */ |
| next() {} |
| } |
| </code></pre> |
| |
| <h3 id="jsdoc-enum-and-typedef-comments">7.7 Enum and typedef comments</h3> |
| |
| <p>All enums and typedefs must be documented with appropriate JSDoc tags |
| (<code>@typedef</code> or <code>@enum</code>) on the preceding line. Public enums and typedefs must |
| also have a description. Individual enum items may be documented with a JSDoc |
| comment on the preceding line.</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * A useful type union, which is reused often. |
| * @typedef {!FruitType|!FruitTypeEnum} |
| */ |
| let CoolUnionType; |
| |
| /** |
| * Types of fruits. |
| * @enum {string} |
| */ |
| const FruitTypeEnum = { |
| /** This kind is very sour. */ |
| SOUR: 'sour', |
| /** The less-sour kind. */ |
| SWEET: 'sweet', |
| }; |
| </code></pre> |
| |
| <p>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 |
| <code>@record</code>.</p> |
| |
| <h3 id="jsdoc-method-and-function-comments">7.8 Method and function comments</h3> |
| |
| <p>In methods and named functions, parameter and return types must be documented, |
| even in the case of same-signature <code>@override</code>s. The <code>this</code> type should be |
| documented when necessary. Return type may be omitted if the function has no |
| non-empty <code>return</code> statements.</p> |
| |
| <p>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.</p> |
| |
| <p>Method descriptions begin with a verb phrase that describes what the method |
| does. This phrase is not an imperative sentence, but instead is written in the |
| third person, as if there is an implied <q>This method ...</q> before it.</p> |
| |
| <p>If a method overrides a superclass method, it must include an <code>@override</code> |
| annotation. For overridden methods, all <code>@param</code> and <code>@return</code> annotations must |
| be specified explicitly even if no type from the superclass method is refined. |
| This is to align with TypeScript.</p> |
| |
| <pre><code class="language-js prettyprint good">/** A class that does something. */ |
| class SomeClass extends SomeBaseClass { |
| /** |
| * Operates on an instance of MyClass and returns something. |
| * @param {!MyClass} obj An object that for some reason needs detailed |
| * explanation that spans multiple lines. |
| * @param {!OtherClass} obviousOtherClass |
| * @return {boolean} Whether something occurred. |
| */ |
| someMethod(obj, obviousOtherClass) { ... } |
| |
| /** |
| * @param {string} param |
| * @return {string} |
| * @override |
| */ |
| overriddenMethod(param) { ... } |
| } |
| |
| /** |
| * Demonstrates how top-level functions follow the same rules. This one |
| * makes an array. |
| * @param {TYPE} arg |
| * @return {!Array<TYPE>} |
| * @template TYPE |
| */ |
| function makeArray(arg) { ... } |
| </code></pre> |
| |
| <p>If you only need to document the param and return types of a function, you may |
| optionally use inline JSDocs in the function's signature. These inline JSDocs |
| specify the return and param types without tags.</p> |
| |
| <pre><code class="language-js prettyprint good">function /** string */ foo(/** number */ arg) {...} |
| </code></pre> |
| |
| <p>If you need descriptions or tags, use a single JSDoc comment above the method. |
| For example, methods which return values need a <code>@return</code> tag.</p> |
| |
| <pre><code class="language-js prettyprint good">class MyClass { |
| /** |
| * @param {number} arg |
| * @return {string} |
| */ |
| bar(arg) {...} |
| } |
| </code></pre> |
| |
| <pre><code class="language-js prettyprint bad">// Illegal inline JSDocs. |
| |
| class MyClass { |
| /** @return {string} */ foo() {...} |
| } |
| |
| /** No function description allowed inline here. */ function bar() {...} |
| |
| function /** Function description is also illegal here. */ baz() {...} |
| </code></pre> |
| |
| |
| |
| <p>In anonymous functions annotations are generally optional. If the automatic type |
| inference is insufficient or explicit annotation improves readability, then |
| annotate param and return types like this:</p> |
| |
| <pre><code class="language-js prettyprint good">promise.then( |
| /** @return {string} */ |
| (/** !Array<string> */ items) => { |
| doSomethingWith(items); |
| return items[0]; |
| }); |
| </code></pre> |
| |
| <p>For function type expressions, see <a href="#jsdoc-function-types">??</a>.</p> |
| |
| <h3 id="jsdoc-property-comments">7.9 Property comments</h3> |
| |
| <p>Property types must be documented. The description may be omitted for private |
| properties, if name and type provide enough documentation for understanding the |
| code.</p> |
| |
| <p>Publicly exported constants are commented the same way as properties.</p> |
| |
| <pre><code class="language-js prettyprint good">/** My class. */ |
| class MyClass { |
| /** @param {string=} someString */ |
| constructor(someString = 'default string') { |
| /** @private @const {string} */ |
| this.someString_ = someString; |
| |
| /** @private @const {!OtherType} */ |
| this.someOtherThing_ = functionThatReturnsAThing(); |
| |
| /** |
| * Maximum number of things per pane. |
| * @type {number} |
| */ |
| this.someProperty = 4; |
| } |
| } |
| |
| /** |
| * The number of times we'll try before giving up. |
| * @const {number} |
| */ |
| MyClass.RETRY_COUNT = 33; |
| </code></pre> |
| |
| <h3 id="jsdoc-type-annotations">7.10 Type annotations</h3> |
| |
| <p>Type annotations are found on <code>@param</code>, <code>@return</code>, <code>@this</code>, and <code>@type</code> tags, |
| and optionally on <code>@const</code>, <code>@export</code>, and any visibility tags. Type annotations |
| attached to JSDoc tags must always be enclosed in braces.</p> |
| |
| <h4 id="jsdoc-nullability">7.10.1 Nullability</h4> |
| |
| <p>The type system defines modifiers <code>!</code> and <code>?</code> for non-null and nullable, |
| respectively. These modifiers must precede the type.</p> |
| |
| <p>Nullability modifiers have different requirements for different types, which |
| fall into two broad categories:</p> |
| |
| <ol> |
| <li>Type annotations for primitives (<code>string</code>, <code>number</code>, <code>boolean</code>, <code>symbol</code>, |
| <code>undefined</code>, <code>null</code>) and literals (<code>{function(...): ...}</code> and <code>{{foo: |
| string...}}</code>) are always non-nullable by default. Use the <code>?</code> modifier to |
| make it nullable, but omit the redundant <code>!</code>.</li> |
| <li>Reference types (generally, anything in <code>UpperCamelCase</code>, including |
| <code>some.namespace.ReferenceType</code>) refer to a class, enum, record, or typedef |
| defined elsewhere. Since these types may or may not be nullable, it is |
| impossible to tell from the name alone whether it is nullable or not. Always |
| use explicit <code>?</code> and <code>!</code> modifiers for these types to prevent ambiguity at |
| use sites.</li> |
| </ol> |
| |
| <p>Bad:</p> |
| |
| <pre><code class="language-js prettyprint bad">const /** MyObject */ myObject = null; // Non-primitive types must be annotated. |
| const /** !number */ someNum = 5; // Primitives are non-nullable by default. |
| const /** number? */ someNullableNum = null; // ? should precede the type. |
| const /** !{foo: string, bar: number} */ record = ...; // Already non-nullable. |
| const /** MyTypeDef */ def = ...; // Not sure if MyTypeDef is nullable. |
| |
| // Not sure if object (nullable), enum (non-nullable, unless otherwise |
| // specified), or typedef (depends on definition). |
| const /** SomeCamelCaseName */ n = ...; |
| </code></pre> |
| |
| <p>Good:</p> |
| |
| <pre><code class="language-js prettyprint good">const /** ?MyObject */ myObject = null; |
| const /** number */ someNum = 5; |
| const /** ?number */ someNullableNum = null; |
| const /** {foo: string, bar: number} */ record = ...; |
| const /** !MyTypeDef */ def = ...; |
| const /** ?SomeCamelCaseName */ n = ...; |
| </code></pre> |
| |
| <h4 id="jsdoc-type-casts">7.10.2 Type Casts</h4> |
| |
| <p>In cases where the compiler doesn't accurately infer the type of an expression, |
| and the assertion functions in |
| <a href="https://google.github.io/closure-library/api/goog.asserts.html">goog.asserts</a> |
| 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.</p> |
| |
| <pre><code class="language-js prettyprint good">/** @type {number} */ (x) |
| </code></pre> |
| |
| <h4 id="jsdoc-template-parameter-types">7.10.3 Template Parameter Types</h4> |
| |
| <p>Always specify template parameters. This way compiler can do a better job and it |
| makes it easier for readers to understand what code does.</p> |
| |
| <p>Bad:</p> |
| |
| <pre><code class="language-js prettyprint bad">const /** !Object */ users = {}; |
| const /** !Array */ books = []; |
| const /** !Promise */ response = ...; |
| </code></pre> |
| |
| <p>Good:</p> |
| |
| <pre><code class="language-js prettyprint good">const /** !Object<string, !User> */ users = {}; |
| const /** !Array<string> */ books = []; |
| const /** !Promise<!Response> */ response = ...; |
| |
| const /** !Promise<undefined> */ thisPromiseReturnsNothingButParameterIsStillUseful = ...; |
| const /** !Object<string, *> */ mapOfEverything = {}; |
| </code></pre> |
| |
| <p>Cases when template parameters should not be used:</p> |
| |
| <ul> |
| <li><code>Object</code> is used for type hierarchy and not as map-like structure.</li> |
| </ul> |
| |
| <h4 id="jsdoc-function-types">7.10.4 Function type expressions</h4> |
| |
| <p><strong>Terminology Note</strong>: <em>function type expression</em> refers to a type annotation for |
| function types with the keyword <code>function</code> in the annotation (see examples |
| below).</p> |
| |
| <p>Where the function definition is given, do not use a function type expression. |
| Specify parameter and return types with <code>@param</code> and <code>@return</code>, or with inline |
| annotations (see <a href="#jsdoc-method-and-function-comments">??</a>). This includes |
| anonymous functions and functions defined and assigned to a const (where the |
| function jsdoc appears above the whole assignment expression).</p> |
| |
| <p>Function type expressions are needed, for example, inside <code>@typedef</code>, <code>@param</code> |
| or <code>@return</code>. Use it also for variables or properties of function type, if they |
| are not immediately initialized with the function definition.</p> |
| |
| <pre><code class="language-js prettyprint good"> /** @private {function(string): string} */ |
| this.idGenerator_ = googFunctions.identity; |
| </code></pre> |
| |
| <p>When using a function type expression, always specify the return type |
| explicitly. Otherwise the default return type is <q>unknown</q> (<code>?</code>), which leads to |
| strange and unexpected behavior, and is rarely what is actually desired.</p> |
| |
| <p>Bad - type error, but no warning given:</p> |
| |
| <pre><code class="language-js prettyprint bad">/** @param {function()} generateNumber */ |
| function foo(generateNumber) { |
| const /** number */ x = generateNumber(); // No compile-time type error here. |
| } |
| |
| foo(() => 'clearly not a number'); |
| </code></pre> |
| |
| <p>Good:</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * @param {function(): *} inputFunction1 Can return any type. |
| * @param {function(): undefined} inputFunction2 Definitely doesn't return |
| * anything. |
| * NOTE: the return type of `foo` itself is safely implied to be {undefined}. |
| */ |
| function foo(inputFunction1, inputFunction2) {...} |
| </code></pre> |
| |
| <h4 id="jsdoc-whitespace">7.10.5 Whitespace</h4> |
| |
| <p>Within a type annotation, a single space or line break is required after each |
| comma or colon. Additional line breaks may be inserted to improve readability or |
| avoid exceeding the column limit. These breaks should be chosen and indented |
| following the applicable guidelines (e.g. <a href="#formatting-line-wrapping">??</a> and |
| <a href="#formatting-block-indentation">??</a>). No other whitespace is allowed in type |
| annotations.</p> |
| |
| <p>Good:</p> |
| |
| <pre><code class="language-js prettyprint good">/** @type {function(string): number} */ |
| |
| /** @type {{foo: number, bar: number}} */ |
| |
| /** @type {number|string} */ |
| |
| /** @type {!Object<string, string>} */ |
| |
| /** @type {function(this: Object<string, string>, number): string} */ |
| |
| /** |
| * @type {function( |
| * !SuperDuperReallyReallyLongTypedefThatForcesTheLineBreak, |
| * !OtherVeryLongTypedef): string} |
| */ |
| |
| /** |
| * @type {!SuperDuperReallyReallyLongTypedefThatForcesTheLineBreak| |
| * !OtherVeryLongTypedef} |
| */ |
| </code></pre> |
| |
| <p>Bad:</p> |
| |
| <pre><code class="language-js prettyprint bad">// Only put a space after the colon |
| /** @type {function(string) : number} */ |
| |
| // Put spaces after colons and commas |
| /** @type {{foo:number,bar:number}} */ |
| |
| // No space in union types |
| /** @type {number | string} */ |
| </code></pre> |
| |
| <h3 id="jsdoc-visibility-annotations">7.11 Visibility annotations</h3> |
| |
| <p>Visibility annotations (<code>@private</code>, <code>@package</code>, <code>@protected</code>) may be specified |
| in a <code>@fileoverview</code> block, 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. <code>@private</code> names may optionally end with an underscore.</p> |
| |
| <h2 id="policies">8 Policies</h2> |
| |
| <h3 id="policies-be-consistent">8.1 Issues unspecified by Google Style: Be Consistent!</h3> |
| |
| <p>For any style question that isn't settled definitively by this specification, |
| prefer to do what the other code in the same file is already doing. If that |
| doesn't resolve the question, consider emulating the other files in the same |
| package.</p> |
| |
| <h3 id="policies-compiler-warnings">8.2 Compiler warnings</h3> |
| |
| <h4 id="policies-use-a-standard-warning-set">8.2.1 Use a standard warning set</h4> |
| |
| <p>As far as possible projects should use |
| <code>--warning_level=VERBOSE</code>.</p> |
| |
| <h4 id="policies-how-to-handle-a-warning">8.2.2 How to handle a warning</h4> |
| |
| <p>Before doing anything, make sure you understand exactly what the warning is |
| telling you. If you're not positive why a warning is appearing, ask for help |
| .</p> |
| |
| <p>Once you understand the warning, attempt the following solutions in order:</p> |
| |
| <ol> |
| <li><strong>First, fix it or work around it.</strong> Make a strong attempt to actually |
| address the warning, or find another way to accomplish the task that avoids |
| the situation entirely.</li> |
| <li><strong>Otherwise, determine if it's a false alarm.</strong> If you are convinced that |
| 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 <code>@suppress</code> |
| annotation.</li> |
| <li><strong>Otherwise, leave a TODO comment.</strong> This is a <strong>last resort</strong>. |
| If you do this, <strong>do |
| not suppress the warning.</strong> The warning should be visible until it can be |
| taken care of properly.</li> |
| </ol> |
| |
| <h4 id="policies-suppress-a-warning-at-the-narrowest-reasonable-scope">8.2.3 Suppress a warning at the narrowest reasonable scope</h4> |
| |
| <p>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.</p> |
| |
| <p>Example</p> |
| |
| <pre><code class="language-js prettyprint good">/** @suppress {uselessCode} Unrecognized 'use asm' declaration */ |
| function fn() { |
| 'use asm'; |
| return 0; |
| } |
| </code></pre> |
| |
| <p>Even a large number of suppressions in a class is still better than blinding the |
| entire class to this type of warning.</p> |
| |
| <h3 id="policies-deprecation">8.3 Deprecation</h3> |
| |
| <p>Mark deprecated methods, classes or interfaces with <code>@deprecated</code> annotations. A |
| deprecation comment must include simple, clear directions for people to fix |
| their call sites.</p> |
| |
| <h3 id="policies-code-not-in-google-style">8.4 Code not in Google Style</h3> |
| |
| <p>You will occasionally encounter files in your codebase that are not in proper |
| Google Style. These may have come from an acquisition, or may have been written |
| before Google Style took a position on some issue, or may be in non-Google Style |
| for any other reason.</p> |
| |
| <h4 id="policies-reformatting-existing-code">8.4.1 Reformatting existing code</h4> |
| |
| <p>When updating the style of existing code, follow these guidelines.</p> |
| |
| <ol> |
| <li>It is not required to change all existing code to meet current style |
| guidelines. Reformatting existing code is a trade-off between code churn and |
| consistency. Style rules evolve over time and these kinds of tweaks to |
| maintain compliance would create unnecessary churn. However, if significant |
| changes are being made to a file it is expected that the file will be in |
| Google Style.</li> |
| <li>Be careful not to allow opportunistic style fixes to muddle the focus of a |
| CL. If you find yourself making a lot of style changes that aren’t critical |
| to the central focus of a CL, promote those changes to a separate CL.</li> |
| </ol> |
| |
| <h4 id="policies-newly-added-code-use-google-style">8.4.2 Newly added code: use Google Style</h4> |
| |
| <p>Brand new files use Google Style, regardless of the style choices of other files |
| in the same package.</p> |
| |
| <p>When adding new code to a file that is not in Google Style, reformatting the |
| existing code first is recommended, subject to the advice in |
| <a href="#policies-reformatting-existing-code">??</a>.</p> |
| |
| <p>If this reformatting is not done, then new code should be as consistent as |
| possible with existing code in the same file, but must not violate the style |
| guide.</p> |
| |
| <h3 id="policies-local-style-rules">8.5 Local style rules</h3> |
| |
| <p>Teams and projects may adopt additional style rules beyond those in this |
| document, but must accept that cleanup changes may not abide by these additional |
| rules, and must not block such cleanup changes due to violating any additional |
| rules. Beware of excessive rules which serve no purpose. The style guide does |
| not seek to define style in every possible scenario and neither should you.</p> |
| |
| <h3 id="policies-generated-code-mostly-exempt">8.6 Generated code: mostly exempt</h3> |
| |
| <p>Source code generated by the build process is not required to be in Google |
| Style. However, any generated identifiers that will be referenced from |
| hand-written source code must follow the naming requirements. As a special |
| exception, such identifiers are allowed to contain underscores, which may help |
| to avoid conflicts with hand-written identifiers.</p> |
| |
| <h2 id="appendices">9 Appendices</h2> |
| |
| <h3 id="appendices-jsdoc-tag-reference">9.1 JSDoc tag reference</h3> |
| |
| <p>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.</p> |
| |
| <h4 id="appendices-type-annotations">9.1.1 Type annotations and other Closure Compiler annotations</h4> |
| |
| <p>Documentation for JSDoc used by the Closure Compiler is described in |
| <a href="https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler">Annotating JavaScript for the Closure Compiler</a> and |
| <a href="https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System">Types in the Closure Type System</a>.</p> |
| |
| <h4 id="appendices-documentation-annotations">9.1.2 Documentation annotations</h4> |
| |
| <p>In addition to the JSDoc described in |
| <a href="https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler">Annotating JavaScript for the Closure Compiler</a> the following tags are common |
| and well supported by various documentation generation tools (such as |
| <a href="https://github.com/jleyba/js-dossier">JsDossier</a>) for purely documentation purposes.</p> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.2.1 <code>@author</code> or <code>@owner</code> - <em>Not recommended.</em></h5> |
| |
| <p><strong>Not recommended.</strong></p> |
| |
| <p>Syntax: <code>@author [email protected] (First Last)</code></p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * @fileoverview Utilities for handling textareas. |
| * @author [email protected] (Uthur Pendragon) |
| */ |
| </code></pre> |
| |
| <p>Documents the author of a file or the owner of a test, generally only used in |
| the <code>@fileoverview</code> comment. The <code>@owner</code> tag is used by the unit test dashboard |
| to determine who owns the test results.</p> |
| |
| </section> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.2.2 <code>@bug</code></h5> |
| |
| <p>Syntax: <code>@bug bugnumber</code></p> |
| |
| <pre><code class="language-js prettyprint good">/** @bug 1234567 */ |
| function testSomething() { |
| // … |
| } |
| |
| /** |
| * @bug 1234568 |
| * @bug 1234569 |
| */ |
| function testTwoBugs() { |
| // … |
| } |
| </code></pre> |
| |
| <p>Indicates what bugs the given test function regression tests.</p> |
| |
| <p>Multiple bugs should each have their own <code>@bug</code> line, to make searching for |
| regression tests as easy as possible.</p> |
| |
| </section> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.2.3 <code>@code</code> - <em>Deprecated. Do not use.</em></h5> |
| |
| <p><strong>Deprecated. Do not use. Use Markdown backticks instead.</strong></p> |
| |
| <p>Syntax: <code>{@code ...}</code></p> |
| |
| <p>Historically, <code>`BatchItem`</code> was written as |
| <code class="badcode">{@code BatchItem}</code>.</p> |
| |
| <pre><code class="language-js prettyprint good">/** Processes pending `BatchItem` instances. */ |
| function processBatchItems() {} |
| </code></pre> |
| |
| <p>Indicates that a term in a JSDoc description is code so it may be correctly |
| formatted in generated documentation.</p> |
| |
| </section> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.2.4 <code>@desc</code></h5> |
| |
| <p>Syntax: <code>@desc Message description</code></p> |
| |
| <pre><code class="language-js prettyprint good">/** @desc Notifying a user that their account has been created. */ |
| exports.MSG_ACCOUNT_CREATED = goog.getMsg( |
| 'Your account has been successfully created.'); |
| </code></pre> |
| |
| </section> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.2.5 <code>@link</code></h5> |
| |
| <p>Syntax: <code>{@link ...}</code></p> |
| |
| <p>This tag is used to generate cross-reference links within generated |
| documentation.</p> |
| |
| <pre><code class="language-js prettyprint good">/** Processes pending {@link BatchItem} instances. */ |
| function processBatchItems() {} |
| </code></pre> |
| |
| <p><strong>Historical note:</strong> @link tags have also been used to create external links in |
| generated documentation. For external links, always use Markdown's link syntax |
| instead:</p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * This class implements a useful subset of the |
| * [native Event interface](https://dom.spec.whatwg.org/#event). |
| */ |
| class ApplicationEvent {} |
| </code></pre> |
| |
| </section> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.2.6 <code>@see</code></h5> |
| |
| <p>Syntax: <code>@see Link</code></p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * Adds a single item, recklessly. |
| * @see #addSafely |
| * @see goog.Collect |
| * @see goog.RecklessAdder#add |
| */ |
| </code></pre> |
| |
| <p>Reference a lookup to another class function or method.</p> |
| |
| </section> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.2.7 <code>@supported</code></h5> |
| |
| <p>Syntax: <code>@supported Description</code></p> |
| |
| <pre><code class="language-js prettyprint good">/** |
| * @fileoverview Event Manager |
| * Provides an abstracted interface to the browsers' event systems. |
| * @supported IE10+, Chrome, Safari |
| */ |
| </code></pre> |
| |
| <p>Used in a fileoverview to indicate what browsers are supported by the file.</p> |
| |
| </section> |
| |
| <p>You may also see other types of JSDoc annotations in third-party code. These |
| annotations appear in the <a href="http://code.google.com/p/jsdoc-toolkit/wiki/TagReference">JSDoc Toolkit Tag Reference</a> but are not considered |
| part of valid Google style.</p> |
| |
| <h4 id="appendices-framework-specific-annotations">9.1.3 Framework specific annotations</h4> |
| |
| <p>The following annotations are specific to a particular framework.</p> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.3.1 <code>@ngInject</code> for Angular 1</h5> |
| |
| </section> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.3.2 <code>@polymerBehavior</code> for Polymer</h5> |
| |
| |
| |
| <p><a href="https://github.com/google/closure-compiler/wiki/Polymer-Pass">https://github.com/google/closure-compiler/wiki/Polymer-Pass</a> |
| </p> |
| |
| </section> |
| |
| <section class="zippy"> |
| |
| </section> |
| |
| <h4 id="appendices-notes-about-standard-closure-compiler-annotations">9.1.4 Notes about standard Closure Compiler annotations</h4> |
| |
| <p>The following tags used to be standard but are now deprecated.</p> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.4.1 <code>@expose</code> - <em>Deprecated. Do not use.</em></h5> |
| |
| <p><strong>Deprecated. Do not use. Use <code>@export</code> and/or <code>@nocollapse</code> instead.</strong></p> |
| |
| </section> |
| |
| <section class="zippy"> |
| |
| <h5>9.1.4.2 <code>@inheritDoc</code> - <em>Deprecated. Do not use.</em></h5> |
| |
| <p><strong>Deprecated. Do not use. Use <code>@override</code> instead.</strong></p> |
| |
| </section> |
| |
| <h3 id="appendices-commonly-misunderstood-style-rules">9.2 Commonly misunderstood style rules</h3> |
| |
| <p>Here is a collection of lesser-known or commonly misunderstood facts about |
| Google Style for JavaScript. (The following are true statements; this is not a |
| list of <q>myths.</q>)</p> |
| |
| <ul> |
| <li>Neither a copyright statement nor <code>@author</code> credit is required in a source |
| file. (Neither is explicitly recommended, either.)</li> |
| <li>There is no <q>hard and fast</q> rule governing how to order the members of a |
| class (<a href="#features-classes">??</a>).</li> |
| <li>Empty blocks can usually be represented concisely as <code>{}</code>, as detailed in |
| (<a href="#formatting-empty-blocks">??</a>).</li> |
| <li>The prime directive of line-wrapping is: prefer to break at a higher |
| syntactic level (<a href="#formatting-where-to-break">??</a>).</li> |
| <li>Non-ASCII characters are allowed in string literals, comments and JSDoc, and |
| in fact are recommended when they make the code easier to read than the |
| equivalent Unicode escape would (<a href="#non-ascii-characters">??</a>).</li> |
| </ul> |
| |
| <h3 id="appendices-style-related-tools">9.3 Style-related tools</h3> |
| |
| <p>The following tools exist to support various aspects of Google Style.</p> |
| |
| <h4 id="appendices-tools-closure-compiler">9.3.1 Closure Compiler</h4> |
| |
| <p>This program performs type checking and |
| other checks, optimizations and other transformations (such as lowering code to |
| ECMAScript 5).</p> |
| |
| <h4 id="appendices-clang-format">9.3.2 <code>clang-format</code></h4> |
| |
| <p>This 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 <code>clang-format</code> is compliant with the style guide. |
| </p> |
| |
| <p><code>clang-format</code> is not required. Authors are allowed to change its output, and |
| reviewers are allowed to ask for such changes; disputes are worked out in the |
| usual way. However, subtrees may choose to opt in to such enforcement locally.</p> |
| |
| <h4 id="appendices-closure-compiler-linter">9.3.3 Closure compiler linter</h4> |
| |
| <p>This program checks for a |
| variety of missteps and anti-patterns.</p> |
| |
| <h4 id="appendices-conformance-framework">9.3.4 Conformance framework</h4> |
| |
| <p>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, |
| for example, forbid access to a certain property, or calls to a certain |
| function, or missing type information (unknowns).</p> |
| |
| <p>These rules are commonly used to enforce critical restrictions (such as defining |
| globals, which could break the codebase) and security patterns (such as using |
| <code>eval</code> or assigning to <code>innerHTML</code>), or more loosely to improve code quality.</p> |
| |
| <p>For additional information see the official documentation for the |
| <a href="https://github.com/google/closure-compiler/wiki/JS-Conformance-Framework">JS Conformance Framework</a>.</p> |
| |
| <h3 id="appendices-legacy-exceptions">9.4 Exceptions for legacy platforms</h3> |
| |
| <h4 id="appendices-legacy-exceptions-overview">9.4.1 Overview</h4> |
| |
| <p>This section describes exceptions and additional rules to be followed when |
| 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:</p> |
| |
| <ul> |
| <li>Use of <code>var</code> declarations is allowed</li> |
| <li>Use of <code>arguments</code> is allowed</li> |
| <li>Optional parameters without default values are allowed</li> |
| </ul> |
| |
| <h4 id="appendices-legacy-exceptions-var">9.4.2 Use <code>var</code></h4> |
| |
| <h5 id="appendices-legacy-exceptions-var-scope">9.4.2.1 <code>var</code> declarations are NOT block-scoped</h5> |
| |
| <p><code>var</code> declarations are scoped to the beginning of the nearest enclosing |
| function, script or module, which can cause unexpected behavior, especially with |
| function closures that reference <code>var</code> declarations inside of loops. The |
| following code gives an example:</p> |
| |
| <pre><code class="language-js prettyprint bad">for (var i = 0; i < 3; ++i) { |
| var iteration = i; |
| setTimeout(function() { console.log(iteration); }, i*1000); |
| } |
| |
| // logs 2, 2, 2 -- NOT 0, 1, 2 |
| // because `iteration` is function-scoped, not local to the loop. |
| |
| </code></pre> |
| |
| <h5 id="appendices-legacy-exceptions-var-declare">9.4.2.2 Declare variables as close as possible to first use</h5> |
| |
| <p>Even though <code>var</code> declarations are scoped to the beginning of the enclosing |
| function, <code>var</code> declarations should be as close as possible to their first use, |
| for readability purposes. However, do not put a <code>var</code> declaration inside a block |
| if that variable is referenced outside the block. For example:</p> |
| |
| <pre><code class="language-js prettyprint good">function sillyFunction() { |
| var count = 0; |
| for (var x in y) { |
| // "count" could be declared here, but don't do that. |
| count++; |
| } |
| console.log(count + ' items in y'); |
| } |
| </code></pre> |
| |
| <h5 id="appendices-legacy-exceptions-var-const">9.4.2.3 Use @const for constants variables</h5> |
| |
| <p>For global declarations where the <code>const</code> keyword would be used, if it were |
| available, annotate the <code>var</code> declaration with <code>@const</code> instead (this is |
| optional for local variables).</p> |
| |
| <h4 id="appendices-legacy-exceptions-function">9.4.3 Do not use block scoped functions declarations</h4> |
| |
| <p>Do <strong>not</strong> do this:</p> |
| |
| <pre><code class="language-js prettyprint bad">if (x) { |
| function foo() {} |
| } |
| </code></pre> |
| |
| <p>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 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.</p> |
| |
| <p>To get consistent behavior, instead use a <code>var</code> initialized with a function |
| expression to define a function within a block:</p> |
| |
| <pre><code class="language-js prettyprint good">if (x) { |
| var foo = function() {}; |
| } |
| </code></pre> |
| |
| <h4 id="appendices-legacy-exceptions-goog-provide">9.4.4 Dependency management with <code>goog.provide</code>/<code>goog.require</code></h4> |
| |
| <h5 id="appendices-legacy-exceptions-goog-provide-summary">9.4.4.1 Summary</h5> |
| |
| <p><strong>WARNING: <code>goog.provide</code> dependency management is deprecated.</strong> All new files, |
| even in projects using <code>goog.provide</code> for older files, should use |
| <a href="#source-file-structure"><code>goog.module</code></a>. The following rules are for |
| pre-existing <code>goog.provide</code> files only.</p> |
| |
| <ul> |
| <li>Place all <code>goog.provide</code>s first, <code>goog.require</code>s second. Separate provides |
| from requires with an empty line.</li> |
| <li>Sort the entries alphabetically (uppercase first).</li> |
| <li>Don't wrap <code>goog.provide</code> and <code>goog.require</code> statements. Exceed 80 columns |
| if necessary.</li> |
| <li>Only provide top-level symbols.</li> |
| </ul> |
| |
| <p><code>goog.provide</code> statements should be grouped together and placed first. All |
| <code>goog.require</code> statements should follow. The two lists should be separated with |
| an empty line.</p> |
| |
| <p>Similar to import statements in other languages, <code>goog.provide</code> and |
| <code>goog.require</code> statements should be written in a single line, even if they |
| exceed the 80 column line length limit.</p> |
| |
| <p>The lines should be sorted alphabetically, with uppercase letters coming first:</p> |
| |
| <pre><code class="language-js prettyprint good">goog.provide('namespace.MyClass'); |
| goog.provide('namespace.helperFoo'); |
| |
| goog.require('an.extremelyLongNamespace.thatSomeoneThought.wouldBeNice.andNowItIsLonger.Than80Columns'); |
| goog.require('goog.dom'); |
| goog.require('goog.dom.TagName'); |
| goog.require('goog.dom.classes'); |
| goog.require('goog.dominoes'); |
| |
| </code></pre> |
| |
| <p>All members defined on a class should be in the same file. 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).</p> |
| |
| <p>Do this:</p> |
| |
| <pre><code class="language-js prettyprint good">goog.provide('namespace.MyClass'); |
| </code></pre> |
| |
| <p>Not this:</p> |
| |
| <pre><code class="language-js prettyprint bad">goog.provide('namespace.MyClass'); |
| goog.provide('namespace.MyClass.CONSTANT'); |
| goog.provide('namespace.MyClass.Enum'); |
| goog.provide('namespace.MyClass.InnerClass'); |
| goog.provide('namespace.MyClass.TypeDef'); |
| goog.provide('namespace.MyClass.staticMethod'); |
| </code></pre> |
| |
| <p>Members on namespaces may also be provided:</p> |
| |
| <pre><code class="language-js prettyprint good">goog.provide('foo.bar'); |
| goog.provide('foo.bar.CONSTANT'); |
| goog.provide('foo.bar.method'); |
| </code></pre> |
| |
| <h5 id="appendices-legacy-exceptions-goog-scope">9.4.4.2 Aliasing with <code>goog.scope</code></h5> |
| |
| <p><strong>WARNING: <code>goog.scope</code> is deprecated.</strong> New files should not use <code>goog.scope</code> |
| even in projects with existing <code>goog.scope</code> usage.</p> |
| |
| <p><code>goog.scope</code> may be used to shorten references to namespaced symbols in code |
| using <code>goog.provide</code>/<code>goog.require</code> dependency management.</p> |
| |
| <p>Only one <code>goog.scope</code> invocation may be added per file. Always place it in the |
| global scope.</p> |
| |
| <p>The opening <code>goog.scope(function() {</code> invocation must be preceded by exactly one |
| blank line and follow any <code>goog.provide</code> statements, <code>goog.require</code> statements, |
| or top-level comments. The invocation must be closed on the last line in the |
| file. Append <code>// goog.scope</code> to the closing statement of the scope. Separate the |
| comment from the semicolon by two spaces.</p> |
| |
| <p>Similar to C++ namespaces, do not indent under <code>goog.scope</code> declarations. |
| Instead, continue from the 0 column.</p> |
| |
| <p>Only make aliases for 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):</p> |
| |
| <pre><code class="language-js prettyprint bad">goog.scope(function() { |
| var Button = goog.ui.Button; |
| |
| Button = function() { ... }; |
| ... |
| </code></pre> |
| |
| <p>Names must be the same as the last property of the global that they are |
| aliasing.</p> |
| |
| <pre><code class="language-js prettyprint good">goog.provide('my.module.SomeType'); |
| |
| goog.require('goog.dom'); |
| goog.require('goog.ui.Button'); |
| |
| goog.scope(function() { |
| var Button = goog.ui.Button; |
| var dom = goog.dom; |
| |
| // Alias new types after the constructor declaration. |
| my.module.SomeType = function() { ... }; |
| var SomeType = my.module.SomeType; |
| |
| // Declare methods on the prototype as usual: |
| SomeType.prototype.findButton = function() { |
| // Button as aliased above. |
| this.button = new Button(dom.getElement('my-button')); |
| }; |
| ... |
| }); // goog.scope |
| </code></pre> |
| |
| <h5 id="appendices-legacy-exceptions-forward-declare">9.4.4.3 <code>goog.forwardDeclare</code></h5> |
| |
| <p>Prefer to use <code>goog.requireType</code> instead of <code>goog.forwardDeclare</code> to break |
| circular dependencies between files in the same library. Unlike <code>goog.require</code>, |
| a <code>goog.requireType</code> statement is allowed to import a namespace before it is |
| defined.</p> |
| |
| <p><code>goog.forwardDeclare</code> statements must follow the same style rules as |
| <code>goog.require</code> and <code>goog.requireType</code>. The entire block of |
| <code>goog.forwardDeclare</code>, <code>goog.require</code> and <code>goog.requireType</code> statements is |
| sorted alphabetically.</p> |
| |
| <p><code>goog.forwardDeclare</code> is used in legacy code to break circular references |
| spanning <em>across library boundaries</em>. 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).</p> |
| |
| <h5 id="appendices-legacy-exceptions-module-get">9.4.4.4 <code>goog.module.get(name)</code></h5> |
| |
| <p>If a <code>goog.provide</code> file depends on a <code>goog.module</code> file, the <code>goog.provide</code> |
| file can not normally refer to the module's exports via a global name. Instead, |
| in addition to <code>goog.require()</code>ing the module, the <code>goog.provide</code> file must |
| fetch the module's export object by calling <code>goog.module.get('module.name')</code>.</p> |
| |
| <p>Note: Only calling <code>goog.module.get('module.name')</code> does not create a build-time |
| dependency of your code on the module. The <code>goog.require</code> is needed for the |
| build dependency.</p> |
| |
| <h5 id="appendices-legacy-exceptions-declareLegacyNamespace">9.4.4.5 <code>goog.module.declareLegacyNamespace()</code></h5> |
| |
| <p><strong>WARNING: <code>goog.module.declareLegacyNamespace</code> is only for transitional use.</strong></p> |
| |
| <p><code>goog.module.declareLegacyNamespace</code> is only for use while migrating a |
| JavaScript file and its consumers from <code>goog.provide</code> to <code>goog.module</code> |
| . Update consumers of |
| your <a href="#source-file-structure"><code>goog.module</code></a> to use <code>goog.module</code> themselves. |
| Remove calls to <code>goog.module.declareLegacyNamespace</code> whenever possible. |
| </p> |
| |
| <p>If you can't update consumers of a legacy namespace from <code>goog.provide</code> to |
| <code>goog.module</code> soon, please wrap the contents of your file in a call to |
| <code>goog.scope</code>, use <code>goog.module.get</code> to import the legacy namespace--and then |
| delete the call to <code>goog.module.declareLegacyNamespace</code> in your <code>goog.module</code>.</p> |
| |
| <p>Calling <code>goog.module.declareLegacyNamespace()</code> inside a <code>goog.module(name)</code> will |
| declare the module's namespace as a global name just like a <code>goog.provide()</code> |
| call does. This allows a non <code>goog.module</code> namespace to access the module's |
| exports without calling <code>goog.module.get(name)</code>.</p> |
| |
| </div> |
| </body> |
| </html> |