1*8c35d5eeSXin Li<!DOCTYPE html> 2*8c35d5eeSXin Li<html lang="en"> 3*8c35d5eeSXin Li<head> 4*8c35d5eeSXin Li<meta charset="utf-8"> 5*8c35d5eeSXin Li<title>Google JavaScript Style Guide</title> 6*8c35d5eeSXin Li<link rel="stylesheet" href="javaguide.css"> 7*8c35d5eeSXin Li<script src="include/styleguide.js"></script> 8*8c35d5eeSXin Li<link rel="shortcut icon" href="https://www.google.com/favicon.ico"> 9*8c35d5eeSXin Li<script src="include/jsguide.js"></script> 10*8c35d5eeSXin Li</head> 11*8c35d5eeSXin Li<body onload="initStyleGuide();"> 12*8c35d5eeSXin Li<div id="content"> 13*8c35d5eeSXin Li<h1>Google JavaScript Style Guide</h1> 14*8c35d5eeSXin Li<h2 id="introduction">1 Introduction</h2> 15*8c35d5eeSXin Li 16*8c35d5eeSXin Li<p>This document serves as the <strong>complete</strong> definition of Google’s coding standards 17*8c35d5eeSXin Lifor source code in the JavaScript programming language. A JavaScript source file 18*8c35d5eeSXin Liis described as being <em>in Google Style</em> if and only if it adheres to the rules 19*8c35d5eeSXin Liherein.</p> 20*8c35d5eeSXin Li 21*8c35d5eeSXin Li<p>Like other programming style guides, the issues covered span not only aesthetic 22*8c35d5eeSXin Liissues of formatting, but other types of conventions or coding standards as 23*8c35d5eeSXin Liwell. However, this document focuses primarily on the hard-and-fast rules that 24*8c35d5eeSXin Liwe follow universally, and avoids giving advice that isn't clearly enforceable 25*8c35d5eeSXin Li(whether by human or tool). </p> 26*8c35d5eeSXin Li 27*8c35d5eeSXin Li<h3 id="terminology-notes">1.1 Terminology notes</h3> 28*8c35d5eeSXin Li 29*8c35d5eeSXin Li<p>In this document, unless otherwise clarified:</p> 30*8c35d5eeSXin Li 31*8c35d5eeSXin Li<ol> 32*8c35d5eeSXin Li<li><p>The term <em>comment</em> always refers to <em>implementation</em> comments. We do not use 33*8c35d5eeSXin Lithe phrase <q>documentation comments</q>, instead using the common term “JSDoc” 34*8c35d5eeSXin Lifor both human-readable text and machine-readable annotations within 35*8c35d5eeSXin Li<code>/** … */</code>.</p></li> 36*8c35d5eeSXin 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>, 37*8c35d5eeSXin Li<em>must not</em>, <em>should</em>, <em>should not</em>, and <em>may</em>. The terms <em>prefer</em> and 38*8c35d5eeSXin Li<em>avoid</em> correspond to <em>should</em> and <em>should not</em>, respectively. Imperative 39*8c35d5eeSXin Liand declarative statements are prescriptive and correspond to <em>must</em>.</p></li> 40*8c35d5eeSXin Li</ol> 41*8c35d5eeSXin Li 42*8c35d5eeSXin Li<p>Other <q>terminology notes</q> will appear occasionally throughout the document.</p> 43*8c35d5eeSXin Li 44*8c35d5eeSXin Li<h3 id="guide-notes">1.2 Guide notes</h3> 45*8c35d5eeSXin Li 46*8c35d5eeSXin Li<p>Example code in this document is <strong>non-normative</strong>. That is, while the examples 47*8c35d5eeSXin Liare in Google Style, they may not illustrate the <em>only</em> stylish way to represent 48*8c35d5eeSXin Lithe code. Optional formatting choices made in examples must not be enforced as 49*8c35d5eeSXin Lirules.</p> 50*8c35d5eeSXin Li 51*8c35d5eeSXin Li<h2 id="source-file-basics">2 Source file basics</h2> 52*8c35d5eeSXin Li 53*8c35d5eeSXin Li<h3 id="file-name">2.1 File name</h3> 54*8c35d5eeSXin Li 55*8c35d5eeSXin Li<p>File names must be all lowercase and may include underscores (<code>_</code>) or dashes 56*8c35d5eeSXin Li(<code>-</code>), but no additional punctuation. Follow the convention that your project 57*8c35d5eeSXin Liuses. Filenames’ extension must be <code>.js</code>.</p> 58*8c35d5eeSXin Li 59*8c35d5eeSXin Li<h3 id="file-encoding">2.2 File encoding: UTF-8</h3> 60*8c35d5eeSXin Li 61*8c35d5eeSXin Li<p>Source files are encoded in <strong>UTF-8</strong>.</p> 62*8c35d5eeSXin Li 63*8c35d5eeSXin Li<h3 id="special-characters">2.3 Special characters</h3> 64*8c35d5eeSXin Li 65*8c35d5eeSXin Li<h4 id="whitespace-characters">2.3.1 Whitespace characters</h4> 66*8c35d5eeSXin Li 67*8c35d5eeSXin Li<p>Aside from the line terminator sequence, the ASCII horizontal space character 68*8c35d5eeSXin Li(0x20) is the only whitespace character that appears anywhere in a source 69*8c35d5eeSXin Lifile. This implies that</p> 70*8c35d5eeSXin Li 71*8c35d5eeSXin Li<ol> 72*8c35d5eeSXin Li<li><p>All other whitespace characters in string literals are escaped, and</p></li> 73*8c35d5eeSXin Li<li><p>Tab characters are <strong>not</strong> used for indentation.</p></li> 74*8c35d5eeSXin Li</ol> 75*8c35d5eeSXin Li 76*8c35d5eeSXin Li<h4 id="special-escape-sequences">2.3.2 Special escape sequences</h4> 77*8c35d5eeSXin Li 78*8c35d5eeSXin Li<p>For any character that has a special escape sequence (<code>\'</code>, <code>\"</code>, <code>\\</code>, <code>\b</code>, 79*8c35d5eeSXin Li<code>\f</code>, <code>\n</code>, <code>\r</code>, <code>\t</code>, <code>\v</code>), that sequence is used rather than the 80*8c35d5eeSXin Licorresponding numeric escape (e.g <code>\x0a</code>, <code>\u000a</code>, or <code>\u{a}</code>). Legacy octal 81*8c35d5eeSXin Liescapes are never used.</p> 82*8c35d5eeSXin Li 83*8c35d5eeSXin Li<h4 id="non-ascii-characters">2.3.3 Non-ASCII characters</h4> 84*8c35d5eeSXin Li 85*8c35d5eeSXin Li<p>For the remaining non-ASCII characters, either the actual Unicode character 86*8c35d5eeSXin Li(e.g. <code>∞</code>) or the equivalent hex or Unicode escape (e.g. <code>\u221e</code>) is used, 87*8c35d5eeSXin Lidepending only on which makes the code <strong>easier to read and understand</strong>.</p> 88*8c35d5eeSXin Li 89*8c35d5eeSXin Li<p>Tip: In the Unicode escape case, and occasionally even when actual Unicode 90*8c35d5eeSXin Licharacters are used, an explanatory comment can be very helpful.</p> 91*8c35d5eeSXin Li 92*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/* Best: perfectly clear even without a comment. */ 93*8c35d5eeSXin Liconst units = 'μs'; 94*8c35d5eeSXin Li 95*8c35d5eeSXin Li/* Allowed: but unncessary as μ is a printable character. */ 96*8c35d5eeSXin Liconst units = '\u03bcs'; // 'μs' 97*8c35d5eeSXin Li 98*8c35d5eeSXin Li/* Good: use escapes for non-printable characters with a comment for clarity. */ 99*8c35d5eeSXin Lireturn '\ufeff' + content; // Prepend a byte order mark. 100*8c35d5eeSXin Li</code></pre> 101*8c35d5eeSXin Li 102*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">/* Poor: the reader has no idea what character this is. */ 103*8c35d5eeSXin Liconst units = '\u03bcs'; 104*8c35d5eeSXin Li</code></pre> 105*8c35d5eeSXin Li 106*8c35d5eeSXin Li<p>Tip: Never make your code less readable simply out of fear that some programs 107*8c35d5eeSXin Limight not handle non-ASCII characters properly. If that happens, those programs 108*8c35d5eeSXin Liare <strong>broken</strong> and they must be <strong>fixed</strong>.</p> 109*8c35d5eeSXin Li 110*8c35d5eeSXin Li<h2 id="source-file-structure">3 Source file structure</h2> 111*8c35d5eeSXin Li 112*8c35d5eeSXin Li<p>All new source files should either be a <code>goog.module</code> file (a file containing a 113*8c35d5eeSXin Li<code>goog.module</code> call) or an ECMAScript (ES) module (uses <code>import</code> and <code>export</code> 114*8c35d5eeSXin Listatements). Files consist of the following, <strong>in order</strong>:</p> 115*8c35d5eeSXin Li 116*8c35d5eeSXin Li<ol> 117*8c35d5eeSXin Li<li>License or copyright information, if present</li> 118*8c35d5eeSXin Li<li><code>@fileoverview</code> JSDoc, if present</li> 119*8c35d5eeSXin Li<li><code>goog.module</code> statement, if a <code>goog.module</code> file</li> 120*8c35d5eeSXin Li<li>ES <code>import</code> statements, if an ES module</li> 121*8c35d5eeSXin Li<li><code>goog.require</code> and <code>goog.requireType</code> statements</li> 122*8c35d5eeSXin Li<li>The file’s implementation</li> 123*8c35d5eeSXin Li</ol> 124*8c35d5eeSXin Li 125*8c35d5eeSXin Li<p><strong>Exactly one blank line</strong> separates each section that is present, except the 126*8c35d5eeSXin Lifile's implementation, which may be preceded by 1 or 2 blank lines.</p> 127*8c35d5eeSXin Li 128*8c35d5eeSXin Li<h3 id="file-copyright">3.1 License or copyright information, if present</h3> 129*8c35d5eeSXin Li 130*8c35d5eeSXin Li<p>If license or copyright information belongs in a file, it belongs here.</p> 131*8c35d5eeSXin Li 132*8c35d5eeSXin Li<h3 id="file-fileoverview">3.2 <code>@fileoverview</code> JSDoc, if present</h3> 133*8c35d5eeSXin Li 134*8c35d5eeSXin Li<p>See <a href="#jsdoc-top-file-level-comments">??</a> for formatting rules.</p> 135*8c35d5eeSXin Li 136*8c35d5eeSXin Li<h3 id="file-goog-module">3.3 <code>goog.module</code> statement</h3> 137*8c35d5eeSXin Li 138*8c35d5eeSXin Li<p>All <code>goog.module</code> files must declare exactly one <code>goog.module</code> name on a single 139*8c35d5eeSXin Liline: lines containing a <code>goog.module</code> declaration must not be wrapped, and are 140*8c35d5eeSXin Litherefore an exception to the 80-column limit.</p> 141*8c35d5eeSXin Li 142*8c35d5eeSXin Li<p>The entire argument to goog.module is what defines a namespace. It is the 143*8c35d5eeSXin Lipackage name (an identifier that reflects the fragment of the directory 144*8c35d5eeSXin Listructure where the code lives) plus, optionally, the main class/enum/interface 145*8c35d5eeSXin Lithat it defines concatenated to the end.</p> 146*8c35d5eeSXin Li 147*8c35d5eeSXin Li<p>Example</p> 148*8c35d5eeSXin Li 149*8c35d5eeSXin Li<pre><code class="language-js prettyprint">goog.module('search.urlHistory.UrlHistoryService'); 150*8c35d5eeSXin Li</code></pre> 151*8c35d5eeSXin Li 152*8c35d5eeSXin Li<h4 id="naming-hierarchy">3.3.1 Hierarchy</h4> 153*8c35d5eeSXin Li 154*8c35d5eeSXin Li<p>Module namespaces may never be named as a <em>direct</em> child of another module's 155*8c35d5eeSXin Linamespace.</p> 156*8c35d5eeSXin Li 157*8c35d5eeSXin Li<p>Disallowed:</p> 158*8c35d5eeSXin Li 159*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though 160*8c35d5eeSXin Ligoog.module('foo.bar.baz'); 161*8c35d5eeSXin Li</code></pre> 162*8c35d5eeSXin Li 163*8c35d5eeSXin Li<p>The directory hierarchy reflects the namespace hierarchy, so that deeper-nested 164*8c35d5eeSXin Lichildren are subdirectories of higher-level parent directories. Note that this 165*8c35d5eeSXin Liimplies that owners of “parent” namespace groups are necessarily aware of all 166*8c35d5eeSXin Lichild namespaces, since they exist in the same directory.</p> 167*8c35d5eeSXin Li 168*8c35d5eeSXin Li<h4 id="file-declare-legacy-namespace">3.3.2 <code>goog.module.declareLegacyNamespace</code></h4> 169*8c35d5eeSXin Li 170*8c35d5eeSXin Li<p>The single <code>goog.module</code> statement may optionally be followed by a call to 171*8c35d5eeSXin Li<code>goog.module.declareLegacyNamespace();</code>. Avoid 172*8c35d5eeSXin Li<code>goog.module.declareLegacyNamespace()</code> when possible.</p> 173*8c35d5eeSXin Li 174*8c35d5eeSXin Li<p>Example:</p> 175*8c35d5eeSXin Li 176*8c35d5eeSXin Li<pre><code class="language-js prettyprint">goog.module('my.test.helpers'); 177*8c35d5eeSXin Ligoog.module.declareLegacyNamespace(); 178*8c35d5eeSXin Ligoog.setTestOnly(); 179*8c35d5eeSXin Li</code></pre> 180*8c35d5eeSXin Li 181*8c35d5eeSXin Li<p><code>goog.module.declareLegacyNamespace</code> exists to ease the transition from 182*8c35d5eeSXin Litraditional object hierarchy-based namespaces but comes with some naming 183*8c35d5eeSXin Lirestrictions. As the child module name must be created after the parent 184*8c35d5eeSXin Linamespace, this name <strong>must not</strong> be a child or parent of any other 185*8c35d5eeSXin Li<code>goog.module</code> (for example, <code>goog.module('parent');</code> and 186*8c35d5eeSXin Li<code>goog.module('parent.child');</code> cannot both exist safely, nor can 187*8c35d5eeSXin Li<code>goog.module('parent');</code> and <code>goog.module('parent.child.grandchild');</code>).</p> 188*8c35d5eeSXin Li 189*8c35d5eeSXin Li<h3 id="file-goog-module-exports">3.3.3 <code>goog.module</code> Exports</h3> 190*8c35d5eeSXin Li 191*8c35d5eeSXin Li<p>Classes, enums, functions, constants, and other symbols are exported using the 192*8c35d5eeSXin Li<code>exports</code> object. Exported symbols may be defined directly on the <code>exports</code> 193*8c35d5eeSXin Liobject, or else declared locally and exported separately. Symbols are only 194*8c35d5eeSXin Liexported if they are meant to be used outside the module. Non-exported 195*8c35d5eeSXin Limodule-local symbols are not declared <code>@private</code> nor do their names end with an 196*8c35d5eeSXin Liunderscore. There is no prescribed ordering for exported and module-local 197*8c35d5eeSXin Lisymbols.</p> 198*8c35d5eeSXin Li 199*8c35d5eeSXin Li<p>Examples:</p> 200*8c35d5eeSXin Li 201*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const /** !Array<number> */ exportedArray = [1, 2, 3]; 202*8c35d5eeSXin Li 203*8c35d5eeSXin Liconst /** !Array<number> */ moduleLocalArray = [4, 5, 6]; 204*8c35d5eeSXin Li 205*8c35d5eeSXin Li/** @return {number} */ 206*8c35d5eeSXin Lifunction moduleLocalFunction() { 207*8c35d5eeSXin Li return moduleLocalArray.length; 208*8c35d5eeSXin Li} 209*8c35d5eeSXin Li 210*8c35d5eeSXin Li/** @return {number} */ 211*8c35d5eeSXin Lifunction exportedFunction() { 212*8c35d5eeSXin Li return moduleLocalFunction() * 2; 213*8c35d5eeSXin Li} 214*8c35d5eeSXin Li 215*8c35d5eeSXin Liexports = {exportedArray, exportedFunction}; 216*8c35d5eeSXin Li</code></pre> 217*8c35d5eeSXin Li 218*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @const {number} */ 219*8c35d5eeSXin Liexports.CONSTANT_ONE = 1; 220*8c35d5eeSXin Li 221*8c35d5eeSXin Li/** @const {string} */ 222*8c35d5eeSXin Liexports.CONSTANT_TWO = 'Another constant'; 223*8c35d5eeSXin Li</code></pre> 224*8c35d5eeSXin Li 225*8c35d5eeSXin Li<p>Do not annotate the <code>exports</code> object as <code>@const</code> as it is already treated as a 226*8c35d5eeSXin Liconstant by the compiler.</p> 227*8c35d5eeSXin Li 228*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">/** @const */ 229*8c35d5eeSXin Liexports = {exportedFunction}; 230*8c35d5eeSXin Li</code></pre> 231*8c35d5eeSXin Li 232*8c35d5eeSXin Li<p><span id="file-es6-modules"></span></p> 233*8c35d5eeSXin Li 234*8c35d5eeSXin Li<h3 id="file-es-modules">3.4 ES modules</h3> 235*8c35d5eeSXin Li 236*8c35d5eeSXin Li<p><span id="es6-module-imports"></span></p> 237*8c35d5eeSXin Li 238*8c35d5eeSXin Li<h4 id="es-module-imports">3.4.1 Imports</h4> 239*8c35d5eeSXin Li 240*8c35d5eeSXin Li<p>Import statements must not be line wrapped and are therefore an exception to the 241*8c35d5eeSXin Li80-column limit.</p> 242*8c35d5eeSXin Li 243*8c35d5eeSXin Li<p><span id="es6-import-paths"></span></p> 244*8c35d5eeSXin Li 245*8c35d5eeSXin Li<h5 id="esm-import-paths">3.4.1.1 Import paths</h5> 246*8c35d5eeSXin Li 247*8c35d5eeSXin Li<p>ES module files must use the <code>import</code> statement to import other ES module 248*8c35d5eeSXin Lifiles. Do not <code>goog.require</code> another ES module.</p> 249*8c35d5eeSXin Li 250*8c35d5eeSXin Li<pre><code class="language-js prettyprint external">import './sideeffects.js'; 251*8c35d5eeSXin Li 252*8c35d5eeSXin Liimport * as goog from '../closure/goog/goog.js'; 253*8c35d5eeSXin Liimport * as parent from '../parent.js'; 254*8c35d5eeSXin Li 255*8c35d5eeSXin Liimport {name} from './sibling.js'; 256*8c35d5eeSXin Li</code></pre> 257*8c35d5eeSXin Li 258*8c35d5eeSXin Li<p><span id="es6-import-paths-file-extension"></span></p> 259*8c35d5eeSXin Li 260*8c35d5eeSXin Li<h6 id="esm-import-paths-file-extension">3.4.1.1.1 File extensions in import paths</h6> 261*8c35d5eeSXin Li 262*8c35d5eeSXin Li<p>The <code>.js</code> file extension is not optional in import paths and must always be 263*8c35d5eeSXin Liincluded.</p> 264*8c35d5eeSXin Li 265*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">import '../directory/file'; 266*8c35d5eeSXin Li</code></pre> 267*8c35d5eeSXin Li 268*8c35d5eeSXin Li<pre><code class="language-js good prettyprint">import '../directory/file.js'; 269*8c35d5eeSXin Li</code></pre> 270*8c35d5eeSXin Li 271*8c35d5eeSXin Li<h5 id="importing-the-same-file-multiple-times">3.4.1.2 Importing the same file multiple times</h5> 272*8c35d5eeSXin Li 273*8c35d5eeSXin Li<p>Do not import the same file multiple times. This can make it hard to determine 274*8c35d5eeSXin Lithe aggregate imports of a file.</p> 275*8c35d5eeSXin Li 276*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">// Imports have the same path, but since it doesn't align it can be hard to see. 277*8c35d5eeSXin Liimport {short} from './long/path/to/a/file.js'; 278*8c35d5eeSXin Liimport {aLongNameThatBreaksAlignment} from './long/path/to/a/file.js'; 279*8c35d5eeSXin Li</code></pre> 280*8c35d5eeSXin Li 281*8c35d5eeSXin Li<p><span id="naming-es6-imports"></span></p> 282*8c35d5eeSXin Li 283*8c35d5eeSXin Li<h5 id="naming-esm-imports">3.4.1.3 Naming imports</h5> 284*8c35d5eeSXin Li 285*8c35d5eeSXin Li<h6 id="naming-module-imports">3.4.1.3.1 Naming module imports</h6> 286*8c35d5eeSXin Li 287*8c35d5eeSXin Li<p>Module import names (<code>import * as name</code>) are <code>lowerCamelCase</code> names that are 288*8c35d5eeSXin Liderived from the imported file name.</p> 289*8c35d5eeSXin Li 290*8c35d5eeSXin Li<pre><code class="language-js prettyprint">import * as fileOne from '../file-one.js'; 291*8c35d5eeSXin Liimport * as fileTwo from '../file_two.js'; 292*8c35d5eeSXin Liimport * as fileThree from '../filethree.js'; 293*8c35d5eeSXin Li</code></pre> 294*8c35d5eeSXin Li 295*8c35d5eeSXin Li<pre><code class="language-js prettyprint">import * as libString from './lib/string.js'; 296*8c35d5eeSXin Liimport * as math from './math/math.js'; 297*8c35d5eeSXin Liimport * as vectorMath from './vector/math.js'; 298*8c35d5eeSXin Li</code></pre> 299*8c35d5eeSXin Li 300*8c35d5eeSXin Li<h6 id="naming-default-imports">3.4.1.3.2 Naming default imports</h6> 301*8c35d5eeSXin Li 302*8c35d5eeSXin Li<p>Default import names are derived from the imported file name and follow the 303*8c35d5eeSXin Lirules in <a href="#naming-rules-by-identifier-type">??</a>.</p> 304*8c35d5eeSXin Li 305*8c35d5eeSXin Li<pre><code class="language-js prettyprint">import MyClass from '../my-class.js'; 306*8c35d5eeSXin Liimport myFunction from '../my_function.js'; 307*8c35d5eeSXin Liimport SOME_CONSTANT from '../someconstant.js'; 308*8c35d5eeSXin Li</code></pre> 309*8c35d5eeSXin Li 310*8c35d5eeSXin Li<p>Note: In general this should not happen as default exports are banned by this 311*8c35d5eeSXin Listyle guide, see <a href="#named-vs-default-exports">??</a>. Default imports are only used 312*8c35d5eeSXin Lito import modules that do not conform to this style guide.</p> 313*8c35d5eeSXin Li 314*8c35d5eeSXin Li<h6 id="naming-named-imports">3.4.1.3.3 Naming named imports</h6> 315*8c35d5eeSXin Li 316*8c35d5eeSXin Li<p>In general symbols imported via the named import (<code>import {name}</code>) should keep 317*8c35d5eeSXin Lithe same name. Avoid aliasing imports (<code>import {SomeThing as SomeOtherThing}</code>). 318*8c35d5eeSXin LiPrefer fixing name collisions by using a module import (<code>import *</code>) or renaming 319*8c35d5eeSXin Lithe exports themselves.</p> 320*8c35d5eeSXin Li 321*8c35d5eeSXin Li<pre><code class="language-js prettyprint">import * as bigAnimals from './biganimals.js'; 322*8c35d5eeSXin Liimport * as domesticatedAnimals from './domesticatedanimals.js'; 323*8c35d5eeSXin Li 324*8c35d5eeSXin Linew bigAnimals.Cat(); 325*8c35d5eeSXin Linew domesticatedAnimals.Cat(); 326*8c35d5eeSXin Li</code></pre> 327*8c35d5eeSXin Li 328*8c35d5eeSXin Li<p>If renaming a named import is needed then use components of the imported 329*8c35d5eeSXin Limodule's file name or path in the resulting alias.</p> 330*8c35d5eeSXin Li 331*8c35d5eeSXin Li<pre><code class="language-js prettyprint">import {Cat as BigCat} from './biganimals.js'; 332*8c35d5eeSXin Liimport {Cat as DomesticatedCat} from './domesticatedanimals.js'; 333*8c35d5eeSXin Li 334*8c35d5eeSXin Linew BigCat(); 335*8c35d5eeSXin Linew DomesticatedCat(); 336*8c35d5eeSXin Li</code></pre> 337*8c35d5eeSXin Li 338*8c35d5eeSXin Li<p><span id="es6-module-exports"></span></p> 339*8c35d5eeSXin Li 340*8c35d5eeSXin Li<h4 id="es-module-exports">3.4.2 Exports</h4> 341*8c35d5eeSXin Li 342*8c35d5eeSXin Li<p>Symbols are only exported if they are meant to be used outside the module. 343*8c35d5eeSXin LiNon-exported module-local symbols are not declared <code>@private</code> nor do their names 344*8c35d5eeSXin Liend with an underscore. There is no prescribed ordering for exported and 345*8c35d5eeSXin Limodule-local symbols.</p> 346*8c35d5eeSXin Li 347*8c35d5eeSXin Li<h5 id="named-vs-default-exports">3.4.2.1 Named vs default exports</h5> 348*8c35d5eeSXin Li 349*8c35d5eeSXin Li<p>Use named exports in all code. You can apply the <code>export</code> keyword to a 350*8c35d5eeSXin Lideclaration, or use the <code>export {name};</code> syntax.</p> 351*8c35d5eeSXin Li 352*8c35d5eeSXin Li<p>Do not use default exports. Importing modules must give a name to these values, 353*8c35d5eeSXin Liwhich can lead to inconsistencies in naming across modules.</p> 354*8c35d5eeSXin Li 355*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">// Do not use default exports: 356*8c35d5eeSXin Liexport default class Foo { ... } // BAD! 357*8c35d5eeSXin Li</code></pre> 358*8c35d5eeSXin Li 359*8c35d5eeSXin Li<pre><code class="language-js good prettyprint">// Use named exports: 360*8c35d5eeSXin Liexport class Foo { ... } 361*8c35d5eeSXin Li</code></pre> 362*8c35d5eeSXin Li 363*8c35d5eeSXin Li<pre><code class="language-js good prettyprint">// Alternate style named exports: 364*8c35d5eeSXin Liclass Foo { ... } 365*8c35d5eeSXin Li 366*8c35d5eeSXin Liexport {Foo}; 367*8c35d5eeSXin Li</code></pre> 368*8c35d5eeSXin Li 369*8c35d5eeSXin Li<h5 id="exporting-static-containers">3.4.2.2 Exporting static container classes and objects</h5> 370*8c35d5eeSXin Li 371*8c35d5eeSXin Li<p>Do not export container classes or objects with static methods or properties for 372*8c35d5eeSXin Lithe sake of namespacing.</p> 373*8c35d5eeSXin Li 374*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">// container.js 375*8c35d5eeSXin Li// Bad: Container is an exported class that has only static methods and fields. 376*8c35d5eeSXin Liexport class Container { 377*8c35d5eeSXin Li /** @return {number} */ 378*8c35d5eeSXin Li static bar() { 379*8c35d5eeSXin Li return 1; 380*8c35d5eeSXin Li } 381*8c35d5eeSXin Li} 382*8c35d5eeSXin Li 383*8c35d5eeSXin Li/** @const {number} */ 384*8c35d5eeSXin LiContainer.FOO = 1; 385*8c35d5eeSXin Li</code></pre> 386*8c35d5eeSXin Li 387*8c35d5eeSXin Li<p>Instead, export individual constants and functions:</p> 388*8c35d5eeSXin Li 389*8c35d5eeSXin Li<pre><code class="language-js good prettyprint">/** @return {number} */ 390*8c35d5eeSXin Liexport function bar() { 391*8c35d5eeSXin Li return 1; 392*8c35d5eeSXin Li} 393*8c35d5eeSXin Li 394*8c35d5eeSXin Liexport const /** number */ FOO = 1; 395*8c35d5eeSXin Li</code></pre> 396*8c35d5eeSXin Li 397*8c35d5eeSXin Li<p><span id="es6-exports-mutability"></span></p> 398*8c35d5eeSXin Li 399*8c35d5eeSXin Li<h5 id="esm-exports-mutability">3.4.2.3 Mutability of exports</h5> 400*8c35d5eeSXin Li 401*8c35d5eeSXin Li<p>Exported variables must not be mutated outside of module initialization.</p> 402*8c35d5eeSXin Li 403*8c35d5eeSXin Li<p>There are alternatives if mutation is needed, including exporting a constant 404*8c35d5eeSXin Lireference to an object that has mutable fields or exporting accessor functions for 405*8c35d5eeSXin Limutable data.</p> 406*8c35d5eeSXin Li 407*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">// Bad: both foo and mutateFoo are exported and mutated. 408*8c35d5eeSXin Liexport let /** number */ foo = 0; 409*8c35d5eeSXin Li 410*8c35d5eeSXin Li/** 411*8c35d5eeSXin Li * Mutates foo. 412*8c35d5eeSXin Li */ 413*8c35d5eeSXin Liexport function mutateFoo() { 414*8c35d5eeSXin Li ++foo; 415*8c35d5eeSXin Li} 416*8c35d5eeSXin Li 417*8c35d5eeSXin Li/** 418*8c35d5eeSXin Li * @param {function(number): number} newMutateFoo 419*8c35d5eeSXin Li */ 420*8c35d5eeSXin Liexport function setMutateFoo(newMutateFoo) { 421*8c35d5eeSXin Li // Exported classes and functions can be mutated! 422*8c35d5eeSXin Li mutateFoo = () => { 423*8c35d5eeSXin Li foo = newMutateFoo(foo); 424*8c35d5eeSXin Li }; 425*8c35d5eeSXin Li} 426*8c35d5eeSXin Li</code></pre> 427*8c35d5eeSXin Li 428*8c35d5eeSXin Li<pre><code class="language-js good prettyprint">// Good: Rather than export the mutable variables foo and mutateFoo directly, 429*8c35d5eeSXin Li// instead make them module scoped and export a getter for foo and a wrapper for 430*8c35d5eeSXin Li// mutateFooFunc. 431*8c35d5eeSXin Lilet /** number */ foo = 0; 432*8c35d5eeSXin Lilet /** function(number): number */ mutateFooFunc = foo => foo + 1; 433*8c35d5eeSXin Li 434*8c35d5eeSXin Li/** @return {number} */ 435*8c35d5eeSXin Liexport function getFoo() { 436*8c35d5eeSXin Li return foo; 437*8c35d5eeSXin Li} 438*8c35d5eeSXin Li 439*8c35d5eeSXin Liexport function mutateFoo() { 440*8c35d5eeSXin Li foo = mutateFooFunc(foo); 441*8c35d5eeSXin Li} 442*8c35d5eeSXin Li 443*8c35d5eeSXin Li/** @param {function(number): number} mutateFoo */ 444*8c35d5eeSXin Liexport function setMutateFoo(mutateFoo) { 445*8c35d5eeSXin Li mutateFooFunc = mutateFoo; 446*8c35d5eeSXin Li} 447*8c35d5eeSXin Li</code></pre> 448*8c35d5eeSXin Li 449*8c35d5eeSXin Li<p><span id="es6-module-circular-dependencies"></span></p> 450*8c35d5eeSXin Li 451*8c35d5eeSXin Li<h5 id="es-module-export-from">3.4.2.4 export from</h5> 452*8c35d5eeSXin Li 453*8c35d5eeSXin Li<p><code>export from</code> statements must not be line wrapped and are therefore an 454*8c35d5eeSXin Liexception to the 80-column limit. This applies to both <code>export from</code> flavors.</p> 455*8c35d5eeSXin Li 456*8c35d5eeSXin Li<pre><code class="language-js">export {specificName} from './other.js'; 457*8c35d5eeSXin Liexport * from './another.js'; 458*8c35d5eeSXin Li</code></pre> 459*8c35d5eeSXin Li 460*8c35d5eeSXin Li<h4 id="es-module-circular-dependencies">3.4.3 Circular Dependencies in ES modules</h4> 461*8c35d5eeSXin Li 462*8c35d5eeSXin Li<p>Do not create cycles between ES modules, even though the ECMAScript 463*8c35d5eeSXin Lispecification allows this. Note that it is possible to create cycles with both 464*8c35d5eeSXin Lithe <code>import</code> and <code>export</code> statements.</p> 465*8c35d5eeSXin Li 466*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">// a.js 467*8c35d5eeSXin Liimport './b.js'; 468*8c35d5eeSXin Li</code></pre> 469*8c35d5eeSXin Li 470*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">// b.js 471*8c35d5eeSXin Liimport './a.js'; 472*8c35d5eeSXin Li 473*8c35d5eeSXin Li// `export from` can cause circular dependencies too! 474*8c35d5eeSXin Liexport {x} from './c.js'; 475*8c35d5eeSXin Li</code></pre> 476*8c35d5eeSXin Li 477*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">// c.js 478*8c35d5eeSXin Liimport './b.js'; 479*8c35d5eeSXin Li 480*8c35d5eeSXin Liexport let x; 481*8c35d5eeSXin Li</code></pre> 482*8c35d5eeSXin Li 483*8c35d5eeSXin Li<p><span id="es6-module-closure-interop"></span></p> 484*8c35d5eeSXin Li 485*8c35d5eeSXin Li<h4 id="es-module-closure-interop">3.4.4 Interoperating with Closure</h4> 486*8c35d5eeSXin Li 487*8c35d5eeSXin Li<p><span id="es6-module-referencing-goog"></span></p> 488*8c35d5eeSXin Li 489*8c35d5eeSXin Li<h5 id="es-module-referencing-goog">3.4.4.1 Referencing goog</h5> 490*8c35d5eeSXin Li 491*8c35d5eeSXin Li<p>To reference the Closure <code>goog</code> namespace, import Closure's <code>goog.js</code>.</p> 492*8c35d5eeSXin Li 493*8c35d5eeSXin Li<pre><code class="language-js good prettyprint external">import * as goog from '../closure/goog/goog.js'; 494*8c35d5eeSXin Li 495*8c35d5eeSXin Liconst name = goog.require('a.name'); 496*8c35d5eeSXin Li 497*8c35d5eeSXin Liexport const CONSTANT = name.compute(); 498*8c35d5eeSXin Li</code></pre> 499*8c35d5eeSXin Li 500*8c35d5eeSXin Li<p><code>goog.js</code> exports only a subset of properties from the global <code>goog</code> that can be 501*8c35d5eeSXin Liused in ES modules.</p> 502*8c35d5eeSXin Li 503*8c35d5eeSXin Li<p><span id="goog-require-in-es6-module"></span></p> 504*8c35d5eeSXin Li 505*8c35d5eeSXin Li<h5 id="goog-require-in-es-module">3.4.4.2 goog.require in ES modules</h5> 506*8c35d5eeSXin Li 507*8c35d5eeSXin Li<p><code>goog.require</code> in ES modules works as it does in <code>goog.module</code> files. You can 508*8c35d5eeSXin Lirequire any Closure namespace symbol (i.e., symbols created by <code>goog.provide</code> or 509*8c35d5eeSXin Li<code>goog.module</code>) and <code>goog.require</code> will return the value.</p> 510*8c35d5eeSXin Li 511*8c35d5eeSXin Li<pre><code class="language-js prettyprint external">import * as goog from '../closure/goog/goog.js'; 512*8c35d5eeSXin Liimport * as anEsModule from './anEsModule.js'; 513*8c35d5eeSXin Li 514*8c35d5eeSXin Liconst GoogPromise = goog.require('goog.Promise'); 515*8c35d5eeSXin Liconst myNamespace = goog.require('my.namespace'); 516*8c35d5eeSXin Li</code></pre> 517*8c35d5eeSXin Li 518*8c35d5eeSXin Li<p><span id="closure-module-id-in-es6-module"></span></p> 519*8c35d5eeSXin Li 520*8c35d5eeSXin Li<h5 id="closure-module-id-in-es-module">3.4.4.3 Declaring Closure Module IDs in ES modules</h5> 521*8c35d5eeSXin Li 522*8c35d5eeSXin Li<p><code>goog.declareModuleId</code> can be used within ES modules to declare a 523*8c35d5eeSXin Li<code>goog.module</code>-like module ID. This means that this module ID can be 524*8c35d5eeSXin Li<code>goog.require</code>d, <code>goog.module.get</code>d, <code>goog.forwardDeclare</code>'d, etc. as if it were 525*8c35d5eeSXin Lia <code>goog.module</code> that did not call <code>goog.module.declareLegacyNamespace</code>. It does 526*8c35d5eeSXin Linot create the module ID as a globally available JavaScript symbol.</p> 527*8c35d5eeSXin Li 528*8c35d5eeSXin Li<p>A <code>goog.require</code> (or <code>goog.module.get</code>) for a module ID from 529*8c35d5eeSXin Li<code>goog.declareModuleId</code> will always return the module object (as if it was 530*8c35d5eeSXin Li<code>import *</code>'d). As a result, the argument to <code>goog.declareModuleId</code> should always 531*8c35d5eeSXin Liend with a <code>lowerCamelCaseName</code>.</p> 532*8c35d5eeSXin Li 533*8c35d5eeSXin Li<p>Note: It is an error to call <code>goog.module.declareLegacyNamespace</code> in an ES 534*8c35d5eeSXin Limodule, it can only be called from <code>goog.module</code> files. There is no direct way 535*8c35d5eeSXin Lito associate a <q>legacy</q> namespace with an ES module.</p> 536*8c35d5eeSXin Li 537*8c35d5eeSXin Li<p><code>goog.declareModuleId</code> should only be used to upgrade Closure files to ES 538*8c35d5eeSXin Limodules in place, where named exports are used.</p> 539*8c35d5eeSXin Li 540*8c35d5eeSXin Li<pre><code class="language-js prettyprint external">import * as goog from '../closure/goog.js'; 541*8c35d5eeSXin Li 542*8c35d5eeSXin Ligoog.declareModuleId('my.esm'); 543*8c35d5eeSXin Li 544*8c35d5eeSXin Liexport class Class {}; 545*8c35d5eeSXin Li</code></pre> 546*8c35d5eeSXin Li 547*8c35d5eeSXin Li<h3 id="file-set-test-only">3.5 <code>goog.setTestOnly</code></h3> 548*8c35d5eeSXin Li 549*8c35d5eeSXin Li<p>In a <code>goog.module</code> file the <code>goog.module</code> statement may optionally be followed 550*8c35d5eeSXin Liby a call to <code>goog.setTestOnly()</code>.</p> 551*8c35d5eeSXin Li 552*8c35d5eeSXin Li<p>In an ES module the <code>import</code> statements may optionally be followed by a call to 553*8c35d5eeSXin Li<code>goog.setTestOnly()</code>.</p> 554*8c35d5eeSXin Li 555*8c35d5eeSXin Li<h3 id="file-goog-require">3.6 <code>goog.require</code> and <code>goog.requireType</code> statements</h3> 556*8c35d5eeSXin Li 557*8c35d5eeSXin Li<p>Imports are done with <code>goog.require</code> and <code>goog.requireType</code> statements. The 558*8c35d5eeSXin Linames imported by a <code>goog.require</code> statement may be used both in code and in 559*8c35d5eeSXin Litype annotations, while those imported by a <code>goog.requireType</code> may be used 560*8c35d5eeSXin Liin type annotations only.</p> 561*8c35d5eeSXin Li 562*8c35d5eeSXin Li<p>The <code>goog.require</code> and <code>goog.requireType</code> statements form a contiguous block 563*8c35d5eeSXin Liwith no empty lines. This block follows the <code>goog.module</code> declaration separated 564*8c35d5eeSXin Li<a href="#source-file-structure">by a single empty line</a>. The entire argument to 565*8c35d5eeSXin Li<code>goog.require</code> or <code>goog.requireType</code> is a namespace defined by a <code>goog.module</code> 566*8c35d5eeSXin Liin a separate file. <code>goog.require</code> and <code>goog.requireType</code> statements may not 567*8c35d5eeSXin Liappear anywhere else in the file.</p> 568*8c35d5eeSXin Li 569*8c35d5eeSXin Li<p>Each <code>goog.require</code> or <code>goog.requireType</code> is assigned to a single constant 570*8c35d5eeSXin Lialias, or else destructured into several constant aliases. These aliases are the 571*8c35d5eeSXin Lionly acceptable way to refer to dependencies in type annotations or code. Fully 572*8c35d5eeSXin Liqualified namespaces must not be used anywhere, except as an argument to 573*8c35d5eeSXin Li<code>goog.require</code> or <code>goog.requireType</code>.</p> 574*8c35d5eeSXin Li 575*8c35d5eeSXin Li<p><strong>Exception</strong>: Types, variables, and functions declared in externs files have to 576*8c35d5eeSXin Liuse their fully qualified name in type annotations and code.</p> 577*8c35d5eeSXin Li 578*8c35d5eeSXin Li<p>Aliases must match the final dot-separated component of the imported module's 579*8c35d5eeSXin Linamespace.</p> 580*8c35d5eeSXin Li 581*8c35d5eeSXin Li<p><strong>Exception</strong>: In certain cases, additional components of the namespace can be 582*8c35d5eeSXin Liused to form a longer alias. The resulting alias must retain the original 583*8c35d5eeSXin Liidentifier's casing such that it still correctly identifies its type. Longer 584*8c35d5eeSXin Lialiases may be used to disambiguate otherwise identical aliases, or if it 585*8c35d5eeSXin Lisignificantly improves readability. In addition, a longer alias must be used to 586*8c35d5eeSXin Liprevent masking native types such as <code>Element</code>, <code>Event</code>, <code>Error</code>, <code>Map</code>, and 587*8c35d5eeSXin Li<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 588*8c35d5eeSXin LiAPIs</a> at MDN). When renaming destructured aliases, a space must follow the colon 589*8c35d5eeSXin Lias required in <a href="#formatting-horizontal-whitespace">??</a>.</p> 590*8c35d5eeSXin Li 591*8c35d5eeSXin Li<p>A file should not contain both a <code>goog.require</code> and a <code>goog.requireType</code> 592*8c35d5eeSXin Listatement for the same namespace. If the imported name is used both in code and 593*8c35d5eeSXin Liin type annotations, it should be imported by a single <code>goog.require</code> statement.</p> 594*8c35d5eeSXin Li 595*8c35d5eeSXin Li<p>If a module is imported only for its side effects, the call must be a 596*8c35d5eeSXin Li<code>goog.require</code> (not a <code>goog.requireType</code>) and assignment may be omitted. A 597*8c35d5eeSXin Licomment is required to explain why this is needed and suppress a compiler 598*8c35d5eeSXin Liwarning.</p> 599*8c35d5eeSXin Li 600*8c35d5eeSXin Li 601*8c35d5eeSXin Li 602*8c35d5eeSXin Li<p>The lines are sorted according to the following rules: All requires with a name 603*8c35d5eeSXin Lion the left hand side come first, sorted alphabetically by those names. Then 604*8c35d5eeSXin Lidestructuring requires, again sorted by the names on the left hand side. 605*8c35d5eeSXin LiFinally, any require calls that are standalone (generally these are for modules 606*8c35d5eeSXin Liimported just for their side effects).</p> 607*8c35d5eeSXin Li 608*8c35d5eeSXin Li<p>Tip: There’s no need to memorize this order and enforce it manually. You can 609*8c35d5eeSXin Lirely on your IDE to report requires 610*8c35d5eeSXin Lithat are not sorted correctly.</p> 611*8c35d5eeSXin Li 612*8c35d5eeSXin Li<p>If a long alias or module name would cause a line to exceed the 80-column limit, 613*8c35d5eeSXin Liit <strong>must not</strong> be wrapped: require lines are an exception to the 80-column 614*8c35d5eeSXin Lilimit.</p> 615*8c35d5eeSXin Li 616*8c35d5eeSXin Li<p>Example:</p> 617*8c35d5eeSXin Li 618*8c35d5eeSXin Li<pre><code class="language-js prettyprint">// Standard alias style. 619*8c35d5eeSXin Liconst MyClass = goog.require('some.package.MyClass'); 620*8c35d5eeSXin Liconst MyType = goog.requireType('some.package.MyType'); 621*8c35d5eeSXin Li// Namespace-based alias used to disambiguate. 622*8c35d5eeSXin Liconst NsMyClass = goog.require('other.ns.MyClass'); 623*8c35d5eeSXin Li// Namespace-based alias used to prevent masking native type. 624*8c35d5eeSXin Liconst RendererElement = goog.require('web.renderer.Element'); 625*8c35d5eeSXin Li// Out of sequence namespace-based aliases used to improve readability. 626*8c35d5eeSXin Li// Also, require lines longer than 80 columns must not be wrapped. 627*8c35d5eeSXin Liconst SomeDataStructureModel = goog.requireType('identical.package.identifiers.models.SomeDataStructure'); 628*8c35d5eeSXin Liconst SomeDataStructureProto = goog.require('proto.identical.package.identifiers.SomeDataStructure'); 629*8c35d5eeSXin Li// Standard alias style. 630*8c35d5eeSXin Liconst asserts = goog.require('goog.asserts'); 631*8c35d5eeSXin Li// Namespace-based alias used to disambiguate. 632*8c35d5eeSXin Liconst testingAsserts = goog.require('goog.testing.asserts'); 633*8c35d5eeSXin Li// Standard destructuring into aliases. 634*8c35d5eeSXin Liconst {clear, clone} = goog.require('goog.array'); 635*8c35d5eeSXin Liconst {Rgb} = goog.require('goog.color'); 636*8c35d5eeSXin Li// Namespace-based destructuring into aliases in order to disambiguate. 637*8c35d5eeSXin Liconst {SomeType: FooSomeType} = goog.requireType('foo.types'); 638*8c35d5eeSXin Liconst {clear: objectClear, clone: objectClone} = goog.require('goog.object'); 639*8c35d5eeSXin Li// goog.require without an alias in order to trigger side effects. 640*8c35d5eeSXin Li/** @suppress {extraRequire} Initializes MyFramework. */ 641*8c35d5eeSXin Ligoog.require('my.framework.initialization'); 642*8c35d5eeSXin Li</code></pre> 643*8c35d5eeSXin Li 644*8c35d5eeSXin Li<p>Discouraged:</p> 645*8c35d5eeSXin Li 646*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">// If necessary to disambiguate, prefer PackageClass over SomeClass as it is 647*8c35d5eeSXin Li// closer to the format of the module name. 648*8c35d5eeSXin Liconst SomeClass = goog.require('some.package.Class'); 649*8c35d5eeSXin Li</code></pre> 650*8c35d5eeSXin Li 651*8c35d5eeSXin Li<p>Disallowed:</p> 652*8c35d5eeSXin Li 653*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">// Extra terms must come from the namespace. 654*8c35d5eeSXin Liconst MyClassForBizzing = goog.require('some.package.MyClass'); 655*8c35d5eeSXin Li// Alias must include the entire final namespace component. 656*8c35d5eeSXin Liconst MyClass = goog.require('some.package.MyClassForBizzing'); 657*8c35d5eeSXin Li// Alias must not mask native type (should be `const JspbMap` here). 658*8c35d5eeSXin Liconst Map = goog.require('jspb.Map'); 659*8c35d5eeSXin Li// Don't break goog.require lines over 80 columns. 660*8c35d5eeSXin Liconst SomeDataStructure = 661*8c35d5eeSXin Li goog.require('proto.identical.package.identifiers.SomeDataStructure'); 662*8c35d5eeSXin Li// Alias must be based on the namespace. 663*8c35d5eeSXin Liconst randomName = goog.require('something.else'); 664*8c35d5eeSXin Li// Missing a space after the colon. 665*8c35d5eeSXin Liconst {Foo:FooProto} = goog.require('some.package.proto.Foo'); 666*8c35d5eeSXin Li// goog.requireType without an alias. 667*8c35d5eeSXin Ligoog.requireType('some.package.with.a.Type'); 668*8c35d5eeSXin Li 669*8c35d5eeSXin Li 670*8c35d5eeSXin Li/** 671*8c35d5eeSXin Li * @param {!some.unimported.Dependency} param All external types used in JSDoc 672*8c35d5eeSXin Li * annotations must be goog.require'd, unless declared in externs. 673*8c35d5eeSXin Li */ 674*8c35d5eeSXin Lifunction someFunction(param) { 675*8c35d5eeSXin Li // goog.require lines must be at the top level before any other code. 676*8c35d5eeSXin Li const alias = goog.require('my.long.name.alias'); 677*8c35d5eeSXin Li // ... 678*8c35d5eeSXin Li} 679*8c35d5eeSXin Li</code></pre> 680*8c35d5eeSXin Li 681*8c35d5eeSXin Li<h3 id="file-implementation">3.7 The file’s implementation</h3> 682*8c35d5eeSXin Li 683*8c35d5eeSXin Li<p>The actual implementation follows after all dependency information is declared 684*8c35d5eeSXin Li(separated by at least one blank line).</p> 685*8c35d5eeSXin Li 686*8c35d5eeSXin Li<p>This may consist of any module-local declarations (constants, variables, 687*8c35d5eeSXin Liclasses, functions, etc), as well as any exported symbols. 688*8c35d5eeSXin Li</p> 689*8c35d5eeSXin Li 690*8c35d5eeSXin Li<h2 id="formatting">4 Formatting</h2> 691*8c35d5eeSXin Li 692*8c35d5eeSXin Li<p><strong>Terminology Note</strong>: <em>block-like construct</em> refers to the body of a class, 693*8c35d5eeSXin Lifunction, method, or brace-delimited block of code. Note that, by 694*8c35d5eeSXin Li<a href="#features-array-literals">??</a> and <a href="#features-object-literals">??</a>, any array or 695*8c35d5eeSXin Liobject literal may optionally be treated as if it were a block-like construct.</p> 696*8c35d5eeSXin Li 697*8c35d5eeSXin Li<p>Tip: Use <code>clang-format</code>. The JavaScript community has invested effort to make 698*8c35d5eeSXin Lisure clang-format <q>does the right thing</q> on JavaScript files. <code>clang-format</code> has 699*8c35d5eeSXin Liintegration with several popular 700*8c35d5eeSXin Lieditors.</p> 701*8c35d5eeSXin Li 702*8c35d5eeSXin Li<h3 id="formatting-braces">4.1 Braces</h3> 703*8c35d5eeSXin Li 704*8c35d5eeSXin Li<h4 id="formatting-braces-all">4.1.1 Braces are used for all control structures</h4> 705*8c35d5eeSXin Li 706*8c35d5eeSXin Li<p>Braces are required for all control structures (i.e. <code>if</code>, <code>else</code>, <code>for</code>, <code>do</code>, 707*8c35d5eeSXin Li<code>while</code>, as well as any others), even if the body contains only a single 708*8c35d5eeSXin Listatement. The first statement of a non-empty block must begin on its own line.</p> 709*8c35d5eeSXin Li 710*8c35d5eeSXin Li<p>Disallowed:</p> 711*8c35d5eeSXin Li 712*8c35d5eeSXin Li<pre><code class="language-js badcode prettyprint">if (someVeryLongCondition()) 713*8c35d5eeSXin Li doSomething(); 714*8c35d5eeSXin Li 715*8c35d5eeSXin Lifor (let i = 0; i < foo.length; i++) bar(foo[i]); 716*8c35d5eeSXin Li</code></pre> 717*8c35d5eeSXin Li 718*8c35d5eeSXin Li<p><strong>Exception</strong>: A simple if statement that can fit entirely on a single line with 719*8c35d5eeSXin Lino wrapping (and that doesn’t have an else) may be kept on a single line with no 720*8c35d5eeSXin Libraces when it improves readability. This is the only case in which a control 721*8c35d5eeSXin Listructure may omit braces and newlines.</p> 722*8c35d5eeSXin Li 723*8c35d5eeSXin Li<pre><code class="language-js prettyprint">if (shortCondition()) foo(); 724*8c35d5eeSXin Li</code></pre> 725*8c35d5eeSXin Li 726*8c35d5eeSXin Li<h4 id="formatting-nonempty-blocks">4.1.2 Nonempty blocks: K&R style</h4> 727*8c35d5eeSXin Li 728*8c35d5eeSXin Li<p>Braces follow the Kernighan and Ritchie style (<q><a href="http://www.codinghorror.com/blog/2012/07/new-programming-jargon.html">Egyptian brackets</a></q>) for 729*8c35d5eeSXin Li<em>nonempty</em> blocks and block-like constructs:</p> 730*8c35d5eeSXin Li 731*8c35d5eeSXin Li<ul> 732*8c35d5eeSXin Li<li>No line break before the opening brace.</li> 733*8c35d5eeSXin Li<li>Line break after the opening brace.</li> 734*8c35d5eeSXin Li<li>Line break before the closing brace.</li> 735*8c35d5eeSXin Li<li>Line break after the closing brace <em>if</em> that brace terminates a statement or 736*8c35d5eeSXin Lithe body of a function or class statement, or a class method. Specifically, 737*8c35d5eeSXin Lithere is <em>no</em> line break after the brace if it is followed by <code>else</code>, <code>catch</code>, 738*8c35d5eeSXin Li<code>while</code>, or a comma, semicolon, or right-parenthesis.</li> 739*8c35d5eeSXin Li</ul> 740*8c35d5eeSXin Li 741*8c35d5eeSXin Li<p>Example:</p> 742*8c35d5eeSXin Li 743*8c35d5eeSXin Li<pre><code class="language-js prettyprint">class InnerClass { 744*8c35d5eeSXin Li constructor() {} 745*8c35d5eeSXin Li 746*8c35d5eeSXin Li /** @param {number} foo */ 747*8c35d5eeSXin Li method(foo) { 748*8c35d5eeSXin Li if (condition(foo)) { 749*8c35d5eeSXin Li try { 750*8c35d5eeSXin Li // Note: this might fail. 751*8c35d5eeSXin Li something(); 752*8c35d5eeSXin Li } catch (err) { 753*8c35d5eeSXin Li recover(); 754*8c35d5eeSXin Li } 755*8c35d5eeSXin Li } 756*8c35d5eeSXin Li } 757*8c35d5eeSXin Li} 758*8c35d5eeSXin Li</code></pre> 759*8c35d5eeSXin Li 760*8c35d5eeSXin Li<h4 id="formatting-empty-blocks">4.1.3 Empty blocks: may be concise</h4> 761*8c35d5eeSXin Li 762*8c35d5eeSXin Li<p>An empty block or block-like construct <em>may</em> be closed immediately after it is 763*8c35d5eeSXin Liopened, with no characters, space, or line break in between (i.e. <code>{}</code>), 764*8c35d5eeSXin Li<strong>unless</strong> it is a part of a <em>multi-block statement</em> (one that directly contains 765*8c35d5eeSXin Limultiple blocks: <code>if</code>/<code>else</code> or <code>try</code>/<code>catch</code>/<code>finally</code>).</p> 766*8c35d5eeSXin Li 767*8c35d5eeSXin Li<p>Example:</p> 768*8c35d5eeSXin Li 769*8c35d5eeSXin Li<pre><code class="language-js prettyprint">function doNothing() {} 770*8c35d5eeSXin Li</code></pre> 771*8c35d5eeSXin Li 772*8c35d5eeSXin Li<p>Disallowed:</p> 773*8c35d5eeSXin Li 774*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">if (condition) { 775*8c35d5eeSXin Li // … 776*8c35d5eeSXin Li} else if (otherCondition) {} else { 777*8c35d5eeSXin Li // … 778*8c35d5eeSXin Li} 779*8c35d5eeSXin Li 780*8c35d5eeSXin Litry { 781*8c35d5eeSXin Li // … 782*8c35d5eeSXin Li} catch (e) {} 783*8c35d5eeSXin Li</code></pre> 784*8c35d5eeSXin Li 785*8c35d5eeSXin Li<h3 id="formatting-block-indentation">4.2 Block indentation: +2 spaces</h3> 786*8c35d5eeSXin Li 787*8c35d5eeSXin Li<p>Each time a new block or block-like construct is opened, the indent increases by 788*8c35d5eeSXin Litwo spaces. When the block ends, the indent returns to the previous indent 789*8c35d5eeSXin Lilevel. The indent level applies to both code and comments throughout the 790*8c35d5eeSXin Liblock. (See the example in <a href="#formatting-nonempty-blocks">??</a>).</p> 791*8c35d5eeSXin Li 792*8c35d5eeSXin Li<h4 id="formatting-array-literals">4.2.1 Array literals: optionally <q>block-like</q></h4> 793*8c35d5eeSXin Li 794*8c35d5eeSXin Li<p>Any array literal may optionally be formatted as if it were a “block-like 795*8c35d5eeSXin Liconstruct.” For example, the following are all valid (<strong>not</strong> an exhaustive 796*8c35d5eeSXin Lilist):</p> 797*8c35d5eeSXin Li 798*8c35d5eeSXin Li<pre><code class="language-js prettyprint columns">const a = [ 799*8c35d5eeSXin Li 0, 800*8c35d5eeSXin Li 1, 801*8c35d5eeSXin Li 2, 802*8c35d5eeSXin Li]; 803*8c35d5eeSXin Li 804*8c35d5eeSXin Liconst b = 805*8c35d5eeSXin Li [0, 1, 2]; 806*8c35d5eeSXin Li 807*8c35d5eeSXin Li</code></pre> 808*8c35d5eeSXin Li 809*8c35d5eeSXin Li<pre><code class="language-js prettyprint columns">const c = [0, 1, 2]; 810*8c35d5eeSXin Li 811*8c35d5eeSXin LisomeMethod(foo, [ 812*8c35d5eeSXin Li 0, 1, 2, 813*8c35d5eeSXin Li], bar); 814*8c35d5eeSXin Li</code></pre> 815*8c35d5eeSXin Li 816*8c35d5eeSXin Li<p>Other combinations are allowed, particularly when emphasizing semantic groupings 817*8c35d5eeSXin Libetween elements, but should not be used only to reduce the vertical size of 818*8c35d5eeSXin Lilarger arrays.</p> 819*8c35d5eeSXin Li 820*8c35d5eeSXin Li<h4 id="formatting-object-literals">4.2.2 Object literals: optionally <q>block-like</q></h4> 821*8c35d5eeSXin Li 822*8c35d5eeSXin Li<p>Any object literal may optionally be formatted as if it were a “block-like 823*8c35d5eeSXin Liconstruct.” The same examples apply as <a href="#formatting-array-literals">??</a>. For 824*8c35d5eeSXin Liexample, the following are all valid (<strong>not</strong> an exhaustive list):</p> 825*8c35d5eeSXin Li 826*8c35d5eeSXin Li<pre><code class="language-js prettyprint columns">const a = { 827*8c35d5eeSXin Li a: 0, 828*8c35d5eeSXin Li b: 1, 829*8c35d5eeSXin Li}; 830*8c35d5eeSXin Li 831*8c35d5eeSXin Liconst b = 832*8c35d5eeSXin Li {a: 0, b: 1}; 833*8c35d5eeSXin Li</code></pre> 834*8c35d5eeSXin Li 835*8c35d5eeSXin Li<pre><code class="language-js prettyprint columns">const c = {a: 0, b: 1}; 836*8c35d5eeSXin Li 837*8c35d5eeSXin LisomeMethod(foo, { 838*8c35d5eeSXin Li a: 0, b: 1, 839*8c35d5eeSXin Li}, bar); 840*8c35d5eeSXin Li</code></pre> 841*8c35d5eeSXin Li 842*8c35d5eeSXin Li<h4 id="formatting-class-literals">4.2.3 Class literals</h4> 843*8c35d5eeSXin Li 844*8c35d5eeSXin Li<p>Class literals (whether declarations or expressions) are indented as blocks. Do 845*8c35d5eeSXin Linot add semicolons after methods, or after the closing brace of a class 846*8c35d5eeSXin Li<em>declaration</em> (statements—such as assignments—that contain class <em>expressions</em> 847*8c35d5eeSXin Liare still terminated with a semicolon). Use the <code>extends</code> keyword, but not the 848*8c35d5eeSXin Li<code>@extends</code> JSDoc annotation unless the class extends a templatized type.</p> 849*8c35d5eeSXin Li 850*8c35d5eeSXin Li<p>Example:</p> 851*8c35d5eeSXin Li 852*8c35d5eeSXin Li<pre><code class="language-js prettyprint columns">class Foo { 853*8c35d5eeSXin Li constructor() { 854*8c35d5eeSXin Li /** @type {number} */ 855*8c35d5eeSXin Li this.x = 42; 856*8c35d5eeSXin Li } 857*8c35d5eeSXin Li 858*8c35d5eeSXin Li /** @return {number} */ 859*8c35d5eeSXin Li method() { 860*8c35d5eeSXin Li return this.x; 861*8c35d5eeSXin Li } 862*8c35d5eeSXin Li} 863*8c35d5eeSXin LiFoo.Empty = class {}; 864*8c35d5eeSXin Li</code></pre> 865*8c35d5eeSXin Li 866*8c35d5eeSXin Li<pre><code class="language-js prettyprint columns">/** @extends {Foo<string>} */ 867*8c35d5eeSXin Lifoo.Bar = class extends Foo { 868*8c35d5eeSXin Li /** @override */ 869*8c35d5eeSXin Li method() { 870*8c35d5eeSXin Li return super.method() / 2; 871*8c35d5eeSXin Li } 872*8c35d5eeSXin Li}; 873*8c35d5eeSXin Li 874*8c35d5eeSXin Li/** @interface */ 875*8c35d5eeSXin Liclass Frobnicator { 876*8c35d5eeSXin Li /** @param {string} message */ 877*8c35d5eeSXin Li frobnicate(message) {} 878*8c35d5eeSXin Li} 879*8c35d5eeSXin Li</code></pre> 880*8c35d5eeSXin Li 881*8c35d5eeSXin Li<h4 id="formatting-function-expressions">4.2.4 Function expressions</h4> 882*8c35d5eeSXin Li 883*8c35d5eeSXin Li<p>When declaring an anonymous function in the list of arguments for a function 884*8c35d5eeSXin Licall, the body of the function is indented two spaces more than the preceding 885*8c35d5eeSXin Liindentation depth.</p> 886*8c35d5eeSXin Li 887*8c35d5eeSXin Li<p>Example:</p> 888*8c35d5eeSXin Li 889*8c35d5eeSXin Li<pre><code class="language-js prettyprint">prefix.something.reallyLongFunctionName('whatever', (a1, a2) => { 890*8c35d5eeSXin Li // Indent the function body +2 relative to indentation depth 891*8c35d5eeSXin Li // of the 'prefix' statement one line above. 892*8c35d5eeSXin Li if (a1.equals(a2)) { 893*8c35d5eeSXin Li someOtherLongFunctionName(a1); 894*8c35d5eeSXin Li } else { 895*8c35d5eeSXin Li andNowForSomethingCompletelyDifferent(a2.parrot); 896*8c35d5eeSXin Li } 897*8c35d5eeSXin Li}); 898*8c35d5eeSXin Li 899*8c35d5eeSXin Lisome.reallyLongFunctionCall(arg1, arg2, arg3) 900*8c35d5eeSXin Li .thatsWrapped() 901*8c35d5eeSXin Li .then((result) => { 902*8c35d5eeSXin Li // Indent the function body +2 relative to the indentation depth 903*8c35d5eeSXin Li // of the '.then()' call. 904*8c35d5eeSXin Li if (result) { 905*8c35d5eeSXin Li result.use(); 906*8c35d5eeSXin Li } 907*8c35d5eeSXin Li }); 908*8c35d5eeSXin Li</code></pre> 909*8c35d5eeSXin Li 910*8c35d5eeSXin Li<h4 id="formatting-switch-statements">4.2.5 Switch statements</h4> 911*8c35d5eeSXin Li 912*8c35d5eeSXin Li<p>As with any other block, the contents of a switch block are indented +2.</p> 913*8c35d5eeSXin Li 914*8c35d5eeSXin Li 915*8c35d5eeSXin Li 916*8c35d5eeSXin Li<p>After a switch label, a newline appears, and the indentation level is increased 917*8c35d5eeSXin Li+2, exactly as if a block were being opened. An explicit block may be used if 918*8c35d5eeSXin Lirequired by lexical scoping. The following switch label returns to the previous 919*8c35d5eeSXin Liindentation level, as if a block had been closed.</p> 920*8c35d5eeSXin Li 921*8c35d5eeSXin Li<p>A blank line is optional between a <code>break</code> and the following case.</p> 922*8c35d5eeSXin Li 923*8c35d5eeSXin Li<p>Example:</p> 924*8c35d5eeSXin Li 925*8c35d5eeSXin Li<pre><code class="language-js prettyprint">switch (animal) { 926*8c35d5eeSXin Li case Animal.BANDERSNATCH: 927*8c35d5eeSXin Li handleBandersnatch(); 928*8c35d5eeSXin Li break; 929*8c35d5eeSXin Li 930*8c35d5eeSXin Li case Animal.JABBERWOCK: 931*8c35d5eeSXin Li handleJabberwock(); 932*8c35d5eeSXin Li break; 933*8c35d5eeSXin Li 934*8c35d5eeSXin Li default: 935*8c35d5eeSXin Li throw new Error('Unknown animal'); 936*8c35d5eeSXin Li} 937*8c35d5eeSXin Li</code></pre> 938*8c35d5eeSXin Li 939*8c35d5eeSXin Li<h3 id="formatting-statements">4.3 Statements</h3> 940*8c35d5eeSXin Li 941*8c35d5eeSXin Li<h4 id="formatting-one-statement-perline">4.3.1 One statement per line</h4> 942*8c35d5eeSXin Li 943*8c35d5eeSXin Li<p>Each statement is followed by a line-break.</p> 944*8c35d5eeSXin Li 945*8c35d5eeSXin Li<h4 id="formatting-semicolons-are-required">4.3.2 Semicolons are required</h4> 946*8c35d5eeSXin Li 947*8c35d5eeSXin Li<p>Every statement must be terminated with a semicolon. Relying on automatic 948*8c35d5eeSXin Lisemicolon insertion is forbidden.</p> 949*8c35d5eeSXin Li 950*8c35d5eeSXin Li<h3 id="formatting-column-limit">4.4 Column limit: 80</h3> 951*8c35d5eeSXin Li 952*8c35d5eeSXin Li<p>JavaScript code has a column limit of 80 characters. Except as noted below, any 953*8c35d5eeSXin Liline that would exceed this limit must be line-wrapped, as explained in 954*8c35d5eeSXin Li<a href="#formatting-line-wrapping">??</a>.</p> 955*8c35d5eeSXin Li 956*8c35d5eeSXin Li<p><strong>Exceptions:</strong></p> 957*8c35d5eeSXin Li 958*8c35d5eeSXin Li<ol> 959*8c35d5eeSXin Li<li><code>goog.module</code>, <code>goog.require</code> and <code>goog.requireType</code> statements (see 960*8c35d5eeSXin Li<a href="#file-goog-module">??</a> and <a href="#file-goog-require">??</a>).</li> 961*8c35d5eeSXin Li<li>ES module <code>import</code> and <code>export from</code> statements (see 962*8c35d5eeSXin Li<a href="#es-module-imports">??</a> and <a href="#es-module-export-from">??</a>).</li> 963*8c35d5eeSXin Li<li>Lines where obeying the column limit is not possible or would hinder 964*8c35d5eeSXin Lidiscoverability. Examples include: 965*8c35d5eeSXin Li<ul> 966*8c35d5eeSXin Li<li>A long URL which should be clickable in source.</li> 967*8c35d5eeSXin Li<li>A shell command intended to be copied-and-pasted.</li> 968*8c35d5eeSXin Li<li>A long string literal which may need to be copied or searched for wholly 969*8c35d5eeSXin Li(e.g., a long file path).</li> 970*8c35d5eeSXin Li</ul></li> 971*8c35d5eeSXin Li</ol> 972*8c35d5eeSXin Li 973*8c35d5eeSXin Li<h3 id="formatting-line-wrapping">4.5 Line-wrapping</h3> 974*8c35d5eeSXin Li 975*8c35d5eeSXin Li<p><strong>Terminology Note</strong>: <em>Line wrapping</em> is breaking a chunk of code into multiple 976*8c35d5eeSXin Lilines to obey column limit, where the chunk could otherwise legally fit in a 977*8c35d5eeSXin Lisingle line.</p> 978*8c35d5eeSXin Li 979*8c35d5eeSXin Li<p>There is no comprehensive, deterministic formula showing <em>exactly</em> how to 980*8c35d5eeSXin Liline-wrap in every situation. Very often there are several valid ways to 981*8c35d5eeSXin Liline-wrap the same piece of code.</p> 982*8c35d5eeSXin Li 983*8c35d5eeSXin Li<p>Note: While the typical reason for line-wrapping is to avoid overflowing the 984*8c35d5eeSXin Licolumn limit, even code that would in fact fit within the column limit may be 985*8c35d5eeSXin Liline-wrapped at the author's discretion.</p> 986*8c35d5eeSXin Li 987*8c35d5eeSXin Li<p>Tip: Extracting a method or local variable may solve the problem without the 988*8c35d5eeSXin Lineed to line-wrap.</p> 989*8c35d5eeSXin Li 990*8c35d5eeSXin Li<h4 id="formatting-where-to-break">4.5.1 Where to break</h4> 991*8c35d5eeSXin Li 992*8c35d5eeSXin Li<p>The prime directive of line-wrapping is: prefer to break at a <strong>higher syntactic 993*8c35d5eeSXin Lilevel</strong>. </p> 994*8c35d5eeSXin Li 995*8c35d5eeSXin Li<p>Preferred:</p> 996*8c35d5eeSXin Li 997*8c35d5eeSXin Li<pre><code class="language-js prettyprint">currentEstimate = 998*8c35d5eeSXin Li calc(currentEstimate + x * currentEstimate) / 999*8c35d5eeSXin Li 2.0; 1000*8c35d5eeSXin Li</code></pre> 1001*8c35d5eeSXin Li 1002*8c35d5eeSXin Li<p>Discouraged:</p> 1003*8c35d5eeSXin Li 1004*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">currentEstimate = calc(currentEstimate + x * 1005*8c35d5eeSXin Li currentEstimate) / 2.0; 1006*8c35d5eeSXin Li</code></pre> 1007*8c35d5eeSXin Li 1008*8c35d5eeSXin Li<p>In the preceding example, the syntactic levels from highest to lowest are as 1009*8c35d5eeSXin Lifollows: assignment, division, function call, parameters, number constant.</p> 1010*8c35d5eeSXin Li 1011*8c35d5eeSXin Li<p>Operators are wrapped as follows:</p> 1012*8c35d5eeSXin Li 1013*8c35d5eeSXin Li<ol> 1014*8c35d5eeSXin Li<li>When a line is broken at an operator the break comes after the symbol. (Note 1015*8c35d5eeSXin Lithat this is not the same practice used in Google style for Java.) 1016*8c35d5eeSXin Li<ol> 1017*8c35d5eeSXin Li<li>This does not apply to the <q>dot</q> (<code>.</code>), which is not actually an 1018*8c35d5eeSXin Lioperator.</li> 1019*8c35d5eeSXin Li</ol></li> 1020*8c35d5eeSXin Li<li>A method or constructor name stays attached to the open parenthesis (<code>(</code>) 1021*8c35d5eeSXin Lithat follows it.</li> 1022*8c35d5eeSXin Li<li>A comma (<code>,</code>) stays attached to the token that precedes it.</li> 1023*8c35d5eeSXin Li</ol> 1024*8c35d5eeSXin Li 1025*8c35d5eeSXin Li<blockquote> 1026*8c35d5eeSXin Li<p>Note: The primary goal for line wrapping is to have clear code, not 1027*8c35d5eeSXin Linecessarily code that fits in the smallest number of lines.</p> 1028*8c35d5eeSXin Li</blockquote> 1029*8c35d5eeSXin Li 1030*8c35d5eeSXin Li<h4 id="formatting-indent">4.5.2 Indent continuation lines at least +4 spaces</h4> 1031*8c35d5eeSXin Li 1032*8c35d5eeSXin Li<p>When line-wrapping, each line after the first (each <em>continuation line</em>) is 1033*8c35d5eeSXin Liindented at least +4 from the original line, unless it falls under the rules of 1034*8c35d5eeSXin Liblock indentation.</p> 1035*8c35d5eeSXin Li 1036*8c35d5eeSXin Li<p>When there are multiple continuation lines, indentation may be varied beyond +4 1037*8c35d5eeSXin Lias appropriate. In general, continuation lines at a deeper syntactic level are 1038*8c35d5eeSXin Liindented by larger multiples of 4, and two lines use the same indentation level 1039*8c35d5eeSXin Liif and only if they begin with syntactically parallel elements.</p> 1040*8c35d5eeSXin Li 1041*8c35d5eeSXin Li<p><a href="#formatting-horizontal-alignment">??</a> addresses the discouraged practice of 1042*8c35d5eeSXin Liusing a variable number of spaces to align certain tokens with previous lines.</p> 1043*8c35d5eeSXin Li 1044*8c35d5eeSXin Li<h3 id="formatting-whitespace">4.6 Whitespace</h3> 1045*8c35d5eeSXin Li 1046*8c35d5eeSXin Li<h4 id="formatting-vertical-whitespace">4.6.1 Vertical whitespace</h4> 1047*8c35d5eeSXin Li 1048*8c35d5eeSXin Li<p>A single blank line appears:</p> 1049*8c35d5eeSXin Li 1050*8c35d5eeSXin Li<ol> 1051*8c35d5eeSXin Li<li>Between consecutive methods in a class or object literal 1052*8c35d5eeSXin Li<ol> 1053*8c35d5eeSXin Li<li>Exception: A blank line between two consecutive properties definitions in 1054*8c35d5eeSXin Lian object literal (with no other code between them) is optional. Such 1055*8c35d5eeSXin Liblank lines are used as needed to create <em>logical groupings</em> of fields.</li> 1056*8c35d5eeSXin Li</ol></li> 1057*8c35d5eeSXin Li<li>Within method bodies, sparingly to create <em>logical groupings</em> of statements. 1058*8c35d5eeSXin LiBlank lines at the start or end of a function body are not allowed.</li> 1059*8c35d5eeSXin Li<li><em>Optionally</em> before the first or after the last method in a class or object 1060*8c35d5eeSXin Liliteral (neither encouraged nor discouraged).</li> 1061*8c35d5eeSXin Li<li>As required by other sections of this document (e.g. 1062*8c35d5eeSXin Li<a href="#file-goog-require">??</a>).</li> 1063*8c35d5eeSXin Li</ol> 1064*8c35d5eeSXin Li 1065*8c35d5eeSXin Li<p><em>Multiple</em> consecutive blank lines are permitted, but never required (nor 1066*8c35d5eeSXin Liencouraged).</p> 1067*8c35d5eeSXin Li 1068*8c35d5eeSXin Li<h4 id="formatting-horizontal-whitespace">4.6.2 Horizontal whitespace</h4> 1069*8c35d5eeSXin Li 1070*8c35d5eeSXin Li<p>Use of horizontal whitespace depends on location, and falls into three broad 1071*8c35d5eeSXin Licategories: <em>leading</em> (at the start of a line), <em>trailing</em> (at the end of a 1072*8c35d5eeSXin Liline), and <em>internal</em>. Leading whitespace (i.e., indentation) is addressed 1073*8c35d5eeSXin Lielsewhere. Trailing whitespace is forbidden.</p> 1074*8c35d5eeSXin Li 1075*8c35d5eeSXin Li<p>Beyond where required by the language or other style rules, and apart from 1076*8c35d5eeSXin Liliterals, comments, and JSDoc, a single internal ASCII space also appears in the 1077*8c35d5eeSXin Lifollowing places <strong>only</strong>.</p> 1078*8c35d5eeSXin Li 1079*8c35d5eeSXin Li<ol> 1080*8c35d5eeSXin Li<li>Separating any reserved word (such as <code>if</code>, <code>for</code>, or <code>catch</code>) except for 1081*8c35d5eeSXin Li<code>function</code> and <code>super</code>, from an open parenthesis (<code>(</code>) that follows it on 1082*8c35d5eeSXin Lithat line.</li> 1083*8c35d5eeSXin Li<li>Separating any reserved word (such as <code>else</code> or <code>catch</code>) from a closing 1084*8c35d5eeSXin Licurly brace (<code>}</code>) that precedes it on that line.</li> 1085*8c35d5eeSXin Li<li>Before any open curly brace (<code>{</code>), with two exceptions: 1086*8c35d5eeSXin Li<ol> 1087*8c35d5eeSXin Li<li>Before an object literal that is the first argument of a function or the 1088*8c35d5eeSXin Lifirst element in an array literal (e.g. <code>foo({a: [{c: d}]})</code>).</li> 1089*8c35d5eeSXin Li<li>In a template expansion, as it is forbidden by the language (e.g. valid: 1090*8c35d5eeSXin Li<code>`ab${1 + 2}cd`</code>, invalid: <code class="badcode">`xy$ {3}z`</code>).</li> 1091*8c35d5eeSXin Li</ol></li> 1092*8c35d5eeSXin Li<li>On both sides of any binary or ternary operator.</li> 1093*8c35d5eeSXin Li<li>After a comma (<code>,</code>) or semicolon (<code>;</code>). Note that spaces are <em>never</em> allowed 1094*8c35d5eeSXin Libefore these characters.</li> 1095*8c35d5eeSXin Li<li>After the colon (<code>:</code>) in an object literal.</li> 1096*8c35d5eeSXin Li<li>On both sides of the double slash (<code>//</code>) that begins an end-of-line comment. 1097*8c35d5eeSXin LiHere, multiple spaces are allowed, but not required.</li> 1098*8c35d5eeSXin Li<li>After an open-block comment character and on both sides of close characters 1099*8c35d5eeSXin Li(e.g. for short-form type declarations, casts, and parameter name comments: 1100*8c35d5eeSXin Li<code>this.foo = /** @type {number} */ (bar)</code>; or <code>function(/** string */ foo) 1101*8c35d5eeSXin Li{</code>; or <code>baz(/* buzz= */ true)</code>).</li> 1102*8c35d5eeSXin Li</ol> 1103*8c35d5eeSXin Li 1104*8c35d5eeSXin Li<h4 id="formatting-horizontal-alignment">4.6.3 Horizontal alignment: discouraged</h4> 1105*8c35d5eeSXin Li 1106*8c35d5eeSXin Li<p><strong>Terminology Note</strong>: <em>Horizontal alignment</em> is the practice of adding a 1107*8c35d5eeSXin Livariable number of additional spaces in your code with the goal of making 1108*8c35d5eeSXin Licertain tokens appear directly below certain other tokens on previous lines.</p> 1109*8c35d5eeSXin Li 1110*8c35d5eeSXin Li<p>This practice is permitted, but it is <strong>generally discouraged</strong> by Google 1111*8c35d5eeSXin LiStyle. It is not even required to <em>maintain</em> horizontal alignment in places 1112*8c35d5eeSXin Liwhere it was already used.</p> 1113*8c35d5eeSXin Li 1114*8c35d5eeSXin Li<p>Here is an example without alignment, followed by one with alignment. Both are 1115*8c35d5eeSXin Liallowed, but the latter is discouraged:</p> 1116*8c35d5eeSXin Li 1117*8c35d5eeSXin Li<pre><code class="language-js prettyprint">{ 1118*8c35d5eeSXin Li tiny: 42, // this is great 1119*8c35d5eeSXin Li longer: 435, // this too 1120*8c35d5eeSXin Li}; 1121*8c35d5eeSXin Li 1122*8c35d5eeSXin Li{ 1123*8c35d5eeSXin Li tiny: 42, // permitted, but future edits 1124*8c35d5eeSXin Li longer: 435, // may leave it unaligned 1125*8c35d5eeSXin Li}; 1126*8c35d5eeSXin Li</code></pre> 1127*8c35d5eeSXin Li 1128*8c35d5eeSXin Li<p>Tip: Alignment can aid readability, but it creates problems for future 1129*8c35d5eeSXin Limaintenance. Consider a future change that needs to touch just one line. This 1130*8c35d5eeSXin Lichange may leave the formerly-pleasing formatting mangled, and that is 1131*8c35d5eeSXin Liallowed. More often it prompts the coder (perhaps you) to adjust whitespace on 1132*8c35d5eeSXin Linearby lines as well, possibly triggering a cascading series of 1133*8c35d5eeSXin Lireformattings. That one-line change now has a <q>blast radius.</q> This can at worst 1134*8c35d5eeSXin Liresult in pointless busywork, but at best it still corrupts version history 1135*8c35d5eeSXin Liinformation, slows down reviewers and exacerbates merge conflicts.</p> 1136*8c35d5eeSXin Li 1137*8c35d5eeSXin Li<h4 id="formatting-function-arguments">4.6.4 Function arguments</h4> 1138*8c35d5eeSXin Li 1139*8c35d5eeSXin Li<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> 1140*8c35d5eeSXin Li 1141*8c35d5eeSXin Li<pre><code class="language-js prettyprint">// Arguments start on a new line, indented four spaces. Preferred when the 1142*8c35d5eeSXin Li// arguments don't fit on the same line with the function name (or the keyword 1143*8c35d5eeSXin Li// "function") but fit entirely on the second line. Works with very long 1144*8c35d5eeSXin Li// function names, survives renaming without reindenting, low on space. 1145*8c35d5eeSXin LidoSomething( 1146*8c35d5eeSXin Li descriptiveArgumentOne, descriptiveArgumentTwo, descriptiveArgumentThree) { 1147*8c35d5eeSXin Li // … 1148*8c35d5eeSXin Li} 1149*8c35d5eeSXin Li 1150*8c35d5eeSXin Li// If the argument list is longer, wrap at 80. Uses less vertical space, 1151*8c35d5eeSXin Li// but violates the rectangle rule and is thus not recommended. 1152*8c35d5eeSXin LidoSomething(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, 1153*8c35d5eeSXin Li tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) { 1154*8c35d5eeSXin Li // … 1155*8c35d5eeSXin Li} 1156*8c35d5eeSXin Li 1157*8c35d5eeSXin Li// Four-space, one argument per line. Works with long function names, 1158*8c35d5eeSXin Li// survives renaming, and emphasizes each argument. 1159*8c35d5eeSXin LidoSomething( 1160*8c35d5eeSXin Li veryDescriptiveArgumentNumberOne, 1161*8c35d5eeSXin Li veryDescriptiveArgumentTwo, 1162*8c35d5eeSXin Li tableModelEventHandlerProxy, 1163*8c35d5eeSXin Li artichokeDescriptorAdapterIterator) { 1164*8c35d5eeSXin Li // … 1165*8c35d5eeSXin Li} 1166*8c35d5eeSXin Li</code></pre> 1167*8c35d5eeSXin Li 1168*8c35d5eeSXin Li<h3 id="formatting-grouping-parentheses">4.7 Grouping parentheses: recommended</h3> 1169*8c35d5eeSXin Li 1170*8c35d5eeSXin Li<p>Optional grouping parentheses are omitted only when the author and reviewer 1171*8c35d5eeSXin Liagree that there is no reasonable chance that the code will be misinterpreted 1172*8c35d5eeSXin Liwithout them, nor would they have made the code easier to read. It is <em>not</em> 1173*8c35d5eeSXin Lireasonable to assume that every reader has the entire operator precedence table 1174*8c35d5eeSXin Limemorized.</p> 1175*8c35d5eeSXin Li 1176*8c35d5eeSXin Li<p>Do not use unnecessary parentheses around the entire expression following 1177*8c35d5eeSXin Li<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> 1178*8c35d5eeSXin Li 1179*8c35d5eeSXin Li<p>Parentheses are required for type casts: <code>/** @type {!Foo} */ (foo)</code>.</p> 1180*8c35d5eeSXin Li 1181*8c35d5eeSXin Li<h3 id="formatting-comments">4.8 Comments</h3> 1182*8c35d5eeSXin Li 1183*8c35d5eeSXin Li<p>This section addresses <em>implementation comments</em>. JSDoc is addressed separately 1184*8c35d5eeSXin Liin <a href="#jsdoc">??</a>.</p> 1185*8c35d5eeSXin Li 1186*8c35d5eeSXin Li<h4 id="formatting-block-comment-style">4.8.1 Block comment style</h4> 1187*8c35d5eeSXin Li 1188*8c35d5eeSXin Li<p>Block comments are indented at the same level as the surrounding code. They may 1189*8c35d5eeSXin Libe in <code>/* … */</code> or <code>//</code>-style. For multi-line <code>/* … */</code> comments, subsequent 1190*8c35d5eeSXin Lilines must start with * aligned with the <code>*</code> on the previous line, to make 1191*8c35d5eeSXin Licomments obvious with no extra context.</p> 1192*8c35d5eeSXin Li 1193*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/* 1194*8c35d5eeSXin Li * This is 1195*8c35d5eeSXin Li * okay. 1196*8c35d5eeSXin Li */ 1197*8c35d5eeSXin Li 1198*8c35d5eeSXin Li// And so 1199*8c35d5eeSXin Li// is this. 1200*8c35d5eeSXin Li 1201*8c35d5eeSXin Li/* This is fine, too. */ 1202*8c35d5eeSXin Li</code></pre> 1203*8c35d5eeSXin Li 1204*8c35d5eeSXin Li<p>Comments are not enclosed in boxes drawn with asterisks or other characters.</p> 1205*8c35d5eeSXin Li 1206*8c35d5eeSXin Li<p>Do not use JSDoc (<code>/** … */</code>) for implementation comments.</p> 1207*8c35d5eeSXin Li 1208*8c35d5eeSXin Li<h4 id="formatting-param-name-comments">4.8.2 Parameter Name Comments</h4> 1209*8c35d5eeSXin Li 1210*8c35d5eeSXin Li<p>“Parameter name” comments should be used whenever the value and method name do 1211*8c35d5eeSXin Linot sufficiently convey the meaning, and refactoring the method to be clearer is 1212*8c35d5eeSXin Liinfeasible . 1213*8c35d5eeSXin LiTheir preferred format is before the value with <q>=</q>:</p> 1214*8c35d5eeSXin Li 1215*8c35d5eeSXin Li<pre><code class="language-js prettyprint">someFunction(obviousParam, /* shouldRender= */ true, /* name= */ 'hello'); 1216*8c35d5eeSXin Li</code></pre> 1217*8c35d5eeSXin Li 1218*8c35d5eeSXin Li<p>For consistency with surrounding code you may put them after the value without 1219*8c35d5eeSXin Li<q>=</q>:</p> 1220*8c35d5eeSXin Li 1221*8c35d5eeSXin Li<pre><code class="language-js prettyprint">someFunction(obviousParam, true /* shouldRender */, 'hello' /* name */); 1222*8c35d5eeSXin Li</code></pre> 1223*8c35d5eeSXin Li 1224*8c35d5eeSXin Li<h2 id="language-features">5 Language features</h2> 1225*8c35d5eeSXin Li 1226*8c35d5eeSXin Li<p>JavaScript includes many dubious (and even dangerous) features. This section 1227*8c35d5eeSXin Lidelineates which features may or may not be used, and any additional constraints 1228*8c35d5eeSXin Lion their use.</p> 1229*8c35d5eeSXin Li 1230*8c35d5eeSXin Li<h3 id="features-local-variable-declarations">5.1 Local variable declarations</h3> 1231*8c35d5eeSXin Li 1232*8c35d5eeSXin Li<h4 id="features-use-const-and-let">5.1.1 Use <code>const</code> and <code>let</code></h4> 1233*8c35d5eeSXin Li 1234*8c35d5eeSXin Li<p>Declare all local variables with either <code>const</code> or <code>let</code>. Use const by default, 1235*8c35d5eeSXin Liunless a variable needs to be reassigned. The <code class="badcode">var</code> 1236*8c35d5eeSXin Likeyword must not be used.</p> 1237*8c35d5eeSXin Li 1238*8c35d5eeSXin Li<h4 id="features-one-variable-per-declaration">5.1.2 One variable per declaration</h4> 1239*8c35d5eeSXin Li 1240*8c35d5eeSXin Li<p>Every local variable declaration declares only one variable: declarations such 1241*8c35d5eeSXin Lias <code class="badcode">let a = 1, b = 2;</code> are not used.</p> 1242*8c35d5eeSXin Li 1243*8c35d5eeSXin Li<h4 id="features-declared-when-needed">5.1.3 Declared when needed, initialized as soon as possible</h4> 1244*8c35d5eeSXin Li 1245*8c35d5eeSXin Li<p>Local variables are <strong>not</strong> habitually declared at the start of their containing 1246*8c35d5eeSXin Liblock or block-like construct. Instead, local variables are declared close to 1247*8c35d5eeSXin Lithe point they are first used (within reason), to minimize their scope.</p> 1248*8c35d5eeSXin Li 1249*8c35d5eeSXin Li<h4 id="features-declare-types-as-needed">5.1.4 Declare types as needed</h4> 1250*8c35d5eeSXin Li 1251*8c35d5eeSXin Li<p>JSDoc type annotations may be added either on the line above the declaration, or 1252*8c35d5eeSXin Lielse inline before the variable name if no other JSDoc is present.</p> 1253*8c35d5eeSXin Li 1254*8c35d5eeSXin Li<p>Example:</p> 1255*8c35d5eeSXin Li 1256*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const /** !Array<number> */ data = []; 1257*8c35d5eeSXin Li 1258*8c35d5eeSXin Li/** 1259*8c35d5eeSXin Li * Some description. 1260*8c35d5eeSXin Li * @type {!Array<number>} 1261*8c35d5eeSXin Li */ 1262*8c35d5eeSXin Liconst data = []; 1263*8c35d5eeSXin Li</code></pre> 1264*8c35d5eeSXin Li 1265*8c35d5eeSXin Li<p>Mixing inline and JSDoc styles is not allowed: the compiler will only process 1266*8c35d5eeSXin Lithe first JsDoc and the inline annotations will be lost.</p> 1267*8c35d5eeSXin Li 1268*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">/** Some description. */ 1269*8c35d5eeSXin Liconst /** !Array<number> */ data = []; 1270*8c35d5eeSXin Li</code></pre> 1271*8c35d5eeSXin Li 1272*8c35d5eeSXin Li<p>Tip: There are many cases where the compiler can infer a templatized type but 1273*8c35d5eeSXin Linot its parameters. This is particularly the case when the initializing literal 1274*8c35d5eeSXin Lior constructor call does not include any values of the template parameter type 1275*8c35d5eeSXin Li(e.g., empty arrays, objects, <code>Map</code>s, or <code>Set</code>s), or if the variable is modified 1276*8c35d5eeSXin Liin a closure. Local variable type annotations are particularly helpful in these 1277*8c35d5eeSXin Licases since otherwise the compiler will infer the template parameter as unknown.</p> 1278*8c35d5eeSXin Li 1279*8c35d5eeSXin Li<h3 id="features-array-literals">5.2 Array literals</h3> 1280*8c35d5eeSXin Li 1281*8c35d5eeSXin Li<h4 id="features-arrays-trailing-comma">5.2.1 Use trailing commas</h4> 1282*8c35d5eeSXin Li 1283*8c35d5eeSXin Li 1284*8c35d5eeSXin Li 1285*8c35d5eeSXin Li<p>Include a trailing comma whenever there is a line break between the final 1286*8c35d5eeSXin Lielement and the closing bracket.</p> 1287*8c35d5eeSXin Li 1288*8c35d5eeSXin Li<p>Example:</p> 1289*8c35d5eeSXin Li 1290*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const values = [ 1291*8c35d5eeSXin Li 'first value', 1292*8c35d5eeSXin Li 'second value', 1293*8c35d5eeSXin Li]; 1294*8c35d5eeSXin Li</code></pre> 1295*8c35d5eeSXin Li 1296*8c35d5eeSXin Li<h4 id="features-arrays-ctor">5.2.2 Do not use the variadic <code>Array</code> constructor</h4> 1297*8c35d5eeSXin Li 1298*8c35d5eeSXin Li<p>The constructor is error-prone if arguments are added or removed. Use a literal 1299*8c35d5eeSXin Liinstead.</p> 1300*8c35d5eeSXin Li 1301*8c35d5eeSXin Li<p>Disallowed:</p> 1302*8c35d5eeSXin Li 1303*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">const a1 = new Array(x1, x2, x3); 1304*8c35d5eeSXin Liconst a2 = new Array(x1, x2); 1305*8c35d5eeSXin Liconst a3 = new Array(x1); 1306*8c35d5eeSXin Liconst a4 = new Array(); 1307*8c35d5eeSXin Li</code></pre> 1308*8c35d5eeSXin Li 1309*8c35d5eeSXin Li<p>This works as expected except for the third case: if <code>x1</code> is a whole number then 1310*8c35d5eeSXin Li<code>a3</code> is an array of size <code>x1</code> where all elements are <code>undefined</code>. If <code>x1</code> is any 1311*8c35d5eeSXin Liother number, then an exception will be thrown, and if it is anything else then 1312*8c35d5eeSXin Liit will be a single-element array.</p> 1313*8c35d5eeSXin Li 1314*8c35d5eeSXin Li<p>Instead, write</p> 1315*8c35d5eeSXin Li 1316*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const a1 = [x1, x2, x3]; 1317*8c35d5eeSXin Liconst a2 = [x1, x2]; 1318*8c35d5eeSXin Liconst a3 = [x1]; 1319*8c35d5eeSXin Liconst a4 = []; 1320*8c35d5eeSXin Li</code></pre> 1321*8c35d5eeSXin Li 1322*8c35d5eeSXin Li<p>Explicitly allocating an array of a given length using <code>new Array(length)</code> is 1323*8c35d5eeSXin Liallowed when appropriate.</p> 1324*8c35d5eeSXin Li 1325*8c35d5eeSXin Li<h4 id="features-arrays-non-numeric-properties">5.2.3 Non-numeric properties</h4> 1326*8c35d5eeSXin Li 1327*8c35d5eeSXin Li<p>Do not define or use non-numeric properties on an array (other than 1328*8c35d5eeSXin Li<code>length</code>). Use a <code>Map</code> (or <code>Object</code>) instead.</p> 1329*8c35d5eeSXin Li 1330*8c35d5eeSXin Li<h4 id="features-arrays-destructuring">5.2.4 Destructuring</h4> 1331*8c35d5eeSXin Li 1332*8c35d5eeSXin Li<p>Array literals may be used on the left-hand side of an assignment to perform 1333*8c35d5eeSXin Lidestructuring (such as when unpacking multiple values from a single array or 1334*8c35d5eeSXin Liiterable). A final <q>rest</q> element may be included (with no space between the 1335*8c35d5eeSXin Li<code>...</code> and the variable name). Elements should be omitted if they are unused.</p> 1336*8c35d5eeSXin Li 1337*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const [a, b, c, ...rest] = generateResults(); 1338*8c35d5eeSXin Lilet [, b,, d] = someArray; 1339*8c35d5eeSXin Li</code></pre> 1340*8c35d5eeSXin Li 1341*8c35d5eeSXin Li<p>Destructuring may also be used for function parameters (note that a parameter 1342*8c35d5eeSXin Liname is required but ignored). Always specify <code>[]</code> as the default value if a 1343*8c35d5eeSXin Lidestructured array parameter is optional, and provide default values on the left 1344*8c35d5eeSXin Lihand side:</p> 1345*8c35d5eeSXin Li 1346*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @param {!Array<number>=} param1 */ 1347*8c35d5eeSXin Lifunction optionalDestructuring([a = 4, b = 2] = []) { … }; 1348*8c35d5eeSXin Li</code></pre> 1349*8c35d5eeSXin Li 1350*8c35d5eeSXin Li<p>Disallowed:</p> 1351*8c35d5eeSXin Li 1352*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">function badDestructuring([a, b] = [4, 2]) { … }; 1353*8c35d5eeSXin Li</code></pre> 1354*8c35d5eeSXin Li 1355*8c35d5eeSXin Li<p>Tip: For (un)packing multiple values into a function’s parameter or return, 1356*8c35d5eeSXin Liprefer object destructuring to array destructuring when possible, as it allows 1357*8c35d5eeSXin Linaming the individual elements and specifying a different type for each.</p> 1358*8c35d5eeSXin Li 1359*8c35d5eeSXin Li<h4 id="features-arrays-spread-operator">5.2.5 Spread operator</h4> 1360*8c35d5eeSXin Li 1361*8c35d5eeSXin Li<p>Array literals may include the spread operator (<code>...</code>) to flatten elements out 1362*8c35d5eeSXin Liof one or more other iterables. The spread operator should be used instead of 1363*8c35d5eeSXin Limore awkward constructs with <code>Array.prototype</code>. There is no space after the 1364*8c35d5eeSXin Li<code>...</code>.</p> 1365*8c35d5eeSXin Li 1366*8c35d5eeSXin Li<p>Example:</p> 1367*8c35d5eeSXin Li 1368*8c35d5eeSXin Li<pre><code class="language-js prettyprint">[...foo] // preferred over Array.prototype.slice.call(foo) 1369*8c35d5eeSXin Li[...foo, ...bar] // preferred over foo.concat(bar) 1370*8c35d5eeSXin Li</code></pre> 1371*8c35d5eeSXin Li 1372*8c35d5eeSXin Li<h3 id="features-object-literals">5.3 Object literals</h3> 1373*8c35d5eeSXin Li 1374*8c35d5eeSXin Li<h4 id="features-objects-use-trailing-comma">5.3.1 Use trailing commas</h4> 1375*8c35d5eeSXin Li 1376*8c35d5eeSXin Li<p>Include a trailing comma whenever there is a line break between the final 1377*8c35d5eeSXin Liproperty and the closing brace.</p> 1378*8c35d5eeSXin Li 1379*8c35d5eeSXin Li<h4 id="features-objects-ctor">5.3.2 Do not use the <code>Object</code> constructor</h4> 1380*8c35d5eeSXin Li 1381*8c35d5eeSXin Li<p>While <code>Object</code> does not have the same problems as <code>Array</code>, it is still 1382*8c35d5eeSXin Lidisallowed for consistency. Use an object literal (<code>{}</code> or <code>{a: 0, b: 1, c: 2}</code>) 1383*8c35d5eeSXin Liinstead.</p> 1384*8c35d5eeSXin Li 1385*8c35d5eeSXin Li<h4 id="features-objects-mixing-keys">5.3.3 Do not mix quoted and unquoted keys</h4> 1386*8c35d5eeSXin Li 1387*8c35d5eeSXin Li<p>Object literals may represent either <em>structs</em> (with unquoted keys and/or 1388*8c35d5eeSXin Lisymbols) or <em>dicts</em> (with quoted and/or computed keys). Do not mix these key 1389*8c35d5eeSXin Litypes in a single object literal.</p> 1390*8c35d5eeSXin Li 1391*8c35d5eeSXin Li<p>Disallowed:</p> 1392*8c35d5eeSXin Li 1393*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">{ 1394*8c35d5eeSXin Li width: 42, // struct-style unquoted key 1395*8c35d5eeSXin Li 'maxWidth': 43, // dict-style quoted key 1396*8c35d5eeSXin Li} 1397*8c35d5eeSXin Li</code></pre> 1398*8c35d5eeSXin Li 1399*8c35d5eeSXin Li<p>This also extends to passing the property name to functions, like 1400*8c35d5eeSXin Li<code>hasOwnProperty</code>. In particular, doing so will break in compiled code because 1401*8c35d5eeSXin Lithe compiler cannot rename/obfuscate the string literal.</p> 1402*8c35d5eeSXin Li 1403*8c35d5eeSXin Li<p>Disallowed:</p> 1404*8c35d5eeSXin Li 1405*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">/** @type {{width: number, maxWidth: (number|undefined)}} */ 1406*8c35d5eeSXin Liconst o = {width: 42}; 1407*8c35d5eeSXin Liif (o.hasOwnProperty('maxWidth')) { 1408*8c35d5eeSXin Li ... 1409*8c35d5eeSXin Li} 1410*8c35d5eeSXin Li</code></pre> 1411*8c35d5eeSXin Li 1412*8c35d5eeSXin Li<p>This is best implemented as:</p> 1413*8c35d5eeSXin Li 1414*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @type {{width: number, maxWidth: (number|undefined)}} */ 1415*8c35d5eeSXin Liconst o = {width: 42}; 1416*8c35d5eeSXin Liif (o.maxWidth != null) { 1417*8c35d5eeSXin Li ... 1418*8c35d5eeSXin Li} 1419*8c35d5eeSXin Li</code></pre> 1420*8c35d5eeSXin Li 1421*8c35d5eeSXin Li<h4 id="features-objects-computed-property-names">5.3.4 Computed property names</h4> 1422*8c35d5eeSXin Li 1423*8c35d5eeSXin Li<p>Computed property names (e.g., <code>{['key' + foo()]: 42}</code>) are allowed, and are 1424*8c35d5eeSXin Liconsidered dict-style (quoted) keys (i.e., must not be mixed with non-quoted 1425*8c35d5eeSXin Likeys) unless the computed property is a 1426*8c35d5eeSXin Li<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol">symbol</a> 1427*8c35d5eeSXin Li(e.g., <code>[Symbol.iterator]</code>). Enum values may also be used for computed keys, but 1428*8c35d5eeSXin Lishould not be mixed with non-enum keys in the same literal.</p> 1429*8c35d5eeSXin Li 1430*8c35d5eeSXin Li<h4 id="features-objects-method-shorthand">5.3.5 Method shorthand</h4> 1431*8c35d5eeSXin Li 1432*8c35d5eeSXin Li<p>Methods can be defined on object literals using the method shorthand (<code>{method() 1433*8c35d5eeSXin Li{… }}</code>) in place of a colon immediately followed by a <code>function</code> or arrow 1434*8c35d5eeSXin Lifunction literal.</p> 1435*8c35d5eeSXin Li 1436*8c35d5eeSXin Li<p>Example:</p> 1437*8c35d5eeSXin Li 1438*8c35d5eeSXin Li<pre><code class="language-js prettyprint">return { 1439*8c35d5eeSXin Li stuff: 'candy', 1440*8c35d5eeSXin Li method() { 1441*8c35d5eeSXin Li return this.stuff; // Returns 'candy' 1442*8c35d5eeSXin Li }, 1443*8c35d5eeSXin Li}; 1444*8c35d5eeSXin Li</code></pre> 1445*8c35d5eeSXin Li 1446*8c35d5eeSXin Li<p>Note that <code>this</code> in a method shorthand or <code>function</code> refers to the object 1447*8c35d5eeSXin Liliteral itself whereas <code>this</code> in an arrow function refers to the scope outside 1448*8c35d5eeSXin Lithe object literal.</p> 1449*8c35d5eeSXin Li 1450*8c35d5eeSXin Li<p>Example:</p> 1451*8c35d5eeSXin Li 1452*8c35d5eeSXin Li<pre><code class="language-js prettyprint">class { 1453*8c35d5eeSXin Li getObjectLiteral() { 1454*8c35d5eeSXin Li this.stuff = 'fruit'; 1455*8c35d5eeSXin Li return { 1456*8c35d5eeSXin Li stuff: 'candy', 1457*8c35d5eeSXin Li method: () => this.stuff, // Returns 'fruit' 1458*8c35d5eeSXin Li }; 1459*8c35d5eeSXin Li } 1460*8c35d5eeSXin Li} 1461*8c35d5eeSXin Li</code></pre> 1462*8c35d5eeSXin Li 1463*8c35d5eeSXin Li<h4 id="features-objects-shorthand-properties">5.3.6 Shorthand properties</h4> 1464*8c35d5eeSXin Li 1465*8c35d5eeSXin Li<p>Shorthand properties are allowed on object literals.</p> 1466*8c35d5eeSXin Li 1467*8c35d5eeSXin Li<p>Example:</p> 1468*8c35d5eeSXin Li 1469*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const foo = 1; 1470*8c35d5eeSXin Liconst bar = 2; 1471*8c35d5eeSXin Liconst obj = { 1472*8c35d5eeSXin Li foo, 1473*8c35d5eeSXin Li bar, 1474*8c35d5eeSXin Li method() { return this.foo + this.bar; }, 1475*8c35d5eeSXin Li}; 1476*8c35d5eeSXin LiassertEquals(3, obj.method()); 1477*8c35d5eeSXin Li</code></pre> 1478*8c35d5eeSXin Li 1479*8c35d5eeSXin Li<h4 id="features-objects-destructuring">5.3.7 Destructuring</h4> 1480*8c35d5eeSXin Li 1481*8c35d5eeSXin Li<p>Object destructuring patterns may be used on the left-hand side of an assignment 1482*8c35d5eeSXin Lito perform destructuring and unpack multiple values from a single object.</p> 1483*8c35d5eeSXin Li 1484*8c35d5eeSXin Li<p>Destructured objects may also be used as function parameters, but should be kept 1485*8c35d5eeSXin Lias simple as possible: a single level of unquoted shorthand properties. Deeper 1486*8c35d5eeSXin Lilevels of nesting and computed properties may not be used in parameter 1487*8c35d5eeSXin Lidestructuring. Specify any default values in the left-hand-side of the 1488*8c35d5eeSXin Lidestructured parameter (<code>{str = 'some default'} = {}</code>, rather than <code class="badcode">{str} = {str: 'some default'}</code>), and if a destructured 1489*8c35d5eeSXin Liobject is itself optional, it must default to <code>{}</code>. The JSDoc for the 1490*8c35d5eeSXin Lidestructured parameter may be given any name (the name is unused but is required 1491*8c35d5eeSXin Liby the compiler).</p> 1492*8c35d5eeSXin Li 1493*8c35d5eeSXin Li<p>Example:</p> 1494*8c35d5eeSXin Li 1495*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 1496*8c35d5eeSXin Li * @param {string} ordinary 1497*8c35d5eeSXin Li * @param {{num: (number|undefined), str: (string|undefined)}=} param1 1498*8c35d5eeSXin Li * num: The number of times to do something. 1499*8c35d5eeSXin Li * str: A string to do stuff to. 1500*8c35d5eeSXin Li */ 1501*8c35d5eeSXin Lifunction destructured(ordinary, {num, str = 'some default'} = {}) 1502*8c35d5eeSXin Li</code></pre> 1503*8c35d5eeSXin Li 1504*8c35d5eeSXin Li<p>Disallowed:</p> 1505*8c35d5eeSXin Li 1506*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">/** @param {{x: {num: (number|undefined), str: (string|undefined)}}} param1 */ 1507*8c35d5eeSXin Lifunction nestedTooDeeply({x: {num, str}}) {}; 1508*8c35d5eeSXin Li/** @param {{num: (number|undefined), str: (string|undefined)}=} param1 */ 1509*8c35d5eeSXin Lifunction nonShorthandProperty({num: a, str: b} = {}) {}; 1510*8c35d5eeSXin Li/** @param {{a: number, b: number}} param1 */ 1511*8c35d5eeSXin Lifunction computedKey({a, b, [a + b]: c}) {}; 1512*8c35d5eeSXin Li/** @param {{a: number, b: string}=} param1 */ 1513*8c35d5eeSXin Lifunction nontrivialDefault({a, b} = {a: 2, b: 4}) {}; 1514*8c35d5eeSXin Li</code></pre> 1515*8c35d5eeSXin Li 1516*8c35d5eeSXin Li<p>Destructuring may also be used for <code>goog.require</code> statements, and in this case 1517*8c35d5eeSXin Limust not be wrapped: the entire statement occupies one line, regardless of how 1518*8c35d5eeSXin Lilong it is (see <a href="#file-goog-require">??</a>).</p> 1519*8c35d5eeSXin Li 1520*8c35d5eeSXin Li<h4 id="features-objects-enums">5.3.8 Enums</h4> 1521*8c35d5eeSXin Li 1522*8c35d5eeSXin Li<p>Enumerations are defined by adding the <code>@enum</code> annotation to an object literal. 1523*8c35d5eeSXin LiAdditional properties may not be added to an enum after it is defined. Enums 1524*8c35d5eeSXin Limust be constant, and all enum values must be deeply immutable.</p> 1525*8c35d5eeSXin Li 1526*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 1527*8c35d5eeSXin Li * Supported temperature scales. 1528*8c35d5eeSXin Li * @enum {string} 1529*8c35d5eeSXin Li */ 1530*8c35d5eeSXin Liconst TemperatureScale = { 1531*8c35d5eeSXin Li CELSIUS: 'celsius', 1532*8c35d5eeSXin Li FAHRENHEIT: 'fahrenheit', 1533*8c35d5eeSXin Li}; 1534*8c35d5eeSXin Li 1535*8c35d5eeSXin Li/** 1536*8c35d5eeSXin Li * An enum with two options. 1537*8c35d5eeSXin Li * @enum {number} 1538*8c35d5eeSXin Li */ 1539*8c35d5eeSXin Liconst Option = { 1540*8c35d5eeSXin Li /** The option used shall have been the first. */ 1541*8c35d5eeSXin Li FIRST_OPTION: 1, 1542*8c35d5eeSXin Li /** The second among two options. */ 1543*8c35d5eeSXin Li SECOND_OPTION: 2, 1544*8c35d5eeSXin Li}; 1545*8c35d5eeSXin Li</code></pre> 1546*8c35d5eeSXin Li 1547*8c35d5eeSXin Li<h3 id="features-classes">5.4 Classes</h3> 1548*8c35d5eeSXin Li 1549*8c35d5eeSXin Li<h4 id="features-classes-constructors">5.4.1 Constructors</h4> 1550*8c35d5eeSXin Li 1551*8c35d5eeSXin Li<p>Constructors are optional. Subclass constructors must call <code>super()</code> before 1552*8c35d5eeSXin Lisetting any fields or otherwise accessing <code>this</code>. Interfaces should declare 1553*8c35d5eeSXin Linon-method properties in the constructor.</p> 1554*8c35d5eeSXin Li 1555*8c35d5eeSXin Li<h4 id="features-classes-fields">5.4.2 Fields</h4> 1556*8c35d5eeSXin Li 1557*8c35d5eeSXin Li<p>Set all of a concrete object’s fields (i.e. all properties other than methods) 1558*8c35d5eeSXin Liin the constructor. Annotate fields that are never reassigned with <code>@const</code> 1559*8c35d5eeSXin Li(these need not be deeply immutable). Annotate non-public fields with the proper 1560*8c35d5eeSXin Livisibility annotation (<code>@private</code>, <code>@protected</code>, <code>@package</code>), and end all 1561*8c35d5eeSXin Li<code>@private</code> fields' names with an underscore. Fields are never set on a concrete 1562*8c35d5eeSXin Liclass' <code>prototype</code>.</p> 1563*8c35d5eeSXin Li 1564*8c35d5eeSXin Li<p>Example:</p> 1565*8c35d5eeSXin Li 1566*8c35d5eeSXin Li<pre><code class="language-js prettyprint">class Foo { 1567*8c35d5eeSXin Li constructor() { 1568*8c35d5eeSXin Li /** @private @const {!Bar} */ 1569*8c35d5eeSXin Li this.bar_ = computeBar(); 1570*8c35d5eeSXin Li 1571*8c35d5eeSXin Li /** @protected @const {!Baz} */ 1572*8c35d5eeSXin Li this.baz = computeBaz(); 1573*8c35d5eeSXin Li } 1574*8c35d5eeSXin Li} 1575*8c35d5eeSXin Li</code></pre> 1576*8c35d5eeSXin Li 1577*8c35d5eeSXin Li<p>Tip: Properties should never be added to or removed from an instance after the 1578*8c35d5eeSXin Liconstructor is finished, since it significantly hinders VMs’ ability to 1579*8c35d5eeSXin Lioptimize. If necessary, fields that are initialized later should be explicitly 1580*8c35d5eeSXin Liset to <code>undefined</code> in the constructor to prevent later shape changes. Adding 1581*8c35d5eeSXin Li<code>@struct</code> to an object will check that undeclared properties are not 1582*8c35d5eeSXin Liadded/accessed. Classes have this added by default.</p> 1583*8c35d5eeSXin Li 1584*8c35d5eeSXin Li<h4 id="features-classes-computed-properties">5.4.3 Computed properties</h4> 1585*8c35d5eeSXin Li 1586*8c35d5eeSXin Li 1587*8c35d5eeSXin Li 1588*8c35d5eeSXin Li<p>Computed properties may only be used in classes when the property is a 1589*8c35d5eeSXin Lisymbol. Dict-style properties (that is, quoted or computed non-symbol keys, as 1590*8c35d5eeSXin Lidefined in <a href="#features-objects-mixing-keys">??</a>) are not allowed. A 1591*8c35d5eeSXin Li<code>[Symbol.iterator]</code> method should be defined for any classes that are logically 1592*8c35d5eeSXin Liiterable. Beyond this, <code>Symbol</code> should be used sparingly.</p> 1593*8c35d5eeSXin Li 1594*8c35d5eeSXin Li<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> 1595*8c35d5eeSXin Li 1596*8c35d5eeSXin Li<h4 id="features-classes-static-methods">5.4.4 Static methods</h4> 1597*8c35d5eeSXin Li 1598*8c35d5eeSXin Li 1599*8c35d5eeSXin Li 1600*8c35d5eeSXin Li<p>Where it does not interfere with readability, prefer module-local functions over 1601*8c35d5eeSXin Liprivate static methods.</p> 1602*8c35d5eeSXin Li 1603*8c35d5eeSXin Li<p>Static methods should only be called on the base class itself. Static methods 1604*8c35d5eeSXin Lishould not be called on variables containing a dynamic instance that may be 1605*8c35d5eeSXin Lieither the constructor or a subclass constructor (and must be defined with 1606*8c35d5eeSXin Li<code>@nocollapse</code> if this is done), and must not be called directly on a subclass 1607*8c35d5eeSXin Lithat doesn’t define the method itself.</p> 1608*8c35d5eeSXin Li 1609*8c35d5eeSXin Li<p>Disallowed:</p> 1610*8c35d5eeSXin Li 1611*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">class Base { /** @nocollapse */ static foo() {} } 1612*8c35d5eeSXin Liclass Sub extends Base {} 1613*8c35d5eeSXin Lifunction callFoo(cls) { cls.foo(); } // discouraged: don't call static methods dynamically 1614*8c35d5eeSXin LiSub.foo(); // Disallowed: don't call static methods on subclasses that don't define it themselves 1615*8c35d5eeSXin Li</code></pre> 1616*8c35d5eeSXin Li 1617*8c35d5eeSXin Li<h4 id="features-classes-old-style">5.4.5 Old-style class declarations</h4> 1618*8c35d5eeSXin Li 1619*8c35d5eeSXin Li<p>While ES6 classes are preferred, there are cases where ES6 classes may not be 1620*8c35d5eeSXin Lifeasible. For example:</p> 1621*8c35d5eeSXin Li 1622*8c35d5eeSXin Li<ol> 1623*8c35d5eeSXin Li<li><p>If there exist or will exist subclasses, including frameworks that create 1624*8c35d5eeSXin Lisubclasses, that cannot be immediately changed to use ES6 class syntax. If 1625*8c35d5eeSXin Lisuch a class were to use ES6 syntax, all downstream subclasses not using ES6 1626*8c35d5eeSXin Liclass syntax would need to be modified.</p></li> 1627*8c35d5eeSXin Li<li><p>Frameworks that require a known <code>this</code> value before calling the superclass 1628*8c35d5eeSXin Liconstructor, since constructors with ES6 super classes do not have 1629*8c35d5eeSXin Liaccess to the instance <code>this</code> value until the call to <code>super</code> returns.</p></li> 1630*8c35d5eeSXin Li</ol> 1631*8c35d5eeSXin Li 1632*8c35d5eeSXin Li<p>In all other ways the style guide still applies to this code: <code>let</code>, <code>const</code>, 1633*8c35d5eeSXin Lidefault parameters, rest, and arrow functions should all be used when 1634*8c35d5eeSXin Liappropriate.</p> 1635*8c35d5eeSXin Li 1636*8c35d5eeSXin Li<p><code>goog.defineClass</code> allows for a class-like definition similar to ES6 class 1637*8c35d5eeSXin Lisyntax:</p> 1638*8c35d5eeSXin Li 1639*8c35d5eeSXin Li<pre><code class="language-javascript">let C = goog.defineClass(S, { 1640*8c35d5eeSXin Li /** 1641*8c35d5eeSXin Li * @param {string} value 1642*8c35d5eeSXin Li */ 1643*8c35d5eeSXin Li constructor(value) { 1644*8c35d5eeSXin Li S.call(this, 2); 1645*8c35d5eeSXin Li /** @const */ 1646*8c35d5eeSXin Li this.prop = value; 1647*8c35d5eeSXin Li }, 1648*8c35d5eeSXin Li 1649*8c35d5eeSXin Li /** 1650*8c35d5eeSXin Li * @param {string} param 1651*8c35d5eeSXin Li * @return {number} 1652*8c35d5eeSXin Li */ 1653*8c35d5eeSXin Li method(param) { 1654*8c35d5eeSXin Li return 0; 1655*8c35d5eeSXin Li }, 1656*8c35d5eeSXin Li}); 1657*8c35d5eeSXin Li</code></pre> 1658*8c35d5eeSXin Li 1659*8c35d5eeSXin Li<p>Alternatively, while <code>goog.defineClass</code> should be preferred for all new code, 1660*8c35d5eeSXin Limore traditional syntax is also allowed.</p> 1661*8c35d5eeSXin Li 1662*8c35d5eeSXin Li<pre><code class="language-javascript">/** 1663*8c35d5eeSXin Li * @constructor @extends {S} 1664*8c35d5eeSXin Li * @param {string} value 1665*8c35d5eeSXin Li */ 1666*8c35d5eeSXin Lifunction C(value) { 1667*8c35d5eeSXin Li S.call(this, 2); 1668*8c35d5eeSXin Li /** @const */ 1669*8c35d5eeSXin Li this.prop = value; 1670*8c35d5eeSXin Li} 1671*8c35d5eeSXin Ligoog.inherits(C, S); 1672*8c35d5eeSXin Li 1673*8c35d5eeSXin Li/** 1674*8c35d5eeSXin Li * @param {string} param 1675*8c35d5eeSXin Li * @return {number} 1676*8c35d5eeSXin Li */ 1677*8c35d5eeSXin LiC.prototype.method = function(param) { 1678*8c35d5eeSXin Li return 0; 1679*8c35d5eeSXin Li}; 1680*8c35d5eeSXin Li</code></pre> 1681*8c35d5eeSXin Li 1682*8c35d5eeSXin Li<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> 1683*8c35d5eeSXin Li 1684*8c35d5eeSXin Li<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> 1685*8c35d5eeSXin Li 1686*8c35d5eeSXin Li<h4 id="features-classes-prototypes">5.4.6 Do not manipulate <code>prototype</code>s directly</h4> 1687*8c35d5eeSXin Li 1688*8c35d5eeSXin Li<p>The <code>class</code> keyword allows clearer and more readable class definitions than 1689*8c35d5eeSXin Lidefining <code>prototype</code> properties. Ordinary implementation code has no business 1690*8c35d5eeSXin Limanipulating these objects, though they are still useful for defining classes as 1691*8c35d5eeSXin Lidefined in <a href="#features-classes-old-style">??</a>. Mixins and modifying the 1692*8c35d5eeSXin Liprototypes of builtin objects are explicitly forbidden.</p> 1693*8c35d5eeSXin Li 1694*8c35d5eeSXin Li<p><strong>Exception</strong>: Framework code (such as Polymer, or Angular) may need to use <code>prototype</code>s, and should not 1695*8c35d5eeSXin Liresort to even-worse workarounds to avoid doing so.</p> 1696*8c35d5eeSXin Li 1697*8c35d5eeSXin Li<h4 id="features-classes-getters-and-setters">5.4.7 Getters and Setters</h4> 1698*8c35d5eeSXin Li 1699*8c35d5eeSXin Li<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 1700*8c35d5eeSXin Lisurprising and difficult to reason about, and have limited support in the 1701*8c35d5eeSXin Licompiler. Provide ordinary methods instead.</p> 1702*8c35d5eeSXin Li 1703*8c35d5eeSXin Li<p><strong>Exception</strong>: there are situations where defining a getter or setter is 1704*8c35d5eeSXin Liunavoidable (e.g. data binding frameworks such as Angular and Polymer, or for 1705*8c35d5eeSXin Licompatibility with external APIs that cannot be adjusted). In these cases only, 1706*8c35d5eeSXin Ligetters and setters may be used <em>with caution</em>, provided they are defined with 1707*8c35d5eeSXin Lithe <code>get</code> and <code>set</code> shorthand method keywords or <code>Object.defineProperties</code> (not 1708*8c35d5eeSXin Li<code>Object.defineProperty</code>, which interferes with property renaming). Getters 1709*8c35d5eeSXin Li<strong>must not</strong> change observable state.</p> 1710*8c35d5eeSXin Li 1711*8c35d5eeSXin Li<p>Disallowed:</p> 1712*8c35d5eeSXin Li 1713*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">class Foo { 1714*8c35d5eeSXin Li get next() { return this.nextId++; } 1715*8c35d5eeSXin Li} 1716*8c35d5eeSXin Li</code></pre> 1717*8c35d5eeSXin Li 1718*8c35d5eeSXin Li<h4 id="features-classes-overriding-tostring">5.4.8 Overriding toString</h4> 1719*8c35d5eeSXin Li 1720*8c35d5eeSXin Li<p>The <code>toString</code> method may be overridden, but must always succeed and never have 1721*8c35d5eeSXin Livisible side effects.</p> 1722*8c35d5eeSXin Li 1723*8c35d5eeSXin Li<p>Tip: Beware, in particular, of calling other methods from toString, since 1724*8c35d5eeSXin Liexceptional conditions could lead to infinite loops.</p> 1725*8c35d5eeSXin Li 1726*8c35d5eeSXin Li<h4 id="features-classes-interfaces">5.4.9 Interfaces</h4> 1727*8c35d5eeSXin Li 1728*8c35d5eeSXin Li<p>Interfaces may be declared with <code>@interface</code> or <code>@record</code>. Interfaces declared 1729*8c35d5eeSXin Liwith <code>@record</code> can be explicitly (i.e. via <code>@implements</code>) or implicitly 1730*8c35d5eeSXin Liimplemented by a class or object literal.</p> 1731*8c35d5eeSXin Li 1732*8c35d5eeSXin Li<p>All non-static method bodies on an interface must be empty blocks. Fields must 1733*8c35d5eeSXin Libe declared as uninitialized members in the class constructor.</p> 1734*8c35d5eeSXin Li 1735*8c35d5eeSXin Li<p>Example:</p> 1736*8c35d5eeSXin Li 1737*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 1738*8c35d5eeSXin Li * Something that can frobnicate. 1739*8c35d5eeSXin Li * @record 1740*8c35d5eeSXin Li */ 1741*8c35d5eeSXin Liclass Frobnicator { 1742*8c35d5eeSXin Li constructor() { 1743*8c35d5eeSXin Li /** @type {number} The number of attempts before giving up. */ 1744*8c35d5eeSXin Li this.attempts; 1745*8c35d5eeSXin Li } 1746*8c35d5eeSXin Li 1747*8c35d5eeSXin Li /** 1748*8c35d5eeSXin Li * Performs the frobnication according to the given strategy. 1749*8c35d5eeSXin Li * @param {!FrobnicationStrategy} strategy 1750*8c35d5eeSXin Li */ 1751*8c35d5eeSXin Li frobnicate(strategy) {} 1752*8c35d5eeSXin Li} 1753*8c35d5eeSXin Li 1754*8c35d5eeSXin Li</code></pre> 1755*8c35d5eeSXin Li 1756*8c35d5eeSXin Li<h4 id="features-classes-abstract-classes">5.4.10 Abstract Classes</h4> 1757*8c35d5eeSXin Li 1758*8c35d5eeSXin Li<p>Use abstract classes when appropriate. Abstract classes and methods must be 1759*8c35d5eeSXin Liannotated 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 1760*8c35d5eeSXin Liclasses and methods</a>.</p> 1761*8c35d5eeSXin Li 1762*8c35d5eeSXin Li<h3 id="features-functions">5.5 Functions</h3> 1763*8c35d5eeSXin Li 1764*8c35d5eeSXin Li<h4 id="features-functions-top-level-functions">5.5.1 Top-level functions</h4> 1765*8c35d5eeSXin Li 1766*8c35d5eeSXin Li<p>Top-level functions may be defined directly on the <code>exports</code> object, or else 1767*8c35d5eeSXin Lideclared locally and optionally exported. See <a href="#file-goog-module-exports">??</a> 1768*8c35d5eeSXin Lifor more on exports.</p> 1769*8c35d5eeSXin Li 1770*8c35d5eeSXin Li<p>Examples:</p> 1771*8c35d5eeSXin Li 1772*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @param {string} str */ 1773*8c35d5eeSXin Liexports.processString = (str) => { 1774*8c35d5eeSXin Li // Process the string. 1775*8c35d5eeSXin Li}; 1776*8c35d5eeSXin Li</code></pre> 1777*8c35d5eeSXin Li 1778*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @param {string} str */ 1779*8c35d5eeSXin Liconst processString = (str) => { 1780*8c35d5eeSXin Li // Process the string. 1781*8c35d5eeSXin Li}; 1782*8c35d5eeSXin Li 1783*8c35d5eeSXin Liexports = {processString}; 1784*8c35d5eeSXin Li</code></pre> 1785*8c35d5eeSXin Li 1786*8c35d5eeSXin Li<h4 id="features-functions-nested-functions">5.5.2 Nested functions and closures</h4> 1787*8c35d5eeSXin Li 1788*8c35d5eeSXin Li<p>Functions may contain nested function definitions. If it is useful to give the 1789*8c35d5eeSXin Lifunction a name, it should be assigned to a local <code>const</code>.</p> 1790*8c35d5eeSXin Li 1791*8c35d5eeSXin Li<h4 id="features-functions-arrow-functions">5.5.3 Arrow functions</h4> 1792*8c35d5eeSXin Li 1793*8c35d5eeSXin Li<p>Arrow functions provide a concise function syntax and simplify scoping <code>this</code> 1794*8c35d5eeSXin Lifor nested functions. Prefer arrow functions over the <code>function</code> keyword, 1795*8c35d5eeSXin Liparticularly for nested functions (but see 1796*8c35d5eeSXin Li<a href="#features-objects-method-shorthand">??</a>).</p> 1797*8c35d5eeSXin Li 1798*8c35d5eeSXin Li<p>Prefer arrow functions over other <code>this</code> scoping approaches such as 1799*8c35d5eeSXin Li<code>f.bind(this)</code>, <code>goog.bind(f, this)</code>, and <code>const self = this</code>. Arrow functions 1800*8c35d5eeSXin Liare particularly useful for calling into callbacks as they permit explicitly 1801*8c35d5eeSXin Lispecifying which parameters to pass to the callback whereas binding will blindly 1802*8c35d5eeSXin Lipass along all parameters.</p> 1803*8c35d5eeSXin Li 1804*8c35d5eeSXin Li<p>The left-hand side of the arrow contains zero or more parameters. Parentheses 1805*8c35d5eeSXin Liaround the parameters are optional if there is only a single non-destructured 1806*8c35d5eeSXin Liparameter. When parentheses are used, inline parameter types may be specified 1807*8c35d5eeSXin Li(see <a href="#jsdoc-method-and-function-comments">??</a>).</p> 1808*8c35d5eeSXin Li 1809*8c35d5eeSXin Li<p>Tip: Always using parentheses even for single-parameter arrow functions can 1810*8c35d5eeSXin Liavoid situations where adding parameters, but forgetting to add parentheses, may 1811*8c35d5eeSXin Liresult in parseable code which no longer works as intended.</p> 1812*8c35d5eeSXin Li 1813*8c35d5eeSXin Li<p>The right-hand side of the arrow contains the body of the function. By default 1814*8c35d5eeSXin Lithe body is a block statement (zero or more statements surrounded by curly 1815*8c35d5eeSXin Libraces). The body may also be an implicitly returned single expression if 1816*8c35d5eeSXin Lieither: the program logic requires returning a value, or the <code>void</code> operator 1817*8c35d5eeSXin Liprecedes a single function or method call (using <code>void</code> ensures <code>undefined</code> is 1818*8c35d5eeSXin Lireturned, prevents leaking values, and communicates intent). The single 1819*8c35d5eeSXin Liexpression form is preferred if it improves readability (e.g., for short or 1820*8c35d5eeSXin Lisimple expressions).</p> 1821*8c35d5eeSXin Li 1822*8c35d5eeSXin Li<p>Examples:</p> 1823*8c35d5eeSXin Li 1824*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 1825*8c35d5eeSXin Li * Arrow functions can be documented just like normal functions. 1826*8c35d5eeSXin Li * @param {number} numParam A number to add. 1827*8c35d5eeSXin Li * @param {string} strParam Another number to add that happens to be a string. 1828*8c35d5eeSXin Li * @return {number} The sum of the two parameters. 1829*8c35d5eeSXin Li */ 1830*8c35d5eeSXin Liconst moduleLocalFunc = (numParam, strParam) => numParam + Number(strParam); 1831*8c35d5eeSXin Li 1832*8c35d5eeSXin Li// Uses the single expression syntax with `void` because the program logic does 1833*8c35d5eeSXin Li// not require returning a value. 1834*8c35d5eeSXin LigetValue((result) => void alert(`Got ${result}`)); 1835*8c35d5eeSXin Li 1836*8c35d5eeSXin Liclass CallbackExample { 1837*8c35d5eeSXin Li constructor() { 1838*8c35d5eeSXin Li /** @private {number} */ 1839*8c35d5eeSXin Li this.cachedValue_ = 0; 1840*8c35d5eeSXin Li 1841*8c35d5eeSXin Li // For inline callbacks, you can use inline typing for parameters. 1842*8c35d5eeSXin Li // Uses a block statement because the value of the single expression should 1843*8c35d5eeSXin Li // not be returned and the expression is not a single function call. 1844*8c35d5eeSXin Li getNullableValue((/** ?number */ result) => { 1845*8c35d5eeSXin Li this.cachedValue_ = result == null ? 0 : result; 1846*8c35d5eeSXin Li }); 1847*8c35d5eeSXin Li } 1848*8c35d5eeSXin Li} 1849*8c35d5eeSXin Li</code></pre> 1850*8c35d5eeSXin Li 1851*8c35d5eeSXin Li<p>Disallowed:</p> 1852*8c35d5eeSXin Li 1853*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">/** 1854*8c35d5eeSXin Li * A function with no params and no returned value. 1855*8c35d5eeSXin Li * This single expression body usage is illegal because the program logic does 1856*8c35d5eeSXin Li * not require returning a value and we're missing the `void` operator. 1857*8c35d5eeSXin Li */ 1858*8c35d5eeSXin Liconst moduleLocalFunc = () => anotherFunction(); 1859*8c35d5eeSXin Li</code></pre> 1860*8c35d5eeSXin Li 1861*8c35d5eeSXin Li<h4 id="features-functions-generators">5.5.4 Generators</h4> 1862*8c35d5eeSXin Li 1863*8c35d5eeSXin Li<p>Generators enable a number of useful abstractions and may be used as needed.</p> 1864*8c35d5eeSXin Li 1865*8c35d5eeSXin Li<p>When defining generator functions, attach the <code>*</code> to the <code>function</code> keyword when 1866*8c35d5eeSXin Lipresent, and separate it with a space from the name of the function. When using 1867*8c35d5eeSXin Lidelegating yields, attach the <code>*</code> to the <code>yield</code> keyword.</p> 1868*8c35d5eeSXin Li 1869*8c35d5eeSXin Li<p>Example:</p> 1870*8c35d5eeSXin Li 1871*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @return {!Iterator<number>} */ 1872*8c35d5eeSXin Lifunction* gen1() { 1873*8c35d5eeSXin Li yield 42; 1874*8c35d5eeSXin Li} 1875*8c35d5eeSXin Li 1876*8c35d5eeSXin Li/** @return {!Iterator<number>} */ 1877*8c35d5eeSXin Liconst gen2 = function*() { 1878*8c35d5eeSXin Li yield* gen1(); 1879*8c35d5eeSXin Li} 1880*8c35d5eeSXin Li 1881*8c35d5eeSXin Liclass SomeClass { 1882*8c35d5eeSXin Li /** @return {!Iterator<number>} */ 1883*8c35d5eeSXin Li * gen() { 1884*8c35d5eeSXin Li yield 42; 1885*8c35d5eeSXin Li } 1886*8c35d5eeSXin Li} 1887*8c35d5eeSXin Li</code></pre> 1888*8c35d5eeSXin Li 1889*8c35d5eeSXin Li<h4 id="features-functions-parameter-return-types">5.5.5 Parameter and return types</h4> 1890*8c35d5eeSXin Li 1891*8c35d5eeSXin Li<p>Function parameters and return types should usually be documented with JSDoc 1892*8c35d5eeSXin Liannotations. See <a href="#jsdoc-method-and-function-comments">??</a> for more information.</p> 1893*8c35d5eeSXin Li 1894*8c35d5eeSXin Li<h5 id="features-functions-default-parameters">5.5.5.1 Default parameters</h5> 1895*8c35d5eeSXin Li 1896*8c35d5eeSXin Li<p>Optional parameters are permitted using the equals operator in the parameter 1897*8c35d5eeSXin Lilist. Optional parameters must include spaces on both sides of the equals 1898*8c35d5eeSXin Lioperator, be named exactly like required parameters (i.e., not prefixed with 1899*8c35d5eeSXin Li<code>opt_</code>), use the <code>=</code> suffix in their JSDoc type, come after required parameters, 1900*8c35d5eeSXin Liand not use initializers that produce observable side effects. All optional 1901*8c35d5eeSXin Liparameters for concrete functions must have default values, even if that value 1902*8c35d5eeSXin Liis <code>undefined</code>. In contrast to concrete functions, abstract and interface 1903*8c35d5eeSXin Limethods must omit default parameter values.</p> 1904*8c35d5eeSXin Li 1905*8c35d5eeSXin Li<p>Example:</p> 1906*8c35d5eeSXin Li 1907*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 1908*8c35d5eeSXin Li * @param {string} required This parameter is always needed. 1909*8c35d5eeSXin Li * @param {string=} optional This parameter can be omitted. 1910*8c35d5eeSXin Li * @param {!Node=} node Another optional parameter. 1911*8c35d5eeSXin Li */ 1912*8c35d5eeSXin Lifunction maybeDoSomething(required, optional = '', node = undefined) {} 1913*8c35d5eeSXin Li 1914*8c35d5eeSXin Li/** @interface */ 1915*8c35d5eeSXin Liclass MyInterface { 1916*8c35d5eeSXin Li /** 1917*8c35d5eeSXin Li * Interface and abstract methods must omit default parameter values. 1918*8c35d5eeSXin Li * @param {string=} optional 1919*8c35d5eeSXin Li */ 1920*8c35d5eeSXin Li someMethod(optional) {} 1921*8c35d5eeSXin Li} 1922*8c35d5eeSXin Li</code></pre> 1923*8c35d5eeSXin Li 1924*8c35d5eeSXin Li<p>Use default parameters sparingly. Prefer destructuring (as in 1925*8c35d5eeSXin Li<a href="#features-objects-destructuring">??</a>) to create readable APIs when there 1926*8c35d5eeSXin Liare more than a small handful of optional parameters that do not have a natural 1927*8c35d5eeSXin Liorder.</p> 1928*8c35d5eeSXin Li 1929*8c35d5eeSXin Li<p>Note: Unlike Python's default parameters, it is okay to use initializers that 1930*8c35d5eeSXin Lireturn new mutable objects (such as <code>{}</code> or <code>[]</code>) because the initializer is 1931*8c35d5eeSXin Lievaluated each time the default value is used, so a single object won't be 1932*8c35d5eeSXin Lishared across invocations.</p> 1933*8c35d5eeSXin Li 1934*8c35d5eeSXin Li<p>Tip: While arbitrary expressions including function calls may be used as 1935*8c35d5eeSXin Liinitializers, these should be kept as simple as possible. Avoid initializers 1936*8c35d5eeSXin Lithat expose shared mutable state, as that can easily introduce unintended 1937*8c35d5eeSXin Licoupling between function calls.</p> 1938*8c35d5eeSXin Li 1939*8c35d5eeSXin Li<h5 id="features-functions-rest-parameters">5.5.5.2 Rest parameters</h5> 1940*8c35d5eeSXin Li 1941*8c35d5eeSXin Li<p>Use a <em>rest</em> parameter instead of accessing <code>arguments</code>. Rest parameters are 1942*8c35d5eeSXin Lityped with a <code>...</code> prefix in their JSDoc. The rest parameter must be the last 1943*8c35d5eeSXin Liparameter in the list. There is no space between the <code>...</code> and the parameter 1944*8c35d5eeSXin Liname. Do not name the rest parameter <code>var_args</code>. Never name a local variable or 1945*8c35d5eeSXin Liparameter <code>arguments</code>, which confusingly shadows the built-in name.</p> 1946*8c35d5eeSXin Li 1947*8c35d5eeSXin Li<p>Example:</p> 1948*8c35d5eeSXin Li 1949*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 1950*8c35d5eeSXin Li * @param {!Array<string>} array This is an ordinary parameter. 1951*8c35d5eeSXin Li * @param {...number} numbers The remainder of arguments are all numbers. 1952*8c35d5eeSXin Li */ 1953*8c35d5eeSXin Lifunction variadic(array, ...numbers) {} 1954*8c35d5eeSXin Li</code></pre> 1955*8c35d5eeSXin Li 1956*8c35d5eeSXin Li<h4 id="features-functions-generics">5.5.6 Generics</h4> 1957*8c35d5eeSXin Li 1958*8c35d5eeSXin Li<p>Declare generic functions and methods when necessary with <code>@template TYPE</code> in 1959*8c35d5eeSXin Lithe JSDoc above the function or method definition.</p> 1960*8c35d5eeSXin Li 1961*8c35d5eeSXin Li<h4 id="features-functions-spread-operator">5.5.7 Spread operator</h4> 1962*8c35d5eeSXin Li 1963*8c35d5eeSXin Li<p>Function calls may use the spread operator (<code>...</code>). Prefer the spread operator 1964*8c35d5eeSXin Lito <code>Function.prototype.apply</code> when an array or iterable is unpacked into 1965*8c35d5eeSXin Limultiple parameters of a variadic function. There is no space after the <code>...</code>.</p> 1966*8c35d5eeSXin Li 1967*8c35d5eeSXin Li<p>Example:</p> 1968*8c35d5eeSXin Li 1969*8c35d5eeSXin Li<pre><code class="language-js prettyprint">function myFunction(...elements) {} 1970*8c35d5eeSXin LimyFunction(...array, ...iterable, ...generator()); 1971*8c35d5eeSXin Li</code></pre> 1972*8c35d5eeSXin Li 1973*8c35d5eeSXin Li<h3 id="features-string-literals">5.6 String literals</h3> 1974*8c35d5eeSXin Li 1975*8c35d5eeSXin Li<h4 id="features-strings-use-single-quotes">5.6.1 Use single quotes</h4> 1976*8c35d5eeSXin Li 1977*8c35d5eeSXin Li<p>Ordinary string literals are delimited with single quotes (<code>'</code>), rather than 1978*8c35d5eeSXin Lidouble quotes (<code>"</code>).</p> 1979*8c35d5eeSXin Li 1980*8c35d5eeSXin Li<p>Tip: if a string contains a single quote character, consider using a template 1981*8c35d5eeSXin Listring to avoid having to escape the quote.</p> 1982*8c35d5eeSXin Li 1983*8c35d5eeSXin Li<p>Ordinary string literals may not span multiple lines.</p> 1984*8c35d5eeSXin Li 1985*8c35d5eeSXin Li<h4 id="features-strings-template-strings">5.6.2 Template literals</h4> 1986*8c35d5eeSXin Li 1987*8c35d5eeSXin Li<p>Use template literals (delimited with <code>`</code>) over complex string 1988*8c35d5eeSXin Liconcatenation, particularly if multiple string literals are involved. Template 1989*8c35d5eeSXin Liliterals may span multiple lines.</p> 1990*8c35d5eeSXin Li 1991*8c35d5eeSXin Li<p>If a template literal spans multiple lines, it does not need to follow the 1992*8c35d5eeSXin Liindentation of the enclosing block, though it may if the added whitespace does 1993*8c35d5eeSXin Linot matter.</p> 1994*8c35d5eeSXin Li 1995*8c35d5eeSXin Li<p>Example:</p> 1996*8c35d5eeSXin Li 1997*8c35d5eeSXin Li<pre><code class="language-js prettyprint">function arithmetic(a, b) { 1998*8c35d5eeSXin Li return `Here is a table of arithmetic operations: 1999*8c35d5eeSXin Li${a} + ${b} = ${a + b} 2000*8c35d5eeSXin Li${a} - ${b} = ${a - b} 2001*8c35d5eeSXin Li${a} * ${b} = ${a * b} 2002*8c35d5eeSXin Li${a} / ${b} = ${a / b}`; 2003*8c35d5eeSXin Li} 2004*8c35d5eeSXin Li</code></pre> 2005*8c35d5eeSXin Li 2006*8c35d5eeSXin Li<h4 id="features-strings-no-line-continuations">5.6.3 No line continuations</h4> 2007*8c35d5eeSXin Li 2008*8c35d5eeSXin Li<p>Do not use <em>line continuations</em> (that is, ending a line inside a string literal 2009*8c35d5eeSXin Liwith a backslash) in either ordinary or template string literals. Even though 2010*8c35d5eeSXin LiES5 allows this, it can lead to tricky errors if any trailing whitespace comes 2011*8c35d5eeSXin Liafter the slash, and is less obvious to readers.</p> 2012*8c35d5eeSXin Li 2013*8c35d5eeSXin Li<p>Disallowed:</p> 2014*8c35d5eeSXin Li 2015*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">const longString = 'This is a very long string that far exceeds the 80 \ 2016*8c35d5eeSXin Li column limit. It unfortunately contains long stretches of spaces due \ 2017*8c35d5eeSXin Li to how the continued lines are indented.'; 2018*8c35d5eeSXin Li</code></pre> 2019*8c35d5eeSXin Li 2020*8c35d5eeSXin Li<p>Instead, write</p> 2021*8c35d5eeSXin Li 2022*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const longString = 'This is a very long string that far exceeds the 80 ' + 2023*8c35d5eeSXin Li 'column limit. It does not contain long stretches of spaces since ' + 2024*8c35d5eeSXin Li 'the concatenated strings are cleaner.'; 2025*8c35d5eeSXin Li</code></pre> 2026*8c35d5eeSXin Li 2027*8c35d5eeSXin Li<h3 id="features-number-literals">5.7 Number literals</h3> 2028*8c35d5eeSXin Li 2029*8c35d5eeSXin Li<p>Numbers may be specified in decimal, hex, octal, or binary. Use exactly <code>0x</code>, 2030*8c35d5eeSXin Li<code>0o</code>, and <code>0b</code> prefixes, with lowercase letters, for hex, octal, and binary, 2031*8c35d5eeSXin Lirespectively. Never include a leading zero unless it is immediately followed by 2032*8c35d5eeSXin Li<code>x</code>, <code>o</code>, or <code>b</code>.</p> 2033*8c35d5eeSXin Li 2034*8c35d5eeSXin Li<h3 id="features-control-structures">5.8 Control structures</h3> 2035*8c35d5eeSXin Li 2036*8c35d5eeSXin Li<h4 id="features-for-loops">5.8.1 For loops</h4> 2037*8c35d5eeSXin Li 2038*8c35d5eeSXin Li<p>With ES6, the language now has three different kinds of <code>for</code> loops. All may be 2039*8c35d5eeSXin Liused, though <code>for</code>-<code>of</code> loops should be preferred when possible.</p> 2040*8c35d5eeSXin Li 2041*8c35d5eeSXin Li<p><code>for</code>-<code>in</code> loops may only be used on dict-style objects (see 2042*8c35d5eeSXin Li<a href="#features-objects-mixing-keys">??</a>), and should not be used to iterate over an 2043*8c35d5eeSXin Liarray. <code>Object.prototype.hasOwnProperty</code> should be used in <code>for</code>-<code>in</code> loops to 2044*8c35d5eeSXin Liexclude unwanted prototype properties. Prefer <code>for</code>-<code>of</code> and <code>Object.keys</code> over 2045*8c35d5eeSXin Li<code>for</code>-<code>in</code> when possible.</p> 2046*8c35d5eeSXin Li 2047*8c35d5eeSXin Li<h4 id="features-exceptions">5.8.2 Exceptions</h4> 2048*8c35d5eeSXin Li 2049*8c35d5eeSXin Li<p>Exceptions are an important part of the language and should be used whenever 2050*8c35d5eeSXin Liexceptional cases occur. Always throw <code>Error</code>s or subclasses of <code>Error</code>: never 2051*8c35d5eeSXin Lithrow string literals or other objects. Always use <code>new</code> when constructing an 2052*8c35d5eeSXin Li<code>Error</code>.</p> 2053*8c35d5eeSXin Li 2054*8c35d5eeSXin Li<p>This treatment extends to <code>Promise</code> rejection values as <code>Promise.reject(obj)</code> is 2055*8c35d5eeSXin Liequivalent to <code>throw obj;</code> in async functions.</p> 2056*8c35d5eeSXin Li 2057*8c35d5eeSXin Li<p>Custom exceptions provide a great way to convey additional error information 2058*8c35d5eeSXin Lifrom functions. They should be defined and used wherever the native <code>Error</code> 2059*8c35d5eeSXin Litype is insufficient.</p> 2060*8c35d5eeSXin Li 2061*8c35d5eeSXin Li<p>Prefer throwing exceptions over ad-hoc error-handling approaches (such as 2062*8c35d5eeSXin Lipassing an error container reference type, or returning an object with an error 2063*8c35d5eeSXin Liproperty).</p> 2064*8c35d5eeSXin Li 2065*8c35d5eeSXin Li<h5 id="features-empty-catch-blocks">5.8.2.1 Empty catch blocks</h5> 2066*8c35d5eeSXin Li 2067*8c35d5eeSXin Li<p>It is very rarely correct to do nothing in response to a caught exception. When 2068*8c35d5eeSXin Liit truly is appropriate to take no action whatsoever in a catch block, the 2069*8c35d5eeSXin Lireason this is justified is explained in a comment.</p> 2070*8c35d5eeSXin Li 2071*8c35d5eeSXin Li<pre><code class="language-js prettyprint">try { 2072*8c35d5eeSXin Li return handleNumericResponse(response); 2073*8c35d5eeSXin Li} catch (ok) { 2074*8c35d5eeSXin Li // it's not numeric; that's fine, just continue 2075*8c35d5eeSXin Li} 2076*8c35d5eeSXin Lireturn handleTextResponse(response); 2077*8c35d5eeSXin Li</code></pre> 2078*8c35d5eeSXin Li 2079*8c35d5eeSXin Li<p>Disallowed:</p> 2080*8c35d5eeSXin Li 2081*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode"> try { 2082*8c35d5eeSXin Li shouldFail(); 2083*8c35d5eeSXin Li fail('expected an error'); 2084*8c35d5eeSXin Li } catch (expected) { 2085*8c35d5eeSXin Li } 2086*8c35d5eeSXin Li</code></pre> 2087*8c35d5eeSXin Li 2088*8c35d5eeSXin Li<p>Tip: Unlike in some other languages, patterns like the above simply don’t work 2089*8c35d5eeSXin Lisince this will catch the error thrown by <code>fail</code>. Use <code>assertThrows()</code> instead.</p> 2090*8c35d5eeSXin Li 2091*8c35d5eeSXin Li<h4 id="features-switch-statements">5.8.3 Switch statements</h4> 2092*8c35d5eeSXin Li 2093*8c35d5eeSXin Li<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> 2094*8c35d5eeSXin Li 2095*8c35d5eeSXin Li<h5 id="features-switch-fall-through">5.8.3.1 Fall-through: commented</h5> 2096*8c35d5eeSXin Li 2097*8c35d5eeSXin Li<p>Within a switch block, each statement group either terminates abruptly (with a 2098*8c35d5eeSXin Li<code>break</code>, <code>return</code> or <code>throw</code>n exception), or is marked with a comment to 2099*8c35d5eeSXin Liindicate that execution will or might continue into the next statement 2100*8c35d5eeSXin Ligroup. Any comment that communicates the idea of fall-through is sufficient 2101*8c35d5eeSXin Li(typically <code>// fall through</code>). This special comment is not required in the last 2102*8c35d5eeSXin Listatement group of the switch block.</p> 2103*8c35d5eeSXin Li 2104*8c35d5eeSXin Li<p>Example:</p> 2105*8c35d5eeSXin Li 2106*8c35d5eeSXin Li<pre><code class="language-js prettyprint">switch (input) { 2107*8c35d5eeSXin Li case 1: 2108*8c35d5eeSXin Li case 2: 2109*8c35d5eeSXin Li prepareOneOrTwo(); 2110*8c35d5eeSXin Li // fall through 2111*8c35d5eeSXin Li case 3: 2112*8c35d5eeSXin Li handleOneTwoOrThree(); 2113*8c35d5eeSXin Li break; 2114*8c35d5eeSXin Li default: 2115*8c35d5eeSXin Li handleLargeNumber(input); 2116*8c35d5eeSXin Li} 2117*8c35d5eeSXin Li</code></pre> 2118*8c35d5eeSXin Li 2119*8c35d5eeSXin Li<h5 id="features-switch-default-case">5.8.3.2 The <code>default</code> case is present</h5> 2120*8c35d5eeSXin Li 2121*8c35d5eeSXin Li<p>Each switch statement includes a <code>default</code> statement group, even if it contains 2122*8c35d5eeSXin Lino code. The <code>default</code> statement group must be last.</p> 2123*8c35d5eeSXin Li 2124*8c35d5eeSXin Li<h3 id="features-this">5.9 this</h3> 2125*8c35d5eeSXin Li 2126*8c35d5eeSXin Li<p>Only use <code>this</code> in class constructors and methods, in arrow functions defined 2127*8c35d5eeSXin Liwithin class constructors and methods, or in functions that have an explicit 2128*8c35d5eeSXin Li<code>@this</code> declared in the immediately-enclosing function’s JSDoc.</p> 2129*8c35d5eeSXin Li 2130*8c35d5eeSXin Li<p>Never use <code>this</code> to refer to the global object, the context of an <code>eval</code>, the 2131*8c35d5eeSXin Litarget of an event, or unnecessarily <code>call()</code>ed or <code>apply()</code>ed functions.</p> 2132*8c35d5eeSXin Li 2133*8c35d5eeSXin Li<h3 id="features-equality-checks">5.10 Equality Checks</h3> 2134*8c35d5eeSXin Li 2135*8c35d5eeSXin Li<p>Use identity operators (<code>===</code>/<code>!==</code>) except in the cases documented below.</p> 2136*8c35d5eeSXin Li 2137*8c35d5eeSXin Li<h4 id="features-equality-checks-exceptions">5.10.1 Exceptions Where Coercion is Desirable</h4> 2138*8c35d5eeSXin Li 2139*8c35d5eeSXin Li<p>Catching both <code>null</code> and <code>undefined</code> values:</p> 2140*8c35d5eeSXin Li 2141*8c35d5eeSXin Li<pre><code class="language-js prettyprint">if (someObjectOrPrimitive == null) { 2142*8c35d5eeSXin Li // Checking for null catches both null and undefined for objects and 2143*8c35d5eeSXin Li // primitives, but does not catch other falsy values like 0 or the empty 2144*8c35d5eeSXin Li // string. 2145*8c35d5eeSXin Li} 2146*8c35d5eeSXin Li</code></pre> 2147*8c35d5eeSXin Li 2148*8c35d5eeSXin Li<h3 id="disallowed-features">5.11 Disallowed features</h3> 2149*8c35d5eeSXin Li 2150*8c35d5eeSXin Li<h4 id="disallowed-features-with">5.11.1 with</h4> 2151*8c35d5eeSXin Li 2152*8c35d5eeSXin Li<p>Do not use the <code>with</code> keyword. It makes your code harder to understand and has 2153*8c35d5eeSXin Libeen banned in strict mode since ES5.</p> 2154*8c35d5eeSXin Li 2155*8c35d5eeSXin Li<h4 id="disallowed-features-dynamic-code-evaluation">5.11.2 Dynamic code evaluation</h4> 2156*8c35d5eeSXin Li 2157*8c35d5eeSXin Li<p>Do not use <code>eval</code> or the <code>Function(...string)</code> constructor (except for code 2158*8c35d5eeSXin Liloaders). These features are potentially dangerous and simply do not work in 2159*8c35d5eeSXin LiCSP environments.</p> 2160*8c35d5eeSXin Li 2161*8c35d5eeSXin Li<h4 id="disallowed-features-automatic-semicolon-insertion">5.11.3 Automatic semicolon insertion</h4> 2162*8c35d5eeSXin Li 2163*8c35d5eeSXin Li<p>Always terminate statements with semicolons (except function and class 2164*8c35d5eeSXin Lideclarations, as noted above).</p> 2165*8c35d5eeSXin Li 2166*8c35d5eeSXin Li<h4 id="disallowed-features-non-standard-features">5.11.4 Non-standard features</h4> 2167*8c35d5eeSXin Li 2168*8c35d5eeSXin Li<p>Do not use non-standard features. This includes old features that have been 2169*8c35d5eeSXin Liremoved (e.g., <code>WeakMap.clear</code>), new features that are not yet standardized 2170*8c35d5eeSXin Li(e.g., the current TC39 working draft, proposals at any stage, or proposed but 2171*8c35d5eeSXin Linot-yet-complete web standards), or proprietary features that are only 2172*8c35d5eeSXin Liimplemented in some browsers. Use only features defined in the current ECMA-262 2173*8c35d5eeSXin Lior WHATWG standards. (Note that projects writing against specific APIs, such as 2174*8c35d5eeSXin LiChrome extensions or Node.js, can obviously use those APIs). Non-standard 2175*8c35d5eeSXin Lilanguage “extensions” (such as those provided by some external transpilers) are 2176*8c35d5eeSXin Liforbidden.</p> 2177*8c35d5eeSXin Li 2178*8c35d5eeSXin Li<h4 id="disallowed-features-wrapper-objects">5.11.5 Wrapper objects for primitive types</h4> 2179*8c35d5eeSXin Li 2180*8c35d5eeSXin Li<p>Never use <code>new</code> on the primitive object wrappers (<code>Boolean</code>, <code>Number</code>, <code>String</code>, 2181*8c35d5eeSXin Li<code>Symbol</code>), nor include them in type annotations.</p> 2182*8c35d5eeSXin Li 2183*8c35d5eeSXin Li<p>Disallowed:</p> 2184*8c35d5eeSXin Li 2185*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">const /** Boolean */ x = new Boolean(false); 2186*8c35d5eeSXin Liif (x) alert(typeof x); // alerts 'object' - WAT? 2187*8c35d5eeSXin Li</code></pre> 2188*8c35d5eeSXin Li 2189*8c35d5eeSXin Li<p>The wrappers may be called as functions for coercing (which is preferred over 2190*8c35d5eeSXin Liusing <code>+</code> or concatenating the empty string) or creating symbols.</p> 2191*8c35d5eeSXin Li 2192*8c35d5eeSXin Li<p>Example:</p> 2193*8c35d5eeSXin Li 2194*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const /** boolean */ x = Boolean(0); 2195*8c35d5eeSXin Liif (!x) alert(typeof x); // alerts 'boolean', as expected 2196*8c35d5eeSXin Li</code></pre> 2197*8c35d5eeSXin Li 2198*8c35d5eeSXin Li<h4 id="disallowed-features-modifying-builtin-objects">5.11.6 Modifying builtin objects</h4> 2199*8c35d5eeSXin Li 2200*8c35d5eeSXin Li<p>Never modify builtin types, either by adding methods to their constructors or to 2201*8c35d5eeSXin Litheir prototypes. Avoid depending on libraries that do this. Note that the 2202*8c35d5eeSXin LiJSCompiler’s runtime library will provide standards-compliant polyfills where 2203*8c35d5eeSXin Lipossible; nothing else may modify builtin objects.</p> 2204*8c35d5eeSXin Li 2205*8c35d5eeSXin Li<p>Do not add symbols to the global object unless absolutely necessary 2206*8c35d5eeSXin Li(e.g. required by a third-party API).</p> 2207*8c35d5eeSXin Li 2208*8c35d5eeSXin Li<h4 id="disallowed-features-omitting-parents-with-new">5.11.7 Omitting <code>()</code> when invoking a constructor</h4> 2209*8c35d5eeSXin Li 2210*8c35d5eeSXin Li<p>Never invoke a constructor in a <code>new</code> statement without using parentheses <code>()</code>.</p> 2211*8c35d5eeSXin Li 2212*8c35d5eeSXin Li<p>Disallowed:</p> 2213*8c35d5eeSXin Li 2214*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">new Foo; 2215*8c35d5eeSXin Li</code></pre> 2216*8c35d5eeSXin Li 2217*8c35d5eeSXin Li<p>Use instead:</p> 2218*8c35d5eeSXin Li 2219*8c35d5eeSXin Li<pre><code class="language-js prettyprint">new Foo(); 2220*8c35d5eeSXin Li</code></pre> 2221*8c35d5eeSXin Li 2222*8c35d5eeSXin Li<p>Omitting parentheses can lead to subtle mistakes. These two lines are not 2223*8c35d5eeSXin Liequivalent:</p> 2224*8c35d5eeSXin Li 2225*8c35d5eeSXin Li<pre><code class="language-js prettyprint">new Foo().Bar(); 2226*8c35d5eeSXin Linew Foo.Bar(); 2227*8c35d5eeSXin Li</code></pre> 2228*8c35d5eeSXin Li 2229*8c35d5eeSXin Li<h2 id="naming">6 Naming</h2> 2230*8c35d5eeSXin Li 2231*8c35d5eeSXin Li<h3 id="naming-rules-common-to-all-identifiers">6.1 Rules common to all identifiers</h3> 2232*8c35d5eeSXin Li 2233*8c35d5eeSXin Li<p>Identifiers use only ASCII letters and digits, and, in a small number of cases 2234*8c35d5eeSXin Linoted below, underscores and very rarely (when required by frameworks like 2235*8c35d5eeSXin LiAngular) dollar signs.</p> 2236*8c35d5eeSXin Li 2237*8c35d5eeSXin Li<p>Give as descriptive a name as possible, within reason. Do not worry about saving 2238*8c35d5eeSXin Lihorizontal space as it is far more important to make your code immediately 2239*8c35d5eeSXin Liunderstandable by a new reader. Do not use abbreviations that are ambiguous or 2240*8c35d5eeSXin Liunfamiliar to readers outside your project, and do not abbreviate by deleting 2241*8c35d5eeSXin Liletters within a word.</p> 2242*8c35d5eeSXin Li 2243*8c35d5eeSXin Li<pre><code class="language-js prettyprint">errorCount // No abbreviation. 2244*8c35d5eeSXin LidnsConnectionIndex // Most people know what "DNS" stands for. 2245*8c35d5eeSXin LireferrerUrl // Ditto for "URL". 2246*8c35d5eeSXin LicustomerId // "Id" is both ubiquitous and unlikely to be misunderstood. 2247*8c35d5eeSXin Li</code></pre> 2248*8c35d5eeSXin Li 2249*8c35d5eeSXin Li<p>Disallowed:</p> 2250*8c35d5eeSXin Li 2251*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">n // Meaningless. 2252*8c35d5eeSXin LinErr // Ambiguous abbreviation. 2253*8c35d5eeSXin LinCompConns // Ambiguous abbreviation. 2254*8c35d5eeSXin LiwgcConnections // Only your group knows what this stands for. 2255*8c35d5eeSXin LipcReader // Lots of things can be abbreviated "pc". 2256*8c35d5eeSXin LicstmrId // Deletes internal letters. 2257*8c35d5eeSXin LikSecondsPerDay // Do not use Hungarian notation. 2258*8c35d5eeSXin Li</code></pre> 2259*8c35d5eeSXin Li 2260*8c35d5eeSXin Li<h3 id="naming-rules-by-identifier-type">6.2 Rules by identifier type</h3> 2261*8c35d5eeSXin Li 2262*8c35d5eeSXin Li<h4 id="naming-package-names">6.2.1 Package names</h4> 2263*8c35d5eeSXin Li 2264*8c35d5eeSXin Li<p>Package names are all <code>lowerCamelCase</code>. For example, 2265*8c35d5eeSXin Li<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> 2266*8c35d5eeSXin Li 2267*8c35d5eeSXin Li<h4 id="naming-class-names">6.2.2 Class names</h4> 2268*8c35d5eeSXin Li 2269*8c35d5eeSXin Li<p>Class, interface, record, and typedef names are written in <code>UpperCamelCase</code>. 2270*8c35d5eeSXin LiUnexported classes are simply locals: they are not marked <code>@private</code> and 2271*8c35d5eeSXin Litherefore are not named with a trailing underscore.</p> 2272*8c35d5eeSXin Li 2273*8c35d5eeSXin Li<p>Type names are typically nouns or noun phrases. For example, <code>Request</code>, 2274*8c35d5eeSXin Li<code>ImmutableList</code>, or <code>VisibilityMode</code>. Additionally, interface names may 2275*8c35d5eeSXin Lisometimes be adjectives or adjective phrases instead (for example, <code>Readable</code>).</p> 2276*8c35d5eeSXin Li 2277*8c35d5eeSXin Li<h4 id="naming-method-names">6.2.3 Method names</h4> 2278*8c35d5eeSXin Li 2279*8c35d5eeSXin Li<p>Method names are written in <code>lowerCamelCase</code>. Names for <code>@private</code> methods must 2280*8c35d5eeSXin Liend with a trailing underscore.</p> 2281*8c35d5eeSXin Li 2282*8c35d5eeSXin Li<p>Method names are typically verbs or verb phrases. For example, <code>sendMessage</code> or 2283*8c35d5eeSXin Li<code>stop_</code>. Getter and setter methods for properties are never required, but if 2284*8c35d5eeSXin Lithey are used they should be named <code>getFoo</code> (or optionally <code>isFoo</code> or <code>hasFoo</code> 2285*8c35d5eeSXin Lifor booleans), or <code>setFoo(value)</code> for setters.</p> 2286*8c35d5eeSXin Li 2287*8c35d5eeSXin Li<p>Underscores may also appear in JsUnit test method names to separate logical 2288*8c35d5eeSXin Licomponents of the name. One typical pattern is 2289*8c35d5eeSXin Li<code>test<MethodUnderTest>_<state>_<expectedOutcome></code>, for example 2290*8c35d5eeSXin Li<code>testPop_emptyStack_throws</code>. There is no One Correct Way to name test methods.</p> 2291*8c35d5eeSXin Li 2292*8c35d5eeSXin Li<h4 id="naming-enum-names">6.2.4 Enum names</h4> 2293*8c35d5eeSXin Li 2294*8c35d5eeSXin Li<p>Enum names are written in <code>UpperCamelCase</code>, similar to classes, and should 2295*8c35d5eeSXin Ligenerally be singular nouns. Individual items within the enum are named in 2296*8c35d5eeSXin Li<code>CONSTANT_CASE</code>.</p> 2297*8c35d5eeSXin Li 2298*8c35d5eeSXin Li<h4 id="naming-constant-names">6.2.5 Constant names</h4> 2299*8c35d5eeSXin Li 2300*8c35d5eeSXin Li<p>Constant names use <code>CONSTANT_CASE</code>: all uppercase letters, with words separated 2301*8c35d5eeSXin Liby underscores. There is no reason for a constant to be named with a trailing 2302*8c35d5eeSXin Liunderscore, since private static properties can be replaced by (implicitly 2303*8c35d5eeSXin Liprivate) module locals.</p> 2304*8c35d5eeSXin Li 2305*8c35d5eeSXin Li<h5 id="naming-definition-of-constant">6.2.5.1 Definition of “constant”</h5> 2306*8c35d5eeSXin Li 2307*8c35d5eeSXin Li<p>Every constant is a <code>@const</code> static property or a module-local <code>const</code> 2308*8c35d5eeSXin Lideclaration, but not all <code>@const</code> static properties and module-local <code>const</code>s 2309*8c35d5eeSXin Liare constants. Before choosing constant case, consider whether the field really 2310*8c35d5eeSXin Lifeels like a <em>deeply immutable</em> constant. For example, if any of that instance's 2311*8c35d5eeSXin Liobservable state can change, it is almost certainly not a constant. Merely 2312*8c35d5eeSXin Liintending to never mutate the object is generally not enough.</p> 2313*8c35d5eeSXin Li 2314*8c35d5eeSXin Li<p>Examples:</p> 2315*8c35d5eeSXin Li 2316*8c35d5eeSXin Li<pre><code class="language-js prettyprint">// Constants 2317*8c35d5eeSXin Liconst NUMBER = 5; 2318*8c35d5eeSXin Li/** @const */ exports.NAMES = ImmutableList.of('Ed', 'Ann'); 2319*8c35d5eeSXin Li/** @enum */ exports.SomeEnum = { ENUM_CONSTANT: 'value' }; 2320*8c35d5eeSXin Li 2321*8c35d5eeSXin Li// Not constants 2322*8c35d5eeSXin Lilet letVariable = 'non-const'; 2323*8c35d5eeSXin Liclass MyClass { constructor() { /** @const {string} */ this.nonStatic = 'non-static'; } }; 2324*8c35d5eeSXin Li/** @type {string} */ MyClass.staticButMutable = 'not @const, can be reassigned'; 2325*8c35d5eeSXin Liconst /** Set<string> */ mutableCollection = new Set(); 2326*8c35d5eeSXin Liconst /** ImmutableSet<SomeMutableType> */ mutableElements = ImmutableSet.of(mutable); 2327*8c35d5eeSXin Liconst Foo = goog.require('my.Foo'); // mirrors imported name 2328*8c35d5eeSXin Liconst logger = log.getLogger('loggers.are.not.immutable'); 2329*8c35d5eeSXin Li</code></pre> 2330*8c35d5eeSXin Li 2331*8c35d5eeSXin Li<p>Constants’ names are typically nouns or noun phrases.</p> 2332*8c35d5eeSXin Li 2333*8c35d5eeSXin Li<h5 id="naming-local-aliases">6.2.5.2 Local aliases</h5> 2334*8c35d5eeSXin Li 2335*8c35d5eeSXin Li<p>Local aliases should be used whenever they improve readability over 2336*8c35d5eeSXin Lifully-qualified names. Follow the same rules as <code>goog.require</code>s 2337*8c35d5eeSXin Li(<a href="#file-goog-require">??</a>), maintaining the last part of the aliased name. 2338*8c35d5eeSXin LiAliases may also be used within functions. Aliases must be <code>const</code>.</p> 2339*8c35d5eeSXin Li 2340*8c35d5eeSXin Li<p>Examples:</p> 2341*8c35d5eeSXin Li 2342*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const staticHelper = importedNamespace.staticHelper; 2343*8c35d5eeSXin Liconst CONSTANT_NAME = ImportedClass.CONSTANT_NAME; 2344*8c35d5eeSXin Liconst {assert, assertInstanceof} = asserts; 2345*8c35d5eeSXin Li</code></pre> 2346*8c35d5eeSXin Li 2347*8c35d5eeSXin Li<h4 id="naming-non-constant-field-names">6.2.6 Non-constant field names</h4> 2348*8c35d5eeSXin Li 2349*8c35d5eeSXin Li<p>Non-constant field names (static or otherwise) are written in <code>lowerCamelCase</code>, 2350*8c35d5eeSXin Liwith a trailing underscore for private fields.</p> 2351*8c35d5eeSXin Li 2352*8c35d5eeSXin Li<p>These names are typically nouns or noun phrases. For example, <code>computedValues</code> 2353*8c35d5eeSXin Lior <code>index_</code>.</p> 2354*8c35d5eeSXin Li 2355*8c35d5eeSXin Li<h4 id="naming-parameter-names">6.2.7 Parameter names</h4> 2356*8c35d5eeSXin Li 2357*8c35d5eeSXin Li<p>Parameter names are written in <code>lowerCamelCase</code>. Note that this applies even if 2358*8c35d5eeSXin Lithe parameter expects a constructor.</p> 2359*8c35d5eeSXin Li 2360*8c35d5eeSXin Li<p>One-character parameter names should not be used in public methods.</p> 2361*8c35d5eeSXin Li 2362*8c35d5eeSXin Li<p><strong>Exception</strong>: When required by a third-party framework, parameter names may 2363*8c35d5eeSXin Libegin with a <code>$</code>. This exception does not apply to any other identifiers 2364*8c35d5eeSXin Li(e.g. local variables or properties).</p> 2365*8c35d5eeSXin Li 2366*8c35d5eeSXin Li<h4 id="naming-local-variable-names">6.2.8 Local variable names</h4> 2367*8c35d5eeSXin Li 2368*8c35d5eeSXin Li<p>Local variable names are written in <code>lowerCamelCase</code>, except for module-local 2369*8c35d5eeSXin Li(top-level) constants, as described above. Constants in function scopes are 2370*8c35d5eeSXin Listill named in <code>lowerCamelCase</code>. Note that <code>lowerCamelCase</code> is used 2371*8c35d5eeSXin Lieven if the variable holds a constructor.</p> 2372*8c35d5eeSXin Li 2373*8c35d5eeSXin Li<h4 id="naming-template-parameter-names">6.2.9 Template parameter names</h4> 2374*8c35d5eeSXin Li 2375*8c35d5eeSXin Li<p>Template parameter names should be concise, single-word or single-letter 2376*8c35d5eeSXin Liidentifiers, and must be all-caps, such as <code>TYPE</code> or <code>THIS</code>.</p> 2377*8c35d5eeSXin Li 2378*8c35d5eeSXin Li<h4 id="naming-module-local-names">6.2.10 Module-local names</h4> 2379*8c35d5eeSXin Li 2380*8c35d5eeSXin Li<p>Module-local names that are not exported are implicitly private. They are not 2381*8c35d5eeSXin Limarked <code>@private</code> and do not end in an underscore. This applies to classes, 2382*8c35d5eeSXin Lifunctions, variables, constants, enums, and other module-local identifiers.</p> 2383*8c35d5eeSXin Li 2384*8c35d5eeSXin Li<h3 id="naming-camel-case-defined">6.3 Camel case: defined</h3> 2385*8c35d5eeSXin Li 2386*8c35d5eeSXin Li<p>Sometimes there is more than one reasonable way to convert an English phrase 2387*8c35d5eeSXin Liinto camel case, such as when acronyms or unusual constructs like <q>IPv6</q> or 2388*8c35d5eeSXin Li<q>iOS</q> are present. To improve predictability, Google Style specifies the 2389*8c35d5eeSXin Lifollowing (nearly) deterministic scheme.</p> 2390*8c35d5eeSXin Li 2391*8c35d5eeSXin Li<p>Beginning with the prose form of the name:</p> 2392*8c35d5eeSXin Li 2393*8c35d5eeSXin Li<ol> 2394*8c35d5eeSXin Li<li>Convert the phrase to plain ASCII and remove any apostrophes. For example, 2395*8c35d5eeSXin Li<q>Müller's algorithm</q> might become <q>Muellers algorithm</q>.</li> 2396*8c35d5eeSXin Li<li>Divide this result into words, splitting on spaces and any remaining 2397*8c35d5eeSXin Lipunctuation (typically hyphens). 2398*8c35d5eeSXin Li<ol> 2399*8c35d5eeSXin Li<li>Recommended: if any word already has a conventional camel case 2400*8c35d5eeSXin Liappearance in common usage, split this into its constituent parts (e.g., 2401*8c35d5eeSXin Li<q>AdWords</q> becomes <q>ad words</q>). Note that a word such as <q>iOS</q> is not 2402*8c35d5eeSXin Lireally in camel case per se; it defies any convention, so this 2403*8c35d5eeSXin Lirecommendation does not apply.</li> 2404*8c35d5eeSXin Li</ol></li> 2405*8c35d5eeSXin Li<li>Now lowercase everything (including acronyms), then uppercase only the first 2406*8c35d5eeSXin Licharacter of: 2407*8c35d5eeSXin Li<ol> 2408*8c35d5eeSXin Li<li>… each word, to yield upper camel case, or</li> 2409*8c35d5eeSXin Li<li>… each word except the first, to yield lower camel case</li> 2410*8c35d5eeSXin Li</ol></li> 2411*8c35d5eeSXin Li<li>Finally, join all the words into a single identifier.</li> 2412*8c35d5eeSXin Li</ol> 2413*8c35d5eeSXin Li 2414*8c35d5eeSXin Li<p>Note that the casing of the original words is almost entirely disregarded.</p> 2415*8c35d5eeSXin Li 2416*8c35d5eeSXin Li<p>Examples:</p> 2417*8c35d5eeSXin Li 2418*8c35d5eeSXin Li<table> 2419*8c35d5eeSXin Li<thead> 2420*8c35d5eeSXin Li<tr> 2421*8c35d5eeSXin Li<th style="text-align: center">Prose form</th> 2422*8c35d5eeSXin Li<th style="text-align: center">Correct</th> 2423*8c35d5eeSXin Li<th style="text-align: center">Incorrect</th> 2424*8c35d5eeSXin Li</tr> 2425*8c35d5eeSXin Li</thead> 2426*8c35d5eeSXin Li 2427*8c35d5eeSXin Li<tbody> 2428*8c35d5eeSXin Li<tr> 2429*8c35d5eeSXin Li<td style="text-align: center"><q>XML HTTP request</q></td> 2430*8c35d5eeSXin Li<td style="text-align: center">XmlHttpRequest</td> 2431*8c35d5eeSXin Li<td style="text-align: center">XMLHTTPRequest</td> 2432*8c35d5eeSXin Li</tr> 2433*8c35d5eeSXin Li<tr> 2434*8c35d5eeSXin Li<td style="text-align: center"><q>new customer ID</q></td> 2435*8c35d5eeSXin Li<td style="text-align: center">newCustomerId</td> 2436*8c35d5eeSXin Li<td style="text-align: center">newCustomerID</td> 2437*8c35d5eeSXin Li</tr> 2438*8c35d5eeSXin Li<tr> 2439*8c35d5eeSXin Li<td style="text-align: center"><q>inner stopwatch</q></td> 2440*8c35d5eeSXin Li<td style="text-align: center">innerStopwatch</td> 2441*8c35d5eeSXin Li<td style="text-align: center">innerStopWatch</td> 2442*8c35d5eeSXin Li</tr> 2443*8c35d5eeSXin Li<tr> 2444*8c35d5eeSXin Li<td style="text-align: center"><q>supports IPv6 on iOS?</q></td> 2445*8c35d5eeSXin Li<td style="text-align: center">supportsIpv6OnIos</td> 2446*8c35d5eeSXin Li<td style="text-align: center">supportsIPv6OnIOS</td> 2447*8c35d5eeSXin Li</tr> 2448*8c35d5eeSXin Li<tr> 2449*8c35d5eeSXin Li<td style="text-align: center"><q>YouTube importer</q></td> 2450*8c35d5eeSXin Li<td style="text-align: center">YouTubeImporter</td> 2451*8c35d5eeSXin Li<td style="text-align: center">YoutubeImporter*</td> 2452*8c35d5eeSXin Li</tr> 2453*8c35d5eeSXin Li</tbody> 2454*8c35d5eeSXin Li</table> 2455*8c35d5eeSXin Li 2456*8c35d5eeSXin Li<p>*Acceptable, but not recommended.</p> 2457*8c35d5eeSXin Li 2458*8c35d5eeSXin Li<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 checkNonempty and checkNonEmpty are likewise both correct.</p> 2459*8c35d5eeSXin Li 2460*8c35d5eeSXin Li<h2 id="jsdoc">7 JSDoc</h2> 2461*8c35d5eeSXin Li 2462*8c35d5eeSXin Li<p><a href="https://developers.google.com/closure/compiler/docs/js-for-compiler">JSDoc</a> is used on all classes, fields, and methods.</p> 2463*8c35d5eeSXin Li 2464*8c35d5eeSXin Li<h3 id="jsdoc-general-form">7.1 General form</h3> 2465*8c35d5eeSXin Li 2466*8c35d5eeSXin Li<p>The basic formatting of JSDoc blocks is as seen in this example:</p> 2467*8c35d5eeSXin Li 2468*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 2469*8c35d5eeSXin Li * Multiple lines of JSDoc text are written here, 2470*8c35d5eeSXin Li * wrapped normally. 2471*8c35d5eeSXin Li * @param {number} arg A number to do something to. 2472*8c35d5eeSXin Li */ 2473*8c35d5eeSXin Lifunction doSomething(arg) { … } 2474*8c35d5eeSXin Li</code></pre> 2475*8c35d5eeSXin Li 2476*8c35d5eeSXin Li<p>or in this single-line example:</p> 2477*8c35d5eeSXin Li 2478*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @const @private {!Foo} A short bit of JSDoc. */ 2479*8c35d5eeSXin Lithis.foo_ = foo; 2480*8c35d5eeSXin Li</code></pre> 2481*8c35d5eeSXin Li 2482*8c35d5eeSXin Li<p>If a single-line comment overflows into multiple lines, it must use the 2483*8c35d5eeSXin Limulti-line style with <code>/**</code> and <code>*/</code> on their own lines.</p> 2484*8c35d5eeSXin Li 2485*8c35d5eeSXin Li<p>Many tools extract metadata from JSDoc comments to perform code validation and 2486*8c35d5eeSXin Lioptimization. As such, these comments <strong>must</strong> be well-formed.</p> 2487*8c35d5eeSXin Li 2488*8c35d5eeSXin Li<h3 id="jsdoc-markdown">7.2 Markdown</h3> 2489*8c35d5eeSXin Li 2490*8c35d5eeSXin Li<p>JSDoc is written in Markdown, though it may include HTML when necessary.</p> 2491*8c35d5eeSXin Li 2492*8c35d5eeSXin Li<p>Note that tools that automatically extract JSDoc (e.g. <a href="https://github.com/jleyba/js-dossier">JsDossier</a>) will often 2493*8c35d5eeSXin Liignore plain text formatting, so if you did this:</p> 2494*8c35d5eeSXin Li 2495*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">/** 2496*8c35d5eeSXin Li * Computes weight based on three factors: 2497*8c35d5eeSXin Li * items sent 2498*8c35d5eeSXin Li * items received 2499*8c35d5eeSXin Li * last timestamp 2500*8c35d5eeSXin Li */ 2501*8c35d5eeSXin Li</code></pre> 2502*8c35d5eeSXin Li 2503*8c35d5eeSXin Li<p>it would come out like this:</p> 2504*8c35d5eeSXin Li 2505*8c35d5eeSXin Li<pre><code>Computes weight based on three factors: items sent items received last timestamp 2506*8c35d5eeSXin Li</code></pre> 2507*8c35d5eeSXin Li 2508*8c35d5eeSXin Li<p>Instead, write a Markdown list:</p> 2509*8c35d5eeSXin Li 2510*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 2511*8c35d5eeSXin Li * Computes weight based on three factors: 2512*8c35d5eeSXin Li * 2513*8c35d5eeSXin Li * - items sent 2514*8c35d5eeSXin Li * - items received 2515*8c35d5eeSXin Li * - last timestamp 2516*8c35d5eeSXin Li */ 2517*8c35d5eeSXin Li</code></pre> 2518*8c35d5eeSXin Li 2519*8c35d5eeSXin Li<h3 id="jsdoc-tags">7.3 JSDoc tags</h3> 2520*8c35d5eeSXin Li 2521*8c35d5eeSXin Li<p>Google style allows a subset of JSDoc tags. See 2522*8c35d5eeSXin Li<a href="#appendices-jsdoc-tag-reference">??</a> for the complete list. Most tags must 2523*8c35d5eeSXin Lioccupy their own line, with the tag at the beginning of the line.</p> 2524*8c35d5eeSXin Li 2525*8c35d5eeSXin Li<p>Disallowed:</p> 2526*8c35d5eeSXin Li 2527*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">/** 2528*8c35d5eeSXin Li * The "param" tag must occupy its own line and may not be combined. 2529*8c35d5eeSXin Li * @param {number} left @param {number} right 2530*8c35d5eeSXin Li */ 2531*8c35d5eeSXin Lifunction add(left, right) { ... } 2532*8c35d5eeSXin Li</code></pre> 2533*8c35d5eeSXin Li 2534*8c35d5eeSXin Li<p>Simple tags that do not require any additional data (such as <code>@private</code>, 2535*8c35d5eeSXin Li<code>@const</code>, <code>@final</code>, <code>@export</code>) may be combined onto the same line, along with an 2536*8c35d5eeSXin Lioptional type when appropriate.</p> 2537*8c35d5eeSXin Li 2538*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 2539*8c35d5eeSXin Li * Place more complex annotations (like "implements" and "template") 2540*8c35d5eeSXin Li * on their own lines. Multiple simple tags (like "export" and "final") 2541*8c35d5eeSXin Li * may be combined in one line. 2542*8c35d5eeSXin Li * @export @final 2543*8c35d5eeSXin Li * @implements {Iterable<TYPE>} 2544*8c35d5eeSXin Li * @template TYPE 2545*8c35d5eeSXin Li */ 2546*8c35d5eeSXin Liclass MyClass { 2547*8c35d5eeSXin Li /** 2548*8c35d5eeSXin Li * @param {!ObjType} obj Some object. 2549*8c35d5eeSXin Li * @param {number=} num An optional number. 2550*8c35d5eeSXin Li */ 2551*8c35d5eeSXin Li constructor(obj, num = 42) { 2552*8c35d5eeSXin Li /** @private @const {!Array<!ObjType|number>} */ 2553*8c35d5eeSXin Li this.data_ = [obj, num]; 2554*8c35d5eeSXin Li } 2555*8c35d5eeSXin Li} 2556*8c35d5eeSXin Li</code></pre> 2557*8c35d5eeSXin Li 2558*8c35d5eeSXin Li<p>There is no hard rule for when to combine tags, or in which order, but be 2559*8c35d5eeSXin Liconsistent.</p> 2560*8c35d5eeSXin Li 2561*8c35d5eeSXin Li<p>For general information about annotating types in JavaScript see 2562*8c35d5eeSXin Li<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 2563*8c35d5eeSXin LiSystem</a>.</p> 2564*8c35d5eeSXin Li 2565*8c35d5eeSXin Li<h3 id="jsdoc-line-wrapping">7.4 Line wrapping</h3> 2566*8c35d5eeSXin Li 2567*8c35d5eeSXin Li<p>Line-wrapped block tags are indented four spaces. Wrapped description text may 2568*8c35d5eeSXin Libe lined up with the description on previous lines, but this horizontal 2569*8c35d5eeSXin Lialignment is discouraged.</p> 2570*8c35d5eeSXin Li 2571*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 2572*8c35d5eeSXin Li * Illustrates line wrapping for long param/return descriptions. 2573*8c35d5eeSXin Li * @param {string} foo This is a param with a description too long to fit in 2574*8c35d5eeSXin Li * one line. 2575*8c35d5eeSXin Li * @return {number} This returns something that has a description too long to 2576*8c35d5eeSXin Li * fit in one line. 2577*8c35d5eeSXin Li */ 2578*8c35d5eeSXin Liexports.method = function(foo) { 2579*8c35d5eeSXin Li return 5; 2580*8c35d5eeSXin Li}; 2581*8c35d5eeSXin Li</code></pre> 2582*8c35d5eeSXin Li 2583*8c35d5eeSXin Li<p>Do not indent when wrapping a <code>@desc</code> or <code>@fileoverview</code> description.</p> 2584*8c35d5eeSXin Li 2585*8c35d5eeSXin Li<h3 id="jsdoc-top-file-level-comments">7.5 Top/file-level comments</h3> 2586*8c35d5eeSXin Li 2587*8c35d5eeSXin Li<p>A file may have a top-level file overview. A copyright notice , author information, and 2588*8c35d5eeSXin Lidefault <a href="#jsdoc-visibility-annotations">visibility level</a> are optional. File overviews are generally recommended whenever a 2589*8c35d5eeSXin Lifile consists of more than a single class definition. The top level comment is 2590*8c35d5eeSXin Lidesigned to orient readers unfamiliar with the code to what is in this file. If 2591*8c35d5eeSXin Lipresent, it may provide a description of the file's contents and any 2592*8c35d5eeSXin Lidependencies or compatibility information. Wrapped lines are not indented.</p> 2593*8c35d5eeSXin Li 2594*8c35d5eeSXin Li<p>Example:</p> 2595*8c35d5eeSXin Li 2596*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 2597*8c35d5eeSXin Li * @fileoverview Description of file, its uses and information 2598*8c35d5eeSXin Li * about its dependencies. 2599*8c35d5eeSXin Li * @package 2600*8c35d5eeSXin Li */ 2601*8c35d5eeSXin Li</code></pre> 2602*8c35d5eeSXin Li 2603*8c35d5eeSXin Li<h3 id="jsdoc-class-comments">7.6 Class comments</h3> 2604*8c35d5eeSXin Li 2605*8c35d5eeSXin Li<p>Classes, interfaces and records must be documented with a description and any 2606*8c35d5eeSXin Litemplate parameters, implemented interfaces, visibility, or other appropriate 2607*8c35d5eeSXin Litags. The class description should provide the reader with enough information to 2608*8c35d5eeSXin Liknow how and when to use the class, as well as any additional considerations 2609*8c35d5eeSXin Linecessary to correctly use the class. Textual descriptions may be omitted on the 2610*8c35d5eeSXin Liconstructor. <code>@constructor</code> and <code>@extends</code> annotations are not used with the 2611*8c35d5eeSXin Li<code>class</code> keyword unless the class is being used to declare an <code>@interface</code> or 2612*8c35d5eeSXin Liit extends a generic class.</p> 2613*8c35d5eeSXin Li 2614*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 2615*8c35d5eeSXin Li * A fancier event target that does cool things. 2616*8c35d5eeSXin Li * @implements {Iterable<string>} 2617*8c35d5eeSXin Li */ 2618*8c35d5eeSXin Liclass MyFancyTarget extends EventTarget { 2619*8c35d5eeSXin Li /** 2620*8c35d5eeSXin Li * @param {string} arg1 An argument that makes this more interesting. 2621*8c35d5eeSXin Li * @param {!Array<number>} arg2 List of numbers to be processed. 2622*8c35d5eeSXin Li */ 2623*8c35d5eeSXin Li constructor(arg1, arg2) { 2624*8c35d5eeSXin Li // ... 2625*8c35d5eeSXin Li } 2626*8c35d5eeSXin Li}; 2627*8c35d5eeSXin Li 2628*8c35d5eeSXin Li/** 2629*8c35d5eeSXin Li * Records are also helpful. 2630*8c35d5eeSXin Li * @extends {Iterator<TYPE>} 2631*8c35d5eeSXin Li * @record 2632*8c35d5eeSXin Li * @template TYPE 2633*8c35d5eeSXin Li */ 2634*8c35d5eeSXin Liclass Listable { 2635*8c35d5eeSXin Li /** @return {TYPE} The next item in line to be returned. */ 2636*8c35d5eeSXin Li next() {} 2637*8c35d5eeSXin Li} 2638*8c35d5eeSXin Li</code></pre> 2639*8c35d5eeSXin Li 2640*8c35d5eeSXin Li<h3 id="jsdoc-enum-and-typedef-comments">7.7 Enum and typedef comments</h3> 2641*8c35d5eeSXin Li 2642*8c35d5eeSXin Li<p>All enums and typedefs must be documented with appropriate JSDoc tags 2643*8c35d5eeSXin Li(<code>@typedef</code> or <code>@enum</code>) on the preceding line. Public enums and typedefs must 2644*8c35d5eeSXin Lialso have a description. Individual enum items may be documented with a JSDoc 2645*8c35d5eeSXin Licomment on the preceding line.</p> 2646*8c35d5eeSXin Li 2647*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 2648*8c35d5eeSXin Li * A useful type union, which is reused often. 2649*8c35d5eeSXin Li * @typedef {!Bandersnatch|!BandersnatchType} 2650*8c35d5eeSXin Li */ 2651*8c35d5eeSXin Lilet CoolUnionType; 2652*8c35d5eeSXin Li 2653*8c35d5eeSXin Li 2654*8c35d5eeSXin Li/** 2655*8c35d5eeSXin Li * Types of bandersnatches. 2656*8c35d5eeSXin Li * @enum {string} 2657*8c35d5eeSXin Li */ 2658*8c35d5eeSXin Liconst BandersnatchType = { 2659*8c35d5eeSXin Li /** This kind is really frumious. */ 2660*8c35d5eeSXin Li FRUMIOUS: 'frumious', 2661*8c35d5eeSXin Li /** The less-frumious kind. */ 2662*8c35d5eeSXin Li MANXOME: 'manxome', 2663*8c35d5eeSXin Li}; 2664*8c35d5eeSXin Li</code></pre> 2665*8c35d5eeSXin Li 2666*8c35d5eeSXin Li<p>Typedefs are useful for defining short record types, or aliases for unions, 2667*8c35d5eeSXin Licomplex functions, or generic types. 2668*8c35d5eeSXin LiTypedefs should be avoided for record types with many fields, since they do not 2669*8c35d5eeSXin Liallow documenting individual fields, nor using templates or recursive 2670*8c35d5eeSXin Lireferences. 2671*8c35d5eeSXin LiFor large record types, prefer <code>@record</code>.</p> 2672*8c35d5eeSXin Li 2673*8c35d5eeSXin Li<h3 id="jsdoc-method-and-function-comments">7.8 Method and function comments</h3> 2674*8c35d5eeSXin Li 2675*8c35d5eeSXin Li<p>In methods and named functions, parameter and return types must be documented, 2676*8c35d5eeSXin Liexcept in the case of same-signature <code>@override</code>s, where all types are omitted. 2677*8c35d5eeSXin LiThe <code>this</code> type should be documented when necessary. Return type may be omitted 2678*8c35d5eeSXin Liif the function has no non-empty <code>return</code> statements.</p> 2679*8c35d5eeSXin Li 2680*8c35d5eeSXin Li<p>Method, parameter, and return descriptions (but not types) may be omitted if 2681*8c35d5eeSXin Lithey are obvious from the rest of the method’s JSDoc or from its signature.</p> 2682*8c35d5eeSXin Li 2683*8c35d5eeSXin Li<p>Method descriptions begin with a verb phrase that describes what the method 2684*8c35d5eeSXin Lidoes. This phrase is not an imperative sentence, but instead is written in the 2685*8c35d5eeSXin Lithird person, as if there is an implied <q>This method ...</q> before it.</p> 2686*8c35d5eeSXin Li 2687*8c35d5eeSXin Li<p>If a method overrides a superclass method, it must include an <code>@override</code> 2688*8c35d5eeSXin Liannotation. Overridden methods inherit all JSDoc annotations from the super 2689*8c35d5eeSXin Liclass method (including visibility annotations) and they should be omitted in 2690*8c35d5eeSXin Lithe overridden method. However, if any type is refined in type annotations, all 2691*8c35d5eeSXin Li<code>@param</code> and <code>@return</code> annotations must be specified explicitly.</p> 2692*8c35d5eeSXin Li 2693*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** A class that does something. */ 2694*8c35d5eeSXin Liclass SomeClass extends SomeBaseClass { 2695*8c35d5eeSXin Li /** 2696*8c35d5eeSXin Li * Operates on an instance of MyClass and returns something. 2697*8c35d5eeSXin Li * @param {!MyClass} obj An object that for some reason needs detailed 2698*8c35d5eeSXin Li * explanation that spans multiple lines. 2699*8c35d5eeSXin Li * @param {!OtherClass} obviousOtherClass 2700*8c35d5eeSXin Li * @return {boolean} Whether something occurred. 2701*8c35d5eeSXin Li */ 2702*8c35d5eeSXin Li someMethod(obj, obviousOtherClass) { ... } 2703*8c35d5eeSXin Li 2704*8c35d5eeSXin Li /** @override */ 2705*8c35d5eeSXin Li overriddenMethod(param) { ... } 2706*8c35d5eeSXin Li} 2707*8c35d5eeSXin Li 2708*8c35d5eeSXin Li/** 2709*8c35d5eeSXin Li * Demonstrates how top-level functions follow the same rules. This one 2710*8c35d5eeSXin Li * makes an array. 2711*8c35d5eeSXin Li * @param {TYPE} arg 2712*8c35d5eeSXin Li * @return {!Array<TYPE>} 2713*8c35d5eeSXin Li * @template TYPE 2714*8c35d5eeSXin Li */ 2715*8c35d5eeSXin Lifunction makeArray(arg) { ... } 2716*8c35d5eeSXin Li</code></pre> 2717*8c35d5eeSXin Li 2718*8c35d5eeSXin Li<p>If you only need to document the param and return types of a function, you may 2719*8c35d5eeSXin Lioptionally use inline JSDocs in the function's signature. These inline JSDocs 2720*8c35d5eeSXin Lispecify the return and param types without tags.</p> 2721*8c35d5eeSXin Li 2722*8c35d5eeSXin Li<pre><code class="language-js prettyprint">function /** string */ foo(/** number */ arg) {...} 2723*8c35d5eeSXin Li</code></pre> 2724*8c35d5eeSXin Li 2725*8c35d5eeSXin Li<p>If you need descriptions or tags, use a single JSDoc comment above the method. 2726*8c35d5eeSXin LiFor example, methods which return values need a <code>@return</code> tag.</p> 2727*8c35d5eeSXin Li 2728*8c35d5eeSXin Li<pre><code class="language-js prettyprint">class MyClass { 2729*8c35d5eeSXin Li /** 2730*8c35d5eeSXin Li * @param {number} arg 2731*8c35d5eeSXin Li * @return {string} 2732*8c35d5eeSXin Li */ 2733*8c35d5eeSXin Li bar(arg) {...} 2734*8c35d5eeSXin Li} 2735*8c35d5eeSXin Li</code></pre> 2736*8c35d5eeSXin Li 2737*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">// Illegal inline JSDocs. 2738*8c35d5eeSXin Li 2739*8c35d5eeSXin Liclass MyClass { 2740*8c35d5eeSXin Li /** @return {string} */ foo() {...} 2741*8c35d5eeSXin Li} 2742*8c35d5eeSXin Li 2743*8c35d5eeSXin Li/** Function description. */ bar() {...} 2744*8c35d5eeSXin Li</code></pre> 2745*8c35d5eeSXin Li 2746*8c35d5eeSXin Li 2747*8c35d5eeSXin Li 2748*8c35d5eeSXin Li<p>In anonymous functions annotations are generally optional. If the automatic type 2749*8c35d5eeSXin Liinference is insufficient or explicit annotation improves readability, then 2750*8c35d5eeSXin Liannotate param and return types like this:</p> 2751*8c35d5eeSXin Li 2752*8c35d5eeSXin Li<pre><code class="language-js prettyprint">promise.then( 2753*8c35d5eeSXin Li /** @return {string} */ 2754*8c35d5eeSXin Li (/** !Array<string> */ items) => { 2755*8c35d5eeSXin Li doSomethingWith(items); 2756*8c35d5eeSXin Li return items[0]; 2757*8c35d5eeSXin Li }); 2758*8c35d5eeSXin Li</code></pre> 2759*8c35d5eeSXin Li 2760*8c35d5eeSXin Li<p>For function type expressions, see <a href="#jsdoc-function-types">??</a>.</p> 2761*8c35d5eeSXin Li 2762*8c35d5eeSXin Li<h3 id="jsdoc-property-comments">7.9 Property comments</h3> 2763*8c35d5eeSXin Li 2764*8c35d5eeSXin Li<p>Property types must be documented. The description may be omitted for private 2765*8c35d5eeSXin Liproperties, if name and type provide enough documentation for understanding the 2766*8c35d5eeSXin Licode.</p> 2767*8c35d5eeSXin Li 2768*8c35d5eeSXin Li<p>Publicly exported constants are commented the same way as properties.</p> 2769*8c35d5eeSXin Li 2770*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** My class. */ 2771*8c35d5eeSXin Liclass MyClass { 2772*8c35d5eeSXin Li /** @param {string=} someString */ 2773*8c35d5eeSXin Li constructor(someString = 'default string') { 2774*8c35d5eeSXin Li /** @private @const {string} */ 2775*8c35d5eeSXin Li this.someString_ = someString; 2776*8c35d5eeSXin Li 2777*8c35d5eeSXin Li /** @private @const {!OtherType} */ 2778*8c35d5eeSXin Li this.someOtherThing_ = functionThatReturnsAThing(); 2779*8c35d5eeSXin Li 2780*8c35d5eeSXin Li /** 2781*8c35d5eeSXin Li * Maximum number of things per pane. 2782*8c35d5eeSXin Li * @type {number} 2783*8c35d5eeSXin Li */ 2784*8c35d5eeSXin Li this.someProperty = 4; 2785*8c35d5eeSXin Li } 2786*8c35d5eeSXin Li} 2787*8c35d5eeSXin Li 2788*8c35d5eeSXin Li/** 2789*8c35d5eeSXin Li * The number of times we'll try before giving up. 2790*8c35d5eeSXin Li * @const {number} 2791*8c35d5eeSXin Li */ 2792*8c35d5eeSXin LiMyClass.RETRY_COUNT = 33; 2793*8c35d5eeSXin Li</code></pre> 2794*8c35d5eeSXin Li 2795*8c35d5eeSXin Li<h3 id="jsdoc-type-annotations">7.10 Type annotations</h3> 2796*8c35d5eeSXin Li 2797*8c35d5eeSXin Li<p>Type annotations are found on <code>@param</code>, <code>@return</code>, <code>@this</code>, and <code>@type</code> tags, 2798*8c35d5eeSXin Liand optionally on <code>@const</code>, <code>@export</code>, and any visibility tags. Type 2799*8c35d5eeSXin Liannotations attached to JSDoc tags must always be enclosed in braces.</p> 2800*8c35d5eeSXin Li 2801*8c35d5eeSXin Li<h4 id="jsdoc-nullability">7.10.1 Nullability</h4> 2802*8c35d5eeSXin Li 2803*8c35d5eeSXin Li<p>The type system defines modifiers <code>!</code> and <code>?</code> for non-null and nullable, 2804*8c35d5eeSXin Lirespectively. These modifiers must precede the type.</p> 2805*8c35d5eeSXin Li 2806*8c35d5eeSXin Li<p>Nullability modifiers have different requirements for different types, which 2807*8c35d5eeSXin Lifall into two broad categories:</p> 2808*8c35d5eeSXin Li 2809*8c35d5eeSXin Li<ol> 2810*8c35d5eeSXin Li<li>Type annotations for primitives (<code>string</code>, <code>number</code>, <code>boolean</code>, <code>symbol</code>, 2811*8c35d5eeSXin Li<code>undefined</code>, <code>null</code>) and literals (<code>{function(...): ...}</code> and <code>{{foo: 2812*8c35d5eeSXin Listring...}}</code>) are always non-nullable by default. Use the <code>?</code> modifier to 2813*8c35d5eeSXin Limake it nullable, but omit the redundant <code>!</code>.</li> 2814*8c35d5eeSXin Li<li>Reference types (generally, anything in <code>UpperCamelCase</code>, including 2815*8c35d5eeSXin Li<code>some.namespace.ReferenceType</code>) refer to a class, enum, record, or typedef 2816*8c35d5eeSXin Lidefined elsewhere. Since these types may or may not be nullable, it is 2817*8c35d5eeSXin Liimpossible to tell from the name alone whether it is nullable or not. Always 2818*8c35d5eeSXin Liuse explicit <code>?</code> and <code>!</code> modifiers for these types to prevent ambiguity at 2819*8c35d5eeSXin Liuse sites.</li> 2820*8c35d5eeSXin Li</ol> 2821*8c35d5eeSXin Li 2822*8c35d5eeSXin Li<p>Bad:</p> 2823*8c35d5eeSXin Li 2824*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">const /** MyObject */ myObject = null; // Non-primitive types must be annotated. 2825*8c35d5eeSXin Liconst /** !number */ someNum = 5; // Primitives are non-nullable by default. 2826*8c35d5eeSXin Liconst /** number? */ someNullableNum = null; // ? should precede the type. 2827*8c35d5eeSXin Liconst /** !{foo: string, bar: number} */ record = ...; // Already non-nullable. 2828*8c35d5eeSXin Liconst /** MyTypeDef */ def = ...; // Not sure if MyTypeDef is nullable. 2829*8c35d5eeSXin Li 2830*8c35d5eeSXin Li// Not sure if object (nullable), enum (non-nullable, unless otherwise 2831*8c35d5eeSXin Li// specified), or typedef (depends on definition). 2832*8c35d5eeSXin Liconst /** SomeCamelCaseName */ n = ...; 2833*8c35d5eeSXin Li</code></pre> 2834*8c35d5eeSXin Li 2835*8c35d5eeSXin Li<p>Good:</p> 2836*8c35d5eeSXin Li 2837*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const /** ?MyObject */ myObject = null; 2838*8c35d5eeSXin Liconst /** number */ someNum = 5; 2839*8c35d5eeSXin Liconst /** ?number */ someNullableNum = null; 2840*8c35d5eeSXin Liconst /** {foo: string, bar: number} */ record = ...; 2841*8c35d5eeSXin Liconst /** !MyTypeDef */ def = ...; 2842*8c35d5eeSXin Liconst /** ?SomeCamelCaseName */ n = ...; 2843*8c35d5eeSXin Li</code></pre> 2844*8c35d5eeSXin Li 2845*8c35d5eeSXin Li<h4 id="jsdoc-type-casts">7.10.2 Type Casts</h4> 2846*8c35d5eeSXin Li 2847*8c35d5eeSXin Li<p>In cases where the compiler doesn't accurately infer the type of an expression, 2848*8c35d5eeSXin Liand the assertion functions in 2849*8c35d5eeSXin Li<a href="https://google.github.io/closure-library/api/goog.asserts.html">goog.asserts</a> 2850*8c35d5eeSXin Licannot remedy it , it is possible to 2851*8c35d5eeSXin Litighten the type by adding a type annotation comment and enclosing the 2852*8c35d5eeSXin Liexpression in parentheses. Note that the parentheses are required.</p> 2853*8c35d5eeSXin Li 2854*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @type {number} */ (x) 2855*8c35d5eeSXin Li</code></pre> 2856*8c35d5eeSXin Li 2857*8c35d5eeSXin Li<h4 id="jsdoc-template-parameter-types">7.10.3 Template Parameter Types</h4> 2858*8c35d5eeSXin Li 2859*8c35d5eeSXin Li<p>Always specify template parameters. This way compiler can do a better job and it 2860*8c35d5eeSXin Limakes it easier for readers to understand what code does.</p> 2861*8c35d5eeSXin Li 2862*8c35d5eeSXin Li<p>Bad:</p> 2863*8c35d5eeSXin Li 2864*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">const /** !Object */ users = {}; 2865*8c35d5eeSXin Liconst /** !Array */ books = []; 2866*8c35d5eeSXin Liconst /** !Promise */ response = ...; 2867*8c35d5eeSXin Li</code></pre> 2868*8c35d5eeSXin Li 2869*8c35d5eeSXin Li<p>Good:</p> 2870*8c35d5eeSXin Li 2871*8c35d5eeSXin Li<pre><code class="language-js prettyprint">const /** !Object<string, !User> */ users = {}; 2872*8c35d5eeSXin Liconst /** !Array<string> */ books = []; 2873*8c35d5eeSXin Liconst /** !Promise<!Response> */ response = ...; 2874*8c35d5eeSXin Li 2875*8c35d5eeSXin Liconst /** !Promise<undefined> */ thisPromiseReturnsNothingButParameterIsStillUseful = ...; 2876*8c35d5eeSXin Liconst /** !Object<string, *> */ mapOfEverything = {}; 2877*8c35d5eeSXin Li</code></pre> 2878*8c35d5eeSXin Li 2879*8c35d5eeSXin Li<p>Cases when template parameters should not be used:</p> 2880*8c35d5eeSXin Li 2881*8c35d5eeSXin Li<ul> 2882*8c35d5eeSXin Li<li><code>Object</code> is used for type hierarchy and not as map-like structure.</li> 2883*8c35d5eeSXin Li</ul> 2884*8c35d5eeSXin Li 2885*8c35d5eeSXin Li<h4 id="jsdoc-function-types">7.10.4 Function type expressions</h4> 2886*8c35d5eeSXin Li 2887*8c35d5eeSXin Li<p><strong>Terminology Note</strong>: <em>function type expression</em> refers to a type annotation for 2888*8c35d5eeSXin Lifunction types with the keyword <code>function</code> in the annotation (see examples 2889*8c35d5eeSXin Libelow).</p> 2890*8c35d5eeSXin Li 2891*8c35d5eeSXin Li<p>Where the function definition is given, do not use a function type expression. 2892*8c35d5eeSXin LiSpecify parameter and return types with <code>@param</code> and <code>@return</code>, or with inline 2893*8c35d5eeSXin Liannotations (see <a href="#jsdoc-method-and-function-comments">??</a>). This includes 2894*8c35d5eeSXin Lianonymous functions and functions defined and assigned to a const (where the 2895*8c35d5eeSXin Lifunction jsdoc appears above the whole assignment expression).</p> 2896*8c35d5eeSXin Li 2897*8c35d5eeSXin Li<p>Function type expressions are needed, for example, inside <code>@typedef</code>, <code>@param</code> 2898*8c35d5eeSXin Lior <code>@return</code>. Use it also for variables or properties of function type, if they 2899*8c35d5eeSXin Liare not immediately initialized with the function definition.</p> 2900*8c35d5eeSXin Li 2901*8c35d5eeSXin Li<pre><code class="language-js prettyprint"> /** @private {function(string): string} */ 2902*8c35d5eeSXin Li this.idGenerator_ = googFunctions.identity; 2903*8c35d5eeSXin Li</code></pre> 2904*8c35d5eeSXin Li 2905*8c35d5eeSXin Li<p>When using a function type expression, always specify the return type 2906*8c35d5eeSXin Liexplicitly. Otherwise the default return type is <q>unknown</q> (<code>?</code>), which leads to 2907*8c35d5eeSXin Listrange and unexpected behavior, and is rarely what is actually desired.</p> 2908*8c35d5eeSXin Li 2909*8c35d5eeSXin Li<p>Bad - type error, but no warning given:</p> 2910*8c35d5eeSXin Li 2911*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">/** @param {function()} generateNumber */ 2912*8c35d5eeSXin Lifunction foo(generateNumber) { 2913*8c35d5eeSXin Li const /** number */ x = generateNumber(); // No compile-time type error here. 2914*8c35d5eeSXin Li} 2915*8c35d5eeSXin Li 2916*8c35d5eeSXin Lifoo(() => 'clearly not a number'); 2917*8c35d5eeSXin Li</code></pre> 2918*8c35d5eeSXin Li 2919*8c35d5eeSXin Li<p>Good:</p> 2920*8c35d5eeSXin Li 2921*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 2922*8c35d5eeSXin Li * @param {function(): *} inputFunction1 Can return any type. 2923*8c35d5eeSXin Li * @param {function(): undefined} inputFunction2 Definitely doesn't return 2924*8c35d5eeSXin Li * anything. 2925*8c35d5eeSXin Li * NOTE: the return type of `foo` itself is safely implied to be {undefined}. 2926*8c35d5eeSXin Li */ 2927*8c35d5eeSXin Lifunction foo(inputFunction1, inputFunction2) {...} 2928*8c35d5eeSXin Li</code></pre> 2929*8c35d5eeSXin Li 2930*8c35d5eeSXin Li<h4 id="jsdoc-whitespace">7.10.5 Whitespace</h4> 2931*8c35d5eeSXin Li 2932*8c35d5eeSXin Li<p>Within a type annotation, a single space or line break is required after each 2933*8c35d5eeSXin Licomma or colon. Additional line breaks may be inserted to improve readability or 2934*8c35d5eeSXin Liavoid exceeding the column limit. These breaks should be chosen and indented 2935*8c35d5eeSXin Lifollowing the applicable guidelines (e.g. <a href="#formatting-line-wrapping">??</a> and 2936*8c35d5eeSXin Li<a href="#formatting-block-indentation">??</a>). No other whitespace is allowed in type 2937*8c35d5eeSXin Liannotations.</p> 2938*8c35d5eeSXin Li 2939*8c35d5eeSXin Li<p>Good:</p> 2940*8c35d5eeSXin Li 2941*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @type {function(string): number} */ 2942*8c35d5eeSXin Li 2943*8c35d5eeSXin Li/** @type {{foo: number, bar: number}} */ 2944*8c35d5eeSXin Li 2945*8c35d5eeSXin Li/** @type {number|string} */ 2946*8c35d5eeSXin Li 2947*8c35d5eeSXin Li/** @type {!Object<string, string>} */ 2948*8c35d5eeSXin Li 2949*8c35d5eeSXin Li/** @type {function(this: Object<string, string>, number): string} */ 2950*8c35d5eeSXin Li 2951*8c35d5eeSXin Li/** 2952*8c35d5eeSXin Li * @type {function( 2953*8c35d5eeSXin Li * !SuperDuperReallyReallyLongTypedefThatForcesTheLineBreak, 2954*8c35d5eeSXin Li * !OtherVeryLongTypedef): string} 2955*8c35d5eeSXin Li */ 2956*8c35d5eeSXin Li 2957*8c35d5eeSXin Li/** 2958*8c35d5eeSXin Li * @type {!SuperDuperReallyReallyLongTypedefThatForcesTheLineBreak| 2959*8c35d5eeSXin Li * !OtherVeryLongTypedef} 2960*8c35d5eeSXin Li */ 2961*8c35d5eeSXin Li</code></pre> 2962*8c35d5eeSXin Li 2963*8c35d5eeSXin Li<p>Bad:</p> 2964*8c35d5eeSXin Li 2965*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">// Only put a space after the colon 2966*8c35d5eeSXin Li/** @type {function(string) : number} */ 2967*8c35d5eeSXin Li 2968*8c35d5eeSXin Li// Put spaces after colons and commas 2969*8c35d5eeSXin Li/** @type {{foo:number,bar:number}} */ 2970*8c35d5eeSXin Li 2971*8c35d5eeSXin Li// No space in union types 2972*8c35d5eeSXin Li/** @type {number | string} */ 2973*8c35d5eeSXin Li</code></pre> 2974*8c35d5eeSXin Li 2975*8c35d5eeSXin Li<h3 id="jsdoc-visibility-annotations">7.11 Visibility annotations</h3> 2976*8c35d5eeSXin Li 2977*8c35d5eeSXin Li<p>Visibility annotations (<code>@private</code>, <code>@package</code>, <code>@protected</code>) may be specified 2978*8c35d5eeSXin Liin a <code>@fileoverview</code> block, or on any exported symbol or property. Do not 2979*8c35d5eeSXin Lispecify visibility for local variables, whether within a function or at the top 2980*8c35d5eeSXin Lilevel of a module. All <code>@private</code> names must end with an underscore.</p> 2981*8c35d5eeSXin Li 2982*8c35d5eeSXin Li<h2 id="policies">8 Policies</h2> 2983*8c35d5eeSXin Li 2984*8c35d5eeSXin Li<h3 id="policies-be-consistent">8.1 Issues unspecified by Google Style: Be Consistent!</h3> 2985*8c35d5eeSXin Li 2986*8c35d5eeSXin Li<p>For any style question that isn't settled definitively by this specification, 2987*8c35d5eeSXin Liprefer to do what the other code in the same file is already doing. If that 2988*8c35d5eeSXin Lidoesn't resolve the question, consider emulating the other files in the same 2989*8c35d5eeSXin Lipackage.</p> 2990*8c35d5eeSXin Li 2991*8c35d5eeSXin Li<h3 id="policies-compiler-warnings">8.2 Compiler warnings</h3> 2992*8c35d5eeSXin Li 2993*8c35d5eeSXin Li<h4 id="policies-use-a-standard-warning-set">8.2.1 Use a standard warning set</h4> 2994*8c35d5eeSXin Li 2995*8c35d5eeSXin Li<p> 2996*8c35d5eeSXin LiAs far as possible projects should use <code>--warning_level=VERBOSE</code>. 2997*8c35d5eeSXin Li</p> 2998*8c35d5eeSXin Li 2999*8c35d5eeSXin Li<h4 id="policies-how-to-handle-a-warning">8.2.2 How to handle a warning</h4> 3000*8c35d5eeSXin Li 3001*8c35d5eeSXin Li<p>Before doing anything, make sure you understand exactly what the warning is 3002*8c35d5eeSXin Litelling you. If you're not positive why a warning is appearing, ask for help 3003*8c35d5eeSXin Li.</p> 3004*8c35d5eeSXin Li 3005*8c35d5eeSXin Li<p>Once you understand the warning, attempt the following solutions in order:</p> 3006*8c35d5eeSXin Li 3007*8c35d5eeSXin Li<ol> 3008*8c35d5eeSXin Li<li><strong>First, fix it or work around it.</strong> Make a strong attempt to actually 3009*8c35d5eeSXin Liaddress the warning, or find another way to accomplish the task that avoids 3010*8c35d5eeSXin Lithe situation entirely.</li> 3011*8c35d5eeSXin Li<li><strong>Otherwise, determine if it's a false alarm.</strong> If you are convinced that 3012*8c35d5eeSXin Lithe warning is invalid and that the code is actually safe and correct, add a 3013*8c35d5eeSXin Licomment to convince the reader of this fact and apply the <code>@suppress</code> 3014*8c35d5eeSXin Liannotation.</li> 3015*8c35d5eeSXin Li<li><strong>Otherwise, leave a TODO comment.</strong> This is a <strong>last resort</strong>. If you do 3016*8c35d5eeSXin Lithis, <strong>do not suppress the warning.</strong> The warning should be visible until 3017*8c35d5eeSXin Liit can be taken care of properly.</li> 3018*8c35d5eeSXin Li</ol> 3019*8c35d5eeSXin Li 3020*8c35d5eeSXin Li<h4 id="policies-suppress-a-warning-at-the-narrowest-reasonable-scope">8.2.3 Suppress a warning at the narrowest reasonable scope</h4> 3021*8c35d5eeSXin Li 3022*8c35d5eeSXin Li<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> 3023*8c35d5eeSXin Li 3024*8c35d5eeSXin Li<p>Example</p> 3025*8c35d5eeSXin Li 3026*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @suppress {uselessCode} Unrecognized 'use asm' declaration */ 3027*8c35d5eeSXin Lifunction fn() { 3028*8c35d5eeSXin Li 'use asm'; 3029*8c35d5eeSXin Li return 0; 3030*8c35d5eeSXin Li} 3031*8c35d5eeSXin Li</code></pre> 3032*8c35d5eeSXin Li 3033*8c35d5eeSXin Li<p>Even a large number of suppressions in a class is still better than blinding the 3034*8c35d5eeSXin Lientire class to this type of warning.</p> 3035*8c35d5eeSXin Li 3036*8c35d5eeSXin Li<h3 id="policies-deprecation">8.3 Deprecation</h3> 3037*8c35d5eeSXin Li 3038*8c35d5eeSXin Li<p>Mark deprecated methods, classes or interfaces with <code>@deprecated</code> annotations. A 3039*8c35d5eeSXin Lideprecation comment must include simple, clear directions for people to fix 3040*8c35d5eeSXin Litheir call sites.</p> 3041*8c35d5eeSXin Li 3042*8c35d5eeSXin Li<h3 id="policies-code-not-in-google-style">8.4 Code not in Google Style</h3> 3043*8c35d5eeSXin Li 3044*8c35d5eeSXin Li<p>You will occasionally encounter files in your codebase that are not in proper 3045*8c35d5eeSXin LiGoogle Style. These may have come from an acquisition, or may have been written 3046*8c35d5eeSXin Libefore Google Style took a position on some issue, or may be in non-Google Style 3047*8c35d5eeSXin Lifor any other reason.</p> 3048*8c35d5eeSXin Li 3049*8c35d5eeSXin Li<h4 id="policies-reformatting-existing-code">8.4.1 Reformatting existing code</h4> 3050*8c35d5eeSXin Li 3051*8c35d5eeSXin Li<p>When updating the style of existing code, follow these guidelines.</p> 3052*8c35d5eeSXin Li 3053*8c35d5eeSXin Li<ol> 3054*8c35d5eeSXin Li<li>It is not required to change all existing code to meet current style 3055*8c35d5eeSXin Liguidelines. Reformatting existing code is a trade-off between code churn 3056*8c35d5eeSXin Liand consistency. Style rules evolve over time and these kinds of tweaks to 3057*8c35d5eeSXin Limaintain compliance would create unnecessary churn. However, if significant 3058*8c35d5eeSXin Lichanges are being made to a file it is expected that the file will be in 3059*8c35d5eeSXin LiGoogle Style.</li> 3060*8c35d5eeSXin Li<li>Be careful not to allow opportunistic style fixes to muddle the focus of a 3061*8c35d5eeSXin LiCL. If you find yourself making a lot of style changes that aren’t critical 3062*8c35d5eeSXin Lito the central focus of a CL, promote those changes to a separate CL.</li> 3063*8c35d5eeSXin Li</ol> 3064*8c35d5eeSXin Li 3065*8c35d5eeSXin Li<h4 id="policies-newly-added-code-use-google-style">8.4.2 Newly added code: use Google Style</h4> 3066*8c35d5eeSXin Li 3067*8c35d5eeSXin Li<p>Brand new files use Google Style, regardless of the style choices of other files 3068*8c35d5eeSXin Liin the same package.</p> 3069*8c35d5eeSXin Li 3070*8c35d5eeSXin Li<p>When adding new code to a file that is not in Google Style, reformatting the 3071*8c35d5eeSXin Liexisting code first is recommended, subject to the advice in 3072*8c35d5eeSXin Li<a href="#policies-reformatting-existing-code">??</a>.</p> 3073*8c35d5eeSXin Li 3074*8c35d5eeSXin Li<p>If this reformatting is not done, then new code should be as consistent as 3075*8c35d5eeSXin Lipossible with existing code in the same file, but must not violate the style 3076*8c35d5eeSXin Liguide.</p> 3077*8c35d5eeSXin Li 3078*8c35d5eeSXin Li<h3 id="policies-local-style-rules">8.5 Local style rules</h3> 3079*8c35d5eeSXin Li 3080*8c35d5eeSXin Li<p>Teams and projects may adopt additional style rules beyond those in this 3081*8c35d5eeSXin Lidocument, but must accept that cleanup changes may not abide by these additional 3082*8c35d5eeSXin Lirules, and must not block such cleanup changes due to violating any additional 3083*8c35d5eeSXin Lirules. Beware of excessive rules which serve no purpose. The style guide does 3084*8c35d5eeSXin Linot seek to define style in every possible scenario and neither should you.</p> 3085*8c35d5eeSXin Li 3086*8c35d5eeSXin Li<h3 id="policies-generated-code-mostly-exempt">8.6 Generated code: mostly exempt</h3> 3087*8c35d5eeSXin Li 3088*8c35d5eeSXin Li<p>Source code generated by the build process is not required to be in Google 3089*8c35d5eeSXin LiStyle. However, any generated identifiers that will be referenced from 3090*8c35d5eeSXin Lihand-written source code must follow the naming requirements. As a special 3091*8c35d5eeSXin Liexception, such identifiers are allowed to contain underscores, which may help 3092*8c35d5eeSXin Lito avoid conflicts with hand-written identifiers.</p> 3093*8c35d5eeSXin Li 3094*8c35d5eeSXin Li<h2 id="appendices">9 Appendices</h2> 3095*8c35d5eeSXin Li 3096*8c35d5eeSXin Li<h3 id="appendices-jsdoc-tag-reference">9.1 JSDoc tag reference</h3> 3097*8c35d5eeSXin Li 3098*8c35d5eeSXin Li<p>JSDoc serves multiple purposes in JavaScript. In addition to being used to 3099*8c35d5eeSXin Ligenerate documentation it is also used to control tooling. The best known are 3100*8c35d5eeSXin Lithe Closure Compiler type annotations.</p> 3101*8c35d5eeSXin Li 3102*8c35d5eeSXin Li<h4 id="appendices-type-annotations">9.1.1 Type annotations and other Closure Compiler annotations</h4> 3103*8c35d5eeSXin Li 3104*8c35d5eeSXin Li<p>Documentation for JSDoc used by the Closure Compiler is described in 3105*8c35d5eeSXin Li<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 3106*8c35d5eeSXin LiSystem</a>.</p> 3107*8c35d5eeSXin Li 3108*8c35d5eeSXin Li<h4 id="appendices-documentation-annotations">9.1.2 Documentation annotations</h4> 3109*8c35d5eeSXin Li 3110*8c35d5eeSXin Li<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 3111*8c35d5eeSXin LiCompiler</a> the following tags are common and well supported by various 3112*8c35d5eeSXin Lidocumentation generation tools (such as <a href="https://github.com/jleyba/js-dossier">JsDossier</a>) for purely documentation 3113*8c35d5eeSXin Lipurposes.</p> 3114*8c35d5eeSXin Li 3115*8c35d5eeSXin Li<p>You may also see other types of JSDoc annotations in third-party code. These 3116*8c35d5eeSXin Liannotations appear in the <a href="http://code.google.com/p/jsdoc-toolkit/wiki/TagReference">JSDoc Toolkit Tag Reference</a> but are not considered 3117*8c35d5eeSXin Lipart of valid Google style.</p> 3118*8c35d5eeSXin Li 3119*8c35d5eeSXin Li<section class="zippy"> 3120*8c35d5eeSXin Li 3121*8c35d5eeSXin Li<h5>9.1.2.1 <code>@author</code> or <code>@owner</code> - <em>Not recommended.</em></h5> 3122*8c35d5eeSXin Li 3123*8c35d5eeSXin Li<p><strong>Not recommended.</strong></p> 3124*8c35d5eeSXin Li 3125*8c35d5eeSXin Li<p>Syntax: <code>@author [email protected] (First Last)</code></p> 3126*8c35d5eeSXin Li 3127*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 3128*8c35d5eeSXin Li * @fileoverview Utilities for handling textareas. 3129*8c35d5eeSXin Li * @author [email protected] (Uthur Pendragon) 3130*8c35d5eeSXin Li */ 3131*8c35d5eeSXin Li</code></pre> 3132*8c35d5eeSXin Li 3133*8c35d5eeSXin Li<p>Documents the author of a file or the owner of a test, generally only used in 3134*8c35d5eeSXin Lithe <code>@fileoverview</code> comment. The <code>@owner</code> tag is used by the unit test dashboard 3135*8c35d5eeSXin Lito determine who owns the test results.</p> 3136*8c35d5eeSXin Li 3137*8c35d5eeSXin Li</section> 3138*8c35d5eeSXin Li 3139*8c35d5eeSXin Li<section class="zippy"> 3140*8c35d5eeSXin Li 3141*8c35d5eeSXin Li<h5>9.1.2.2 <code>@bug</code></h5> 3142*8c35d5eeSXin Li 3143*8c35d5eeSXin Li<p>Syntax: <code>@bug bugnumber</code></p> 3144*8c35d5eeSXin Li 3145*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @bug 1234567 */ 3146*8c35d5eeSXin Lifunction testSomething() { 3147*8c35d5eeSXin Li // … 3148*8c35d5eeSXin Li} 3149*8c35d5eeSXin Li 3150*8c35d5eeSXin Li/** 3151*8c35d5eeSXin Li * @bug 1234568 3152*8c35d5eeSXin Li * @bug 1234569 3153*8c35d5eeSXin Li */ 3154*8c35d5eeSXin Lifunction testTwoBugs() { 3155*8c35d5eeSXin Li // … 3156*8c35d5eeSXin Li} 3157*8c35d5eeSXin Li</code></pre> 3158*8c35d5eeSXin Li 3159*8c35d5eeSXin Li<p>Indicates what bugs the given test function regression tests.</p> 3160*8c35d5eeSXin Li 3161*8c35d5eeSXin Li<p>Multiple bugs should each have their own <code>@bug</code> line, to make searching for 3162*8c35d5eeSXin Liregression tests as easy as possible.</p> 3163*8c35d5eeSXin Li 3164*8c35d5eeSXin Li</section> 3165*8c35d5eeSXin Li 3166*8c35d5eeSXin Li<section class="zippy"> 3167*8c35d5eeSXin Li 3168*8c35d5eeSXin Li<h5>9.1.2.3 <code>@code</code> - <em>Deprecated. Do not use.</em></h5> 3169*8c35d5eeSXin Li 3170*8c35d5eeSXin Li<p><strong>Deprecated. Do not use. Use Markdown backticks instead.</strong></p> 3171*8c35d5eeSXin Li 3172*8c35d5eeSXin Li<p>Syntax: <code>{@code ...}</code></p> 3173*8c35d5eeSXin Li 3174*8c35d5eeSXin Li<p>Historically, <code>`BatchItem`</code> was written as 3175*8c35d5eeSXin Li<code class="badcode">{@code BatchItem}</code>.</p> 3176*8c35d5eeSXin Li 3177*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** Processes pending `BatchItem` instances. */ 3178*8c35d5eeSXin Lifunction processBatchItems() {} 3179*8c35d5eeSXin Li</code></pre> 3180*8c35d5eeSXin Li 3181*8c35d5eeSXin Li<p>Indicates that a term in a JSDoc description is code so it may be correctly 3182*8c35d5eeSXin Liformatted in generated documentation.</p> 3183*8c35d5eeSXin Li 3184*8c35d5eeSXin Li</section> 3185*8c35d5eeSXin Li 3186*8c35d5eeSXin Li<section class="zippy"> 3187*8c35d5eeSXin Li 3188*8c35d5eeSXin Li<h5>9.1.2.4 <code>@desc</code></h5> 3189*8c35d5eeSXin Li 3190*8c35d5eeSXin Li<p>Syntax: <code>@desc Message description</code></p> 3191*8c35d5eeSXin Li 3192*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** @desc Notifying a user that their account has been created. */ 3193*8c35d5eeSXin Liexports.MSG_ACCOUNT_CREATED = goog.getMsg( 3194*8c35d5eeSXin Li 'Your account has been successfully created.'); 3195*8c35d5eeSXin Li</code></pre> 3196*8c35d5eeSXin Li 3197*8c35d5eeSXin Li</section> 3198*8c35d5eeSXin Li 3199*8c35d5eeSXin Li<section class="zippy"> 3200*8c35d5eeSXin Li 3201*8c35d5eeSXin Li<h5>9.1.2.5 <code>@link</code></h5> 3202*8c35d5eeSXin Li 3203*8c35d5eeSXin Li<p>Syntax: <code>{@link ...}</code></p> 3204*8c35d5eeSXin Li 3205*8c35d5eeSXin Li<p>This tag is used to generate cross-reference links within generated 3206*8c35d5eeSXin Lidocumentation.</p> 3207*8c35d5eeSXin Li 3208*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** Processes pending {@link BatchItem} instances. */ 3209*8c35d5eeSXin Lifunction processBatchItems() {} 3210*8c35d5eeSXin Li</code></pre> 3211*8c35d5eeSXin Li 3212*8c35d5eeSXin Li<p><strong>Historical note:</strong> @link tags have also been used to create external links in 3213*8c35d5eeSXin Ligenerated documentation. For external links, always use Markdown's link syntax 3214*8c35d5eeSXin Liinstead:</p> 3215*8c35d5eeSXin Li 3216*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 3217*8c35d5eeSXin Li * This class implements a useful subset of the 3218*8c35d5eeSXin Li * [native Event interface](https://dom.spec.whatwg.org/#event). 3219*8c35d5eeSXin Li */ 3220*8c35d5eeSXin Liclass ApplicationEvent {} 3221*8c35d5eeSXin Li</code></pre> 3222*8c35d5eeSXin Li 3223*8c35d5eeSXin Li</section> 3224*8c35d5eeSXin Li 3225*8c35d5eeSXin Li<section class="zippy"> 3226*8c35d5eeSXin Li 3227*8c35d5eeSXin Li<h5>9.1.2.6 <code>@see</code></h5> 3228*8c35d5eeSXin Li 3229*8c35d5eeSXin Li<p>Syntax: <code>@see Link</code></p> 3230*8c35d5eeSXin Li 3231*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 3232*8c35d5eeSXin Li * Adds a single item, recklessly. 3233*8c35d5eeSXin Li * @see #addSafely 3234*8c35d5eeSXin Li * @see goog.Collect 3235*8c35d5eeSXin Li * @see goog.RecklessAdder#add 3236*8c35d5eeSXin Li */ 3237*8c35d5eeSXin Li</code></pre> 3238*8c35d5eeSXin Li 3239*8c35d5eeSXin Li<p>Reference a lookup to another class function or method.</p> 3240*8c35d5eeSXin Li 3241*8c35d5eeSXin Li</section> 3242*8c35d5eeSXin Li 3243*8c35d5eeSXin Li<section class="zippy"> 3244*8c35d5eeSXin Li 3245*8c35d5eeSXin Li<h5>9.1.2.7 <code>@supported</code></h5> 3246*8c35d5eeSXin Li 3247*8c35d5eeSXin Li<p>Syntax: <code>@supported Description</code></p> 3248*8c35d5eeSXin Li 3249*8c35d5eeSXin Li<pre><code class="language-js prettyprint">/** 3250*8c35d5eeSXin Li * @fileoverview Event Manager 3251*8c35d5eeSXin Li * Provides an abstracted interface to the browsers' event systems. 3252*8c35d5eeSXin Li * @supported IE10+, Chrome, Safari 3253*8c35d5eeSXin Li */ 3254*8c35d5eeSXin Li</code></pre> 3255*8c35d5eeSXin Li 3256*8c35d5eeSXin Li<p>Used in a fileoverview to indicate what browsers are supported by the file.</p> 3257*8c35d5eeSXin Li 3258*8c35d5eeSXin Li</section> 3259*8c35d5eeSXin Li 3260*8c35d5eeSXin Li<h4 id="appendices-framework-specific-annotations">9.1.3 Framework specific annotations</h4> 3261*8c35d5eeSXin Li 3262*8c35d5eeSXin Li<p>The following annotations are specific to a particular framework.</p> 3263*8c35d5eeSXin Li 3264*8c35d5eeSXin Li<section class="zippy"> 3265*8c35d5eeSXin Li 3266*8c35d5eeSXin Li<h5>9.1.3.1 <code>@ngInject</code> for Angular 1</h5> 3267*8c35d5eeSXin Li 3268*8c35d5eeSXin Li</section> 3269*8c35d5eeSXin Li 3270*8c35d5eeSXin Li<section class="zippy"> 3271*8c35d5eeSXin Li 3272*8c35d5eeSXin Li<h5>9.1.3.2 <code>@polymerBehavior</code> for Polymer</h5> 3273*8c35d5eeSXin Li 3274*8c35d5eeSXin Li 3275*8c35d5eeSXin Li 3276*8c35d5eeSXin Li<p><a href="https://github.com/google/closure-compiler/wiki/Polymer-Pass">https://github.com/google/closure-compiler/wiki/Polymer-Pass</a> 3277*8c35d5eeSXin Li</p> 3278*8c35d5eeSXin Li 3279*8c35d5eeSXin Li</section> 3280*8c35d5eeSXin Li 3281*8c35d5eeSXin Li<section class="zippy"> 3282*8c35d5eeSXin Li 3283*8c35d5eeSXin Li</section> 3284*8c35d5eeSXin Li 3285*8c35d5eeSXin Li<h4 id="appendices-notes-about-standard-closure-compiler-annotations">9.1.4 Notes about standard Closure Compiler annotations</h4> 3286*8c35d5eeSXin Li 3287*8c35d5eeSXin Li<p>The following tags used to be standard but are now deprecated.</p> 3288*8c35d5eeSXin Li 3289*8c35d5eeSXin Li<section class="zippy"> 3290*8c35d5eeSXin Li 3291*8c35d5eeSXin Li<h5>9.1.4.1 <code>@expose</code> - <em>Deprecated. Do not use.</em></h5> 3292*8c35d5eeSXin Li 3293*8c35d5eeSXin Li<p><strong>Deprecated. Do not use. Use <code>@export</code> and/or <code>@nocollapse</code> instead.</strong></p> 3294*8c35d5eeSXin Li 3295*8c35d5eeSXin Li</section> 3296*8c35d5eeSXin Li 3297*8c35d5eeSXin Li<section class="zippy"> 3298*8c35d5eeSXin Li 3299*8c35d5eeSXin Li<h5>9.1.4.2 <code>@inheritDoc</code> - <em>Deprecated. Do not use.</em></h5> 3300*8c35d5eeSXin Li 3301*8c35d5eeSXin Li<p><strong>Deprecated. Do not use. Use <code>@override</code> instead.</strong></p> 3302*8c35d5eeSXin Li 3303*8c35d5eeSXin Li</section> 3304*8c35d5eeSXin Li 3305*8c35d5eeSXin Li<section class="zippy"> 3306*8c35d5eeSXin Li 3307*8c35d5eeSXin Li</section> 3308*8c35d5eeSXin Li 3309*8c35d5eeSXin Li<section class="zippy"> 3310*8c35d5eeSXin Li 3311*8c35d5eeSXin Li</section> 3312*8c35d5eeSXin Li 3313*8c35d5eeSXin Li<section class="zippy"> 3314*8c35d5eeSXin Li 3315*8c35d5eeSXin Li</section> 3316*8c35d5eeSXin Li 3317*8c35d5eeSXin Li<section class="zippy"> 3318*8c35d5eeSXin Li 3319*8c35d5eeSXin Li</section> 3320*8c35d5eeSXin Li 3321*8c35d5eeSXin Li<section class="zippy"> 3322*8c35d5eeSXin Li 3323*8c35d5eeSXin Li</section> 3324*8c35d5eeSXin Li 3325*8c35d5eeSXin Li<section class="zippy"> 3326*8c35d5eeSXin Li 3327*8c35d5eeSXin Li</section> 3328*8c35d5eeSXin Li 3329*8c35d5eeSXin Li<h3 id="appendices-commonly-misunderstood-style-rules">9.2 Commonly misunderstood style rules</h3> 3330*8c35d5eeSXin Li 3331*8c35d5eeSXin Li<p>Here is a collection of lesser-known or commonly misunderstood facts about 3332*8c35d5eeSXin LiGoogle Style for JavaScript. (The following are true statements; this is not a 3333*8c35d5eeSXin Lilist of <q>myths.</q>)</p> 3334*8c35d5eeSXin Li 3335*8c35d5eeSXin Li<ul> 3336*8c35d5eeSXin Li<li>Neither a copyright statement nor <code>@author</code> credit is required in a source 3337*8c35d5eeSXin Lifile. (Neither is explicitly recommended, either.)</li> 3338*8c35d5eeSXin Li<li>There is no <q>hard and fast</q> rule governing how to order the members of a 3339*8c35d5eeSXin Liclass (<a href="#features-classes">??</a>).</li> 3340*8c35d5eeSXin Li<li>Empty blocks can usually be represented concisely as <code>{}</code>, as detailed in 3341*8c35d5eeSXin Li(<a href="#formatting-empty-blocks">??</a>).</li> 3342*8c35d5eeSXin Li<li>The prime directive of line-wrapping is: prefer to break at a higher 3343*8c35d5eeSXin Lisyntactic level (<a href="#formatting-where-to-break">??</a>).</li> 3344*8c35d5eeSXin Li<li>Non-ASCII characters are allowed in string literals, comments and JSDoc, 3345*8c35d5eeSXin Liand in fact are recommended when they make the code easier to read than the 3346*8c35d5eeSXin Liequivalent Unicode escape would (<a href="#non-ascii-characters">??</a>).</li> 3347*8c35d5eeSXin Li</ul> 3348*8c35d5eeSXin Li 3349*8c35d5eeSXin Li<h3 id="appendices-style-related-tools">9.3 Style-related tools</h3> 3350*8c35d5eeSXin Li 3351*8c35d5eeSXin Li<p>The following tools exist to support various aspects of Google Style.</p> 3352*8c35d5eeSXin Li 3353*8c35d5eeSXin Li<h4 id="appendices-tools-closure-compiler">9.3.1 Closure Compiler</h4> 3354*8c35d5eeSXin Li 3355*8c35d5eeSXin Li<p>This program performs type checking and other checks, 3356*8c35d5eeSXin Lioptimizations and other transformations (such as ECMAScript 6 to ECMAScript 5 3357*8c35d5eeSXin Licode lowering).</p> 3358*8c35d5eeSXin Li 3359*8c35d5eeSXin Li<h4 id="appendices-clang-format">9.3.2 <code>clang-format</code></h4> 3360*8c35d5eeSXin Li 3361*8c35d5eeSXin Li<p>This program reformats 3362*8c35d5eeSXin LiJavaScript source code into Google Style, and also follows a number of 3363*8c35d5eeSXin Linon-required but frequently readability-enhancing formatting practices. 3364*8c35d5eeSXin LiThe output produced by <code>clang-format</code> is compliant with the style guide. 3365*8c35d5eeSXin Li</p> 3366*8c35d5eeSXin Li 3367*8c35d5eeSXin Li<p><code>clang-format</code> is not required. Authors are allowed to change its output, and 3368*8c35d5eeSXin Lireviewers are allowed to ask for such changes; disputes are worked out in the 3369*8c35d5eeSXin Liusual way. However, subtrees may choose to opt in to such enforcement locally.</p> 3370*8c35d5eeSXin Li 3371*8c35d5eeSXin Li<h4 id="appendices-closure-compiler-linter">9.3.3 Closure compiler linter</h4> 3372*8c35d5eeSXin Li 3373*8c35d5eeSXin Li<p>This program checks for a 3374*8c35d5eeSXin Livariety of missteps and anti-patterns. 3375*8c35d5eeSXin Li</p> 3376*8c35d5eeSXin Li 3377*8c35d5eeSXin Li<h4 id="appendices-conformance-framework">9.3.4 Conformance framework</h4> 3378*8c35d5eeSXin Li 3379*8c35d5eeSXin Li<p>The JS Conformance Framework is a tool that is part of the Closure Compiler that 3380*8c35d5eeSXin Liprovides developers a simple means to specify a set of additional checks to be 3381*8c35d5eeSXin Lirun against their code base above the standard checks. Conformance checks can, 3382*8c35d5eeSXin Lifor example, forbid access to a certain property, or calls to a certain 3383*8c35d5eeSXin Lifunction, or missing type information (unknowns).</p> 3384*8c35d5eeSXin Li 3385*8c35d5eeSXin Li<p>These rules are commonly used to enforce critical restrictions (such as defining 3386*8c35d5eeSXin Liglobals, which could break the codebase) and security patterns (such as using 3387*8c35d5eeSXin Li<code>eval</code> or assigning to <code>innerHTML</code>), or more loosely to improve code quality.</p> 3388*8c35d5eeSXin Li 3389*8c35d5eeSXin Li<p>For additional information see the official documentation for the 3390*8c35d5eeSXin Li<a href="https://github.com/google/closure-compiler/wiki/JS-Conformance-Framework">JS Conformance Framework</a>.</p> 3391*8c35d5eeSXin Li 3392*8c35d5eeSXin Li<h3 id="appendices-legacy-exceptions">9.4 Exceptions for legacy platforms</h3> 3393*8c35d5eeSXin Li 3394*8c35d5eeSXin Li<h4 id="appendices-legacy-exceptions-overview">9.4.1 Overview</h4> 3395*8c35d5eeSXin Li 3396*8c35d5eeSXin Li<p>This section describes exceptions and additional rules to be followed when 3397*8c35d5eeSXin Limodern ECMAScript 6 syntax is not available to the code authors. Exceptions to 3398*8c35d5eeSXin Lithe recommended style are required when ECMAScript 6 syntax is not possible and 3399*8c35d5eeSXin Liare outlined here:</p> 3400*8c35d5eeSXin Li 3401*8c35d5eeSXin Li<ul> 3402*8c35d5eeSXin Li<li>Use of <code>var</code> declarations is allowed</li> 3403*8c35d5eeSXin Li<li>Use of <code>arguments</code> is allowed</li> 3404*8c35d5eeSXin Li<li>Optional parameters without default values are allowed</li> 3405*8c35d5eeSXin Li</ul> 3406*8c35d5eeSXin Li 3407*8c35d5eeSXin Li<h4 id="appendices-legacy-exceptions-var">9.4.2 Use <code>var</code></h4> 3408*8c35d5eeSXin Li 3409*8c35d5eeSXin Li<h5 id="appendices-legacy-exceptions-var-scope">9.4.2.1 <code>var</code> declarations are NOT block-scoped</h5> 3410*8c35d5eeSXin Li 3411*8c35d5eeSXin Li<p><code>var</code> declarations are scoped to the beginning of the nearest enclosing 3412*8c35d5eeSXin Lifunction, script or module, which can cause unexpected behavior, especially with 3413*8c35d5eeSXin Lifunction closures that reference <code>var</code> declarations inside of loops. The 3414*8c35d5eeSXin Lifollowing code gives an example:</p> 3415*8c35d5eeSXin Li 3416*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">for (var i = 0; i < 3; ++i) { 3417*8c35d5eeSXin Li var iteration = i; 3418*8c35d5eeSXin Li setTimeout(function() { console.log(iteration); }, i*1000); 3419*8c35d5eeSXin Li} 3420*8c35d5eeSXin Li 3421*8c35d5eeSXin Li// logs 2, 2, 2 -- NOT 0, 1, 2 3422*8c35d5eeSXin Li// because `iteration` is function-scoped, not local to the loop. 3423*8c35d5eeSXin Li 3424*8c35d5eeSXin Li</code></pre> 3425*8c35d5eeSXin Li 3426*8c35d5eeSXin Li<h5 id="appendices-legacy-exceptions-var-declare">9.4.2.2 Declare variables as close as possible to first use</h5> 3427*8c35d5eeSXin Li 3428*8c35d5eeSXin Li<p>Even though <code>var</code> declarations are scoped to the beginning of the enclosing 3429*8c35d5eeSXin Lifunction, <code>var</code> declarations should be as close as possible to their first use, 3430*8c35d5eeSXin Lifor readability purposes. However, do not put a <code>var</code> declaration inside a block 3431*8c35d5eeSXin Liif that variable is referenced outside the block. For example:</p> 3432*8c35d5eeSXin Li 3433*8c35d5eeSXin Li<pre><code class="language-js prettyprint">function sillyFunction() { 3434*8c35d5eeSXin Li var count = 0; 3435*8c35d5eeSXin Li for (var x in y) { 3436*8c35d5eeSXin Li // "count" could be declared here, but don't do that. 3437*8c35d5eeSXin Li count++; 3438*8c35d5eeSXin Li } 3439*8c35d5eeSXin Li console.log(count + ' items in y'); 3440*8c35d5eeSXin Li} 3441*8c35d5eeSXin Li</code></pre> 3442*8c35d5eeSXin Li 3443*8c35d5eeSXin Li<h5 id="appendices-legacy-exceptions-var-const">9.4.2.3 Use @const for constants variables</h5> 3444*8c35d5eeSXin Li 3445*8c35d5eeSXin Li<p>For global declarations where the <code>const</code> keyword would be used, if it were 3446*8c35d5eeSXin Liavailable, annotate the <code>var</code> declaration with @const instead (this is optional 3447*8c35d5eeSXin Lifor local variables).</p> 3448*8c35d5eeSXin Li 3449*8c35d5eeSXin Li<h4 id="appendices-legacy-exceptions-function">9.4.3 Do not use block scoped functions declarations</h4> 3450*8c35d5eeSXin Li 3451*8c35d5eeSXin Li<p>Do <strong>not</strong> do this:</p> 3452*8c35d5eeSXin Li 3453*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">if (x) { 3454*8c35d5eeSXin Li function foo() {} 3455*8c35d5eeSXin Li} 3456*8c35d5eeSXin Li</code></pre> 3457*8c35d5eeSXin Li 3458*8c35d5eeSXin Li<p>While most JavaScript VMs implemented before ECMAScript 6 support function 3459*8c35d5eeSXin Lideclarations within blocks it was not standardized. Implementations were 3460*8c35d5eeSXin Liinconsistent with each other and with the now-standard ECMAScript 6 behavior for 3461*8c35d5eeSXin Liblock scoped function declaration. ECMAScript 5 and prior only allow for 3462*8c35d5eeSXin Lifunction declarations in the root statement list of a script or function and 3463*8c35d5eeSXin Liexplicitly ban them in block scopes in strict mode.</p> 3464*8c35d5eeSXin Li 3465*8c35d5eeSXin Li<p>To get consistent behavior, instead use a <code>var</code> initialized with a function 3466*8c35d5eeSXin Liexpression to define a function within a block:</p> 3467*8c35d5eeSXin Li 3468*8c35d5eeSXin Li<pre><code class="language-js prettyprint">if (x) { 3469*8c35d5eeSXin Li var foo = function() {}; 3470*8c35d5eeSXin Li} 3471*8c35d5eeSXin Li</code></pre> 3472*8c35d5eeSXin Li 3473*8c35d5eeSXin Li<h4 id="appendices-legacy-exceptions-goog-provide">9.4.4 Dependency management with <code>goog.provide</code>/<code>goog.require</code></h4> 3474*8c35d5eeSXin Li 3475*8c35d5eeSXin Li<h5 id="appendices-legacy-exceptions-goog-provide-summary">9.4.4.1 Summary</h5> 3476*8c35d5eeSXin Li 3477*8c35d5eeSXin Li<p><strong>WARNING: <code>goog.provide</code> dependency management is deprecated.</strong> All new files, 3478*8c35d5eeSXin Lieven in projects using <code>goog.provide</code> for older files, should use 3479*8c35d5eeSXin Li<a href="#source-file-structure"><code>goog.module</code></a>. The following rules are for 3480*8c35d5eeSXin Lipre-existing <code>goog.provide</code> files only.</p> 3481*8c35d5eeSXin Li 3482*8c35d5eeSXin Li<ul> 3483*8c35d5eeSXin Li<li>Place all <code>goog.provide</code>s first, <code>goog.require</code>s second. Separate provides 3484*8c35d5eeSXin Lifrom requires with an empty line.</li> 3485*8c35d5eeSXin Li<li>Sort the entries alphabetically (uppercase first).</li> 3486*8c35d5eeSXin Li<li>Don't wrap <code>goog.provide</code> and <code>goog.require</code> statements. Exceed 80 columns 3487*8c35d5eeSXin Liif necessary.</li> 3488*8c35d5eeSXin Li<li>Only provide top-level symbols.</li> 3489*8c35d5eeSXin Li</ul> 3490*8c35d5eeSXin Li 3491*8c35d5eeSXin Li<p><code>goog.provide</code> statements should be grouped together and placed first. All 3492*8c35d5eeSXin Li<code>goog.require</code> statements should follow. The two lists should be separated with 3493*8c35d5eeSXin Lian empty line.</p> 3494*8c35d5eeSXin Li 3495*8c35d5eeSXin Li<p>Similar to import statements in other languages, <code>goog.provide</code> and 3496*8c35d5eeSXin Li<code>goog.require</code> statements should be written in a single line, even if they 3497*8c35d5eeSXin Liexceed the 80 column line length limit.</p> 3498*8c35d5eeSXin Li 3499*8c35d5eeSXin Li<p>The lines should be sorted alphabetically, with uppercase letters coming first:</p> 3500*8c35d5eeSXin Li 3501*8c35d5eeSXin Li<pre><code class="language-js prettyprint">goog.provide('namespace.MyClass'); 3502*8c35d5eeSXin Ligoog.provide('namespace.helperFoo'); 3503*8c35d5eeSXin Li 3504*8c35d5eeSXin Ligoog.require('an.extremelyLongNamespace.thatSomeoneThought.wouldBeNice.andNowItIsLonger.Than80Columns'); 3505*8c35d5eeSXin Ligoog.require('goog.dom'); 3506*8c35d5eeSXin Ligoog.require('goog.dom.TagName'); 3507*8c35d5eeSXin Ligoog.require('goog.dom.classes'); 3508*8c35d5eeSXin Ligoog.require('goog.dominoes'); 3509*8c35d5eeSXin Li 3510*8c35d5eeSXin Li</code></pre> 3511*8c35d5eeSXin Li 3512*8c35d5eeSXin Li<p>All members defined on a class should be in the same file. Only top-level 3513*8c35d5eeSXin Liclasses should be provided in a file that contains multiple members defined on 3514*8c35d5eeSXin Lithe same class (e.g. enums, inner classes, etc).</p> 3515*8c35d5eeSXin Li 3516*8c35d5eeSXin Li<p>Do this:</p> 3517*8c35d5eeSXin Li 3518*8c35d5eeSXin Li<pre><code class="language-js prettyprint">goog.provide('namespace.MyClass'); 3519*8c35d5eeSXin Li</code></pre> 3520*8c35d5eeSXin Li 3521*8c35d5eeSXin Li<p>Not this:</p> 3522*8c35d5eeSXin Li 3523*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">goog.provide('namespace.MyClass'); 3524*8c35d5eeSXin Ligoog.provide('namespace.MyClass.CONSTANT'); 3525*8c35d5eeSXin Ligoog.provide('namespace.MyClass.Enum'); 3526*8c35d5eeSXin Ligoog.provide('namespace.MyClass.InnerClass'); 3527*8c35d5eeSXin Ligoog.provide('namespace.MyClass.TypeDef'); 3528*8c35d5eeSXin Ligoog.provide('namespace.MyClass.staticMethod'); 3529*8c35d5eeSXin Li</code></pre> 3530*8c35d5eeSXin Li 3531*8c35d5eeSXin Li<p>Members on namespaces may also be provided:</p> 3532*8c35d5eeSXin Li 3533*8c35d5eeSXin Li<pre><code class="language-js prettyprint">goog.provide('foo.bar'); 3534*8c35d5eeSXin Ligoog.provide('foo.bar.CONSTANT'); 3535*8c35d5eeSXin Ligoog.provide('foo.bar.method'); 3536*8c35d5eeSXin Li</code></pre> 3537*8c35d5eeSXin Li 3538*8c35d5eeSXin Li<h5 id="appendices-legacy-exceptions-goog-scope">9.4.4.2 Aliasing with <code>goog.scope</code></h5> 3539*8c35d5eeSXin Li 3540*8c35d5eeSXin Li<p><strong>WARNING: <code>goog.scope</code> is deprecated.</strong> New files should not use <code>goog.scope</code> 3541*8c35d5eeSXin Lieven in projects with existing <code>goog.scope</code> usage.</p> 3542*8c35d5eeSXin Li 3543*8c35d5eeSXin Li<p><code>goog.scope</code> may be used to shorten references to namespaced symbols in 3544*8c35d5eeSXin Licode using <code>goog.provide</code>/<code>goog.require</code> dependency management.</p> 3545*8c35d5eeSXin Li 3546*8c35d5eeSXin Li<p>Only one <code>goog.scope</code> invocation may be added per file. Always place it in 3547*8c35d5eeSXin Lithe global scope.</p> 3548*8c35d5eeSXin Li 3549*8c35d5eeSXin Li<p>The opening <code>goog.scope(function() {</code> invocation must be preceded by exactly one 3550*8c35d5eeSXin Liblank line and follow any <code>goog.provide</code> statements, <code>goog.require</code> statements, 3551*8c35d5eeSXin Lior top-level comments. The invocation must be closed on the last line in the 3552*8c35d5eeSXin Lifile. Append <code>// goog.scope</code> to the closing statement of the scope. Separate the 3553*8c35d5eeSXin Licomment from the semicolon by two spaces.</p> 3554*8c35d5eeSXin Li 3555*8c35d5eeSXin Li<p>Similar to C++ namespaces, do not indent under <code>goog.scope</code> declarations. 3556*8c35d5eeSXin LiInstead, continue from the 0 column.</p> 3557*8c35d5eeSXin Li 3558*8c35d5eeSXin Li<p>Only make aliases for names that will not be re-assigned to another object 3559*8c35d5eeSXin Li(e.g., most constructors, enums, and namespaces). Do not do this (see below for 3560*8c35d5eeSXin Lihow to alias a constructor):</p> 3561*8c35d5eeSXin Li 3562*8c35d5eeSXin Li<pre><code class="language-js prettyprint badcode">goog.scope(function() { 3563*8c35d5eeSXin Livar Button = goog.ui.Button; 3564*8c35d5eeSXin Li 3565*8c35d5eeSXin LiButton = function() { ... }; 3566*8c35d5eeSXin Li... 3567*8c35d5eeSXin Li</code></pre> 3568*8c35d5eeSXin Li 3569*8c35d5eeSXin Li<p>Names must be the same as the last property of the global that they are aliasing.</p> 3570*8c35d5eeSXin Li 3571*8c35d5eeSXin Li<pre><code class="language-js prettyprint">goog.provide('my.module.SomeType'); 3572*8c35d5eeSXin Li 3573*8c35d5eeSXin Ligoog.require('goog.dom'); 3574*8c35d5eeSXin Ligoog.require('goog.ui.Button'); 3575*8c35d5eeSXin Li 3576*8c35d5eeSXin Ligoog.scope(function() { 3577*8c35d5eeSXin Livar Button = goog.ui.Button; 3578*8c35d5eeSXin Livar dom = goog.dom; 3579*8c35d5eeSXin Li 3580*8c35d5eeSXin Li// Alias new types after the constructor declaration. 3581*8c35d5eeSXin Limy.module.SomeType = function() { ... }; 3582*8c35d5eeSXin Livar SomeType = my.module.SomeType; 3583*8c35d5eeSXin Li 3584*8c35d5eeSXin Li// Declare methods on the prototype as usual: 3585*8c35d5eeSXin LiSomeType.prototype.findButton = function() { 3586*8c35d5eeSXin Li // Button as aliased above. 3587*8c35d5eeSXin Li this.button = new Button(dom.getElement('my-button')); 3588*8c35d5eeSXin Li}; 3589*8c35d5eeSXin Li... 3590*8c35d5eeSXin Li}); // goog.scope 3591*8c35d5eeSXin Li</code></pre> 3592*8c35d5eeSXin Li 3593*8c35d5eeSXin Li<h5 id="appendices-legacy-exceptions-forward-declare">9.4.4.3 <code>goog.forwardDeclare</code></h5> 3594*8c35d5eeSXin Li 3595*8c35d5eeSXin Li<p>Prefer to use <code>goog.requireType</code> instead of <code>goog.forwardDeclare</code> to break 3596*8c35d5eeSXin Licircular dependencies between files in the same library. Unlike <code>goog.require</code>, 3597*8c35d5eeSXin Lia <code>goog.requireType</code> statement is allowed to import a namespace before it is 3598*8c35d5eeSXin Lidefined.</p> 3599*8c35d5eeSXin Li 3600*8c35d5eeSXin Li<p><code>goog.forwardDeclare</code> may still be used in legacy code to break circular 3601*8c35d5eeSXin Lireferences spanning across library boundaries, but newer code should be 3602*8c35d5eeSXin Listructured to avoid it.</p> 3603*8c35d5eeSXin Li 3604*8c35d5eeSXin Li<p><code>goog.forwardDeclare</code> statements must follow the same style rules as 3605*8c35d5eeSXin Li<code>goog.require</code> and <code>goog.requireType</code>. The entire block of 3606*8c35d5eeSXin Li<code>goog.forwardDeclare</code>, <code>goog.require</code> and <code>goog.requireType</code> statements is 3607*8c35d5eeSXin Lisorted alphabetically.</p> 3608*8c35d5eeSXin Li 3609*8c35d5eeSXin Li</div> 3610*8c35d5eeSXin Li</body> 3611*8c35d5eeSXin Li</html> 3612