1*8c35d5eeSXin Li<?xml version = '1.0'?> 2*8c35d5eeSXin Li<?xml-stylesheet type="text/xsl" href="styleguide.xsl"?> 3*8c35d5eeSXin Li<GUIDE title="Google JavaScript Style Guide"> 4*8c35d5eeSXin Li <p class="revision"> 5*8c35d5eeSXin Li Please note: there's a newer version of this guide that includes 6*8c35d5eeSXin Li ECMAScript 6th Edition features. It lives <a href="jsguide.html">here</a>. 7*8c35d5eeSXin Li You should probably be using that for new code. 8*8c35d5eeSXin Li 9*8c35d5eeSXin Li Revision 2.93 10*8c35d5eeSXin Li </p> 11*8c35d5eeSXin Li 12*8c35d5eeSXin Li <address> 13*8c35d5eeSXin Li Aaron Whyte<br/> 14*8c35d5eeSXin Li Bob Jervis<br/> 15*8c35d5eeSXin Li Dan Pupius<br/> 16*8c35d5eeSXin Li Erik Arvidsson<br/> 17*8c35d5eeSXin Li Fritz Schneider<br/> 18*8c35d5eeSXin Li Robby Walker<br/> 19*8c35d5eeSXin Li </address> 20*8c35d5eeSXin Li <OVERVIEW> 21*8c35d5eeSXin Li <CATEGORY title="Important Note"> 22*8c35d5eeSXin Li <STYLEPOINT title="Displaying Hidden Details in this Guide"> 23*8c35d5eeSXin Li <SUMMARY> 24*8c35d5eeSXin Li This style guide contains many details that are initially 25*8c35d5eeSXin Li hidden from view. They are marked by the triangle icon, which you 26*8c35d5eeSXin Li see here on your left. Click it now. 27*8c35d5eeSXin Li You should see "Hooray" appear below. 28*8c35d5eeSXin Li </SUMMARY> 29*8c35d5eeSXin Li <BODY> 30*8c35d5eeSXin Li <p> 31*8c35d5eeSXin Li Hooray! Now you know you can expand points to get more 32*8c35d5eeSXin Li details. Alternatively, there's a "toggle all" at the 33*8c35d5eeSXin Li top of this document. 34*8c35d5eeSXin Li </p> 35*8c35d5eeSXin Li </BODY> 36*8c35d5eeSXin Li </STYLEPOINT> 37*8c35d5eeSXin Li </CATEGORY> 38*8c35d5eeSXin Li <CATEGORY title="Background"> 39*8c35d5eeSXin Li <p> 40*8c35d5eeSXin Li JavaScript is the main client-side scripting language used 41*8c35d5eeSXin Li 42*8c35d5eeSXin Li by many of Google's open-source 43*8c35d5eeSXin Li projects. 44*8c35d5eeSXin Li This style guide is a list of <em>do</em>s and <em>don't</em>s for 45*8c35d5eeSXin Li JavaScript programs. 46*8c35d5eeSXin Li </p> 47*8c35d5eeSXin Li 48*8c35d5eeSXin Li 49*8c35d5eeSXin Li 50*8c35d5eeSXin Li 51*8c35d5eeSXin Li 52*8c35d5eeSXin Li </CATEGORY> 53*8c35d5eeSXin Li </OVERVIEW> 54*8c35d5eeSXin Li <CATEGORY title="JavaScript Language Rules"> 55*8c35d5eeSXin Li 56*8c35d5eeSXin Li 57*8c35d5eeSXin Li 58*8c35d5eeSXin Li 59*8c35d5eeSXin Li <STYLEPOINT title="var"> 60*8c35d5eeSXin Li <SUMMARY> 61*8c35d5eeSXin Li Declarations with <code>var</code>: Always 62*8c35d5eeSXin Li </SUMMARY> 63*8c35d5eeSXin Li <BODY> 64*8c35d5eeSXin Li <DECISION> 65*8c35d5eeSXin Li When you fail to specify <code>var</code>, 66*8c35d5eeSXin Li the variable gets placed in the global context, potentially clobbering 67*8c35d5eeSXin Li existing values. Also, if there's no declaration, it's hard to tell in 68*8c35d5eeSXin Li what scope a variable lives (e.g., it could be in the Document or 69*8c35d5eeSXin Li Window just as easily as in the local scope). So always declare with 70*8c35d5eeSXin Li <code>var</code>. 71*8c35d5eeSXin Li </DECISION> 72*8c35d5eeSXin Li </BODY> 73*8c35d5eeSXin Li </STYLEPOINT> 74*8c35d5eeSXin Li 75*8c35d5eeSXin Li <STYLEPOINT title="Constants"> 76*8c35d5eeSXin Li <SUMMARY> 77*8c35d5eeSXin Li <ul> 78*8c35d5eeSXin Li <li>Use <code>NAMES_LIKE_THIS</code> for constant <em>values</em>.</li> 79*8c35d5eeSXin Li <li>Use <code>@const</code> to indicate a constant (non-overwritable) 80*8c35d5eeSXin Li <em>pointer</em> (a variable or property).</li> 81*8c35d5eeSXin Li <li>Never use the 82*8c35d5eeSXin Li <a href="https://developer.mozilla.org/en/JavaScript/Reference/Statements/const"> 83*8c35d5eeSXin Li <code>const</code> keyword</a> 84*8c35d5eeSXin Li as it's not supported in Internet Explorer.</li> 85*8c35d5eeSXin Li </ul> 86*8c35d5eeSXin Li </SUMMARY> 87*8c35d5eeSXin Li <BODY> 88*8c35d5eeSXin Li <DECISION> 89*8c35d5eeSXin Li <SUBSECTION title="Constant values"> 90*8c35d5eeSXin Li 91*8c35d5eeSXin Li <p>If a value is intended to be <em>constant</em> 92*8c35d5eeSXin Li and <em>immutable</em>, it should be given a name 93*8c35d5eeSXin Li in <code>CONSTANT_VALUE_CASE</code>. 94*8c35d5eeSXin Li <code>ALL_CAPS</code> additionally implies <code>@const</code> 95*8c35d5eeSXin Li (that the value is not overwritable). 96*8c35d5eeSXin Li </p> 97*8c35d5eeSXin Li 98*8c35d5eeSXin Li <p>Primitive types (<code>number</code>, <code>string</code>, 99*8c35d5eeSXin Li <code>boolean</code>) are constant values.</p> 100*8c35d5eeSXin Li 101*8c35d5eeSXin Li <p><code>Objects</code>' 102*8c35d5eeSXin Li immutability is more subjective — objects should be 103*8c35d5eeSXin Li considered immutable only if they do not demonstrate observable 104*8c35d5eeSXin Li state change. This is not enforced by the compiler.</p> 105*8c35d5eeSXin Li 106*8c35d5eeSXin Li 107*8c35d5eeSXin Li </SUBSECTION> 108*8c35d5eeSXin Li 109*8c35d5eeSXin Li <SUBSECTION title="Constant pointers (variables and properties)"> 110*8c35d5eeSXin Li <p>The <code>@const</code> annotation on a variable or property 111*8c35d5eeSXin Li implies that it is not overwritable. This is enforced by the 112*8c35d5eeSXin Li compiler at build time. This behavior is consistent with the 113*8c35d5eeSXin Li <a href="https://developer.mozilla.org/en/JavaScript/Reference/Statements/const"> 114*8c35d5eeSXin Li <code>const</code> keyword</a> (which we do not use due to the 115*8c35d5eeSXin Li lack of support in Internet Explorer).</p> 116*8c35d5eeSXin Li 117*8c35d5eeSXin Li <p>A <code>@const</code> annotation on a method additionally 118*8c35d5eeSXin Li implies that the method cannot not be overridden in subclasses. 119*8c35d5eeSXin Li </p> 120*8c35d5eeSXin Li 121*8c35d5eeSXin Li <p>A <code>@const</code> annotation on a constructor implies the 122*8c35d5eeSXin Li class cannot be subclassed (akin to <code>final</code> in Java). 123*8c35d5eeSXin Li </p> 124*8c35d5eeSXin Li 125*8c35d5eeSXin Li </SUBSECTION> 126*8c35d5eeSXin Li 127*8c35d5eeSXin Li <SUBSECTION title="Examples"> 128*8c35d5eeSXin Li 129*8c35d5eeSXin Li <p>Note that <code>@const</code> does not necessarily imply 130*8c35d5eeSXin Li <code>CONSTANT_VALUES_CASE</code>. 131*8c35d5eeSXin Li 132*8c35d5eeSXin Li However, <code>CONSTANT_VALUES_CASE</code> 133*8c35d5eeSXin Li <em>does</em> imply <code>@const</code>. 134*8c35d5eeSXin Li </p> 135*8c35d5eeSXin Li 136*8c35d5eeSXin Li <CODE_SNIPPET> 137*8c35d5eeSXin Li /** 138*8c35d5eeSXin Li * Request timeout in milliseconds. 139*8c35d5eeSXin Li * @type {number} 140*8c35d5eeSXin Li */ 141*8c35d5eeSXin Li goog.example.TIMEOUT_IN_MILLISECONDS = 60; 142*8c35d5eeSXin Li </CODE_SNIPPET> 143*8c35d5eeSXin Li 144*8c35d5eeSXin Li <p>The number of seconds in a minute never changes. It is a 145*8c35d5eeSXin Li constant value. <code>ALL_CAPS</code> 146*8c35d5eeSXin Li also implies <code>@const</code>, so the constant cannot be 147*8c35d5eeSXin Li overwritten. 148*8c35d5eeSXin Li </p> 149*8c35d5eeSXin Li 150*8c35d5eeSXin Li <p>The open source compiler will allow the symbol to be 151*8c35d5eeSXin Li overwritten because the constant is 152*8c35d5eeSXin Li <em>not</em> marked as <code>@const</code>.</p> 153*8c35d5eeSXin Li 154*8c35d5eeSXin Li <CODE_SNIPPET> 155*8c35d5eeSXin Li /** 156*8c35d5eeSXin Li * Map of URL to response string. 157*8c35d5eeSXin Li * @const 158*8c35d5eeSXin Li */ 159*8c35d5eeSXin Li MyClass.fetchedUrlCache_ = new goog.structs.Map(); 160*8c35d5eeSXin Li </CODE_SNIPPET> 161*8c35d5eeSXin Li 162*8c35d5eeSXin Li <CODE_SNIPPET> 163*8c35d5eeSXin Li /** 164*8c35d5eeSXin Li * Class that cannot be subclassed. 165*8c35d5eeSXin Li * @const 166*8c35d5eeSXin Li * @constructor 167*8c35d5eeSXin Li */ 168*8c35d5eeSXin Li sloth.MyFinalClass = function() {}; 169*8c35d5eeSXin Li </CODE_SNIPPET> 170*8c35d5eeSXin Li 171*8c35d5eeSXin Li <p>In this case, the pointer can never be overwritten, but 172*8c35d5eeSXin Li value is highly mutable and <b>not</b> constant (and thus in 173*8c35d5eeSXin Li <code>camelCase</code>, not <code>ALL_CAPS</code>).</p> 174*8c35d5eeSXin Li </SUBSECTION> 175*8c35d5eeSXin Li 176*8c35d5eeSXin Li </DECISION> 177*8c35d5eeSXin Li </BODY> 178*8c35d5eeSXin Li </STYLEPOINT> 179*8c35d5eeSXin Li 180*8c35d5eeSXin Li <STYLEPOINT title="Semicolons"> 181*8c35d5eeSXin Li <SUMMARY> 182*8c35d5eeSXin Li Always use semicolons. 183*8c35d5eeSXin Li </SUMMARY> 184*8c35d5eeSXin Li <BODY> 185*8c35d5eeSXin Li <p>Relying on implicit insertion can cause subtle, hard to debug 186*8c35d5eeSXin Li problems. Don't do it. You're better than that.</p> 187*8c35d5eeSXin Li <p>There are a couple places where missing semicolons are particularly 188*8c35d5eeSXin Li dangerous:</p> 189*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 190*8c35d5eeSXin Li // 1. 191*8c35d5eeSXin Li MyClass.prototype.myMethod = function() { 192*8c35d5eeSXin Li return 42; 193*8c35d5eeSXin Li } // No semicolon here. 194*8c35d5eeSXin Li 195*8c35d5eeSXin Li (function() { 196*8c35d5eeSXin Li // Some initialization code wrapped in a function to create a scope for locals. 197*8c35d5eeSXin Li })(); 198*8c35d5eeSXin Li 199*8c35d5eeSXin Li 200*8c35d5eeSXin Li var x = { 201*8c35d5eeSXin Li 'i': 1, 202*8c35d5eeSXin Li 'j': 2 203*8c35d5eeSXin Li } // No semicolon here. 204*8c35d5eeSXin Li 205*8c35d5eeSXin Li // 2. Trying to do one thing on Internet Explorer and another on Firefox. 206*8c35d5eeSXin Li // I know you'd never write code like this, but throw me a bone. 207*8c35d5eeSXin Li [ffVersion, ieVersion][isIE](); 208*8c35d5eeSXin Li 209*8c35d5eeSXin Li 210*8c35d5eeSXin Li var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] // No semicolon here. 211*8c35d5eeSXin Li 212*8c35d5eeSXin Li // 3. conditional execution a la bash 213*8c35d5eeSXin Li -1 == resultOfOperation() || die(); 214*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 215*8c35d5eeSXin Li <SUBSECTION title="So what happens?"> 216*8c35d5eeSXin Li <ol> 217*8c35d5eeSXin Li <li>JavaScript error - first the function returning 42 is called 218*8c35d5eeSXin Li with the second function as a parameter, then the number 42 is 219*8c35d5eeSXin Li "called" resulting in an error.</li> 220*8c35d5eeSXin Li <li>You will most likely get a 'no such property in undefined' 221*8c35d5eeSXin Li error at runtime as it tries to call 222*8c35d5eeSXin Li <code>x[ffVersion, ieVersion][isIE]()</code>.</li> 223*8c35d5eeSXin Li <li><code>die</code> is always called since the array minus 1 is 224*8c35d5eeSXin Li <code>NaN</code> which is never equal to anything (not even if 225*8c35d5eeSXin Li <code>resultOfOperation()</code> returns <code>NaN</code>) and 226*8c35d5eeSXin Li <code>THINGS_TO_EAT</code> gets assigned the result of 227*8c35d5eeSXin Li <code>die()</code>.</li> 228*8c35d5eeSXin Li </ol> 229*8c35d5eeSXin Li </SUBSECTION> 230*8c35d5eeSXin Li <SUBSECTION title="Why?"> 231*8c35d5eeSXin Li <p>JavaScript requires statements to end with a semicolon, except when 232*8c35d5eeSXin Li it thinks it can safely infer their existence. In each of these 233*8c35d5eeSXin Li examples, a function declaration or object or array literal is used 234*8c35d5eeSXin Li inside a statement. The closing brackets are not enough to signal 235*8c35d5eeSXin Li the end of the statement. Javascript never ends a statement if the 236*8c35d5eeSXin Li next token is an infix or bracket operator.</p> 237*8c35d5eeSXin Li <p>This has really surprised people, so make sure your assignments end 238*8c35d5eeSXin Li with semicolons.</p> 239*8c35d5eeSXin Li </SUBSECTION> 240*8c35d5eeSXin Li <SUBSECTION title="Clarification: Semicolons and functions"> 241*8c35d5eeSXin Li <p>Semicolons should be included at the end of function expressions, 242*8c35d5eeSXin Li but not at the end of function declarations. The distinction is 243*8c35d5eeSXin Li best illustrated with an example:</p> 244*8c35d5eeSXin Li <CODE_SNIPPET> 245*8c35d5eeSXin Li var foo = function() { 246*8c35d5eeSXin Li return true; 247*8c35d5eeSXin Li }; // semicolon here. 248*8c35d5eeSXin Li 249*8c35d5eeSXin Li function foo() { 250*8c35d5eeSXin Li return true; 251*8c35d5eeSXin Li } // no semicolon here. 252*8c35d5eeSXin Li </CODE_SNIPPET> 253*8c35d5eeSXin Li </SUBSECTION> 254*8c35d5eeSXin Li </BODY> 255*8c35d5eeSXin Li </STYLEPOINT> 256*8c35d5eeSXin Li 257*8c35d5eeSXin Li <STYLEPOINT title="Nested functions"> 258*8c35d5eeSXin Li <SUMMARY>Yes</SUMMARY> 259*8c35d5eeSXin Li <BODY> 260*8c35d5eeSXin Li <p>Nested functions can be very useful, for example in the creation of 261*8c35d5eeSXin Li continuations and for the task of hiding helper functions. Feel free 262*8c35d5eeSXin Li to use them.</p> 263*8c35d5eeSXin Li </BODY> 264*8c35d5eeSXin Li </STYLEPOINT> 265*8c35d5eeSXin Li 266*8c35d5eeSXin Li <STYLEPOINT title="Function Declarations Within Blocks"> 267*8c35d5eeSXin Li <SUMMARY>No</SUMMARY> 268*8c35d5eeSXin Li <BODY> 269*8c35d5eeSXin Li <p>Do not do this:</p> 270*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 271*8c35d5eeSXin Li if (x) { 272*8c35d5eeSXin Li function foo() {} 273*8c35d5eeSXin Li } 274*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 275*8c35d5eeSXin Li 276*8c35d5eeSXin Li <p>While most script engines support Function Declarations within blocks 277*8c35d5eeSXin Li it is not part of ECMAScript (see 278*8c35d5eeSXin Li <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMA-262</a>, 279*8c35d5eeSXin Li clause 13 and 14). Worse implementations are inconsistent with each 280*8c35d5eeSXin Li other and with future EcmaScript proposals. ECMAScript only allows for 281*8c35d5eeSXin Li Function Declarations in the root statement list of a script or 282*8c35d5eeSXin Li function. Instead use a variable initialized with a Function 283*8c35d5eeSXin Li Expression to define a function within a block:</p> 284*8c35d5eeSXin Li <CODE_SNIPPET> 285*8c35d5eeSXin Li if (x) { 286*8c35d5eeSXin Li var foo = function() {}; 287*8c35d5eeSXin Li } 288*8c35d5eeSXin Li </CODE_SNIPPET> 289*8c35d5eeSXin Li </BODY> 290*8c35d5eeSXin Li </STYLEPOINT> 291*8c35d5eeSXin Li 292*8c35d5eeSXin Li <STYLEPOINT title="Exceptions"> 293*8c35d5eeSXin Li <SUMMARY>Yes</SUMMARY> 294*8c35d5eeSXin Li <BODY> 295*8c35d5eeSXin Li <p>You basically can't avoid exceptions if you're doing something 296*8c35d5eeSXin Li non-trivial (using an application development framework, etc.). 297*8c35d5eeSXin Li Go for it.</p> 298*8c35d5eeSXin Li </BODY> 299*8c35d5eeSXin Li </STYLEPOINT> 300*8c35d5eeSXin Li 301*8c35d5eeSXin Li <STYLEPOINT title="Custom exceptions"> 302*8c35d5eeSXin Li <SUMMARY>Yes</SUMMARY> 303*8c35d5eeSXin Li <BODY> 304*8c35d5eeSXin Li <p>Without custom exceptions, returning error information from a 305*8c35d5eeSXin Li function that also returns a value can be tricky, not to mention 306*8c35d5eeSXin Li inelegant. Bad solutions include passing in a reference type to hold 307*8c35d5eeSXin Li error information or always returning Objects with a potential 308*8c35d5eeSXin Li error member. These basically amount to a primitive exception 309*8c35d5eeSXin Li handling hack. Feel free to use custom exceptions when 310*8c35d5eeSXin Li appropriate.</p> 311*8c35d5eeSXin Li </BODY> 312*8c35d5eeSXin Li </STYLEPOINT> 313*8c35d5eeSXin Li 314*8c35d5eeSXin Li <STYLEPOINT title="Standards features"> 315*8c35d5eeSXin Li <SUMMARY>Always preferred over non-standards features</SUMMARY> 316*8c35d5eeSXin Li <BODY> 317*8c35d5eeSXin Li <p>For maximum portability and compatibility, always prefer standards 318*8c35d5eeSXin Li features over non-standards features (e.g., 319*8c35d5eeSXin Li <code>string.charAt(3)</code> over <code>string[3]</code> and element 320*8c35d5eeSXin Li access with DOM functions instead of using an application-specific 321*8c35d5eeSXin Li shorthand).</p> 322*8c35d5eeSXin Li </BODY> 323*8c35d5eeSXin Li </STYLEPOINT> 324*8c35d5eeSXin Li 325*8c35d5eeSXin Li <STYLEPOINT title="Wrapper objects for primitive types"> 326*8c35d5eeSXin Li <SUMMARY>No</SUMMARY> 327*8c35d5eeSXin Li <BODY> 328*8c35d5eeSXin Li <p>There's no reason to use wrapper objects for primitive types, plus 329*8c35d5eeSXin Li they're dangerous:</p> 330*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 331*8c35d5eeSXin Li var x = new Boolean(false); 332*8c35d5eeSXin Li if (x) { 333*8c35d5eeSXin Li alert('hi'); // Shows 'hi'. 334*8c35d5eeSXin Li } 335*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 336*8c35d5eeSXin Li <p>Don't do it!</p> 337*8c35d5eeSXin Li <p>However type casting is fine.</p> 338*8c35d5eeSXin Li <CODE_SNIPPET> 339*8c35d5eeSXin Li var x = Boolean(0); 340*8c35d5eeSXin Li if (x) { 341*8c35d5eeSXin Li alert('hi'); // This will never be alerted. 342*8c35d5eeSXin Li } 343*8c35d5eeSXin Li typeof Boolean(0) == 'boolean'; 344*8c35d5eeSXin Li typeof new Boolean(0) == 'object'; 345*8c35d5eeSXin Li </CODE_SNIPPET> 346*8c35d5eeSXin Li <p>This is very useful for casting things to 347*8c35d5eeSXin Li <code>number</code>, <code>string</code> and <code>boolean</code>.</p> 348*8c35d5eeSXin Li </BODY> 349*8c35d5eeSXin Li </STYLEPOINT> 350*8c35d5eeSXin Li 351*8c35d5eeSXin Li <STYLEPOINT title="Multi-level prototype hierarchies"> 352*8c35d5eeSXin Li <SUMMARY>Not preferred</SUMMARY> 353*8c35d5eeSXin Li <BODY> 354*8c35d5eeSXin Li <p>Multi-level prototype hierarchies are how JavaScript implements 355*8c35d5eeSXin Li inheritance. You have a multi-level hierarchy if you have a 356*8c35d5eeSXin Li user-defined class D with another user-defined class B as its 357*8c35d5eeSXin Li prototype. These hierarchies are much harder to get right than they 358*8c35d5eeSXin Li first appear! </p> 359*8c35d5eeSXin Li 360*8c35d5eeSXin Li <p>For that reason, it is best to use <code>goog.inherits()</code> from 361*8c35d5eeSXin Li <a href="https://code.google.com/closure/library/"> 362*8c35d5eeSXin Li the Closure Library 363*8c35d5eeSXin Li </a> 364*8c35d5eeSXin Li or a similar library function. 365*8c35d5eeSXin Li </p> 366*8c35d5eeSXin Li <CODE_SNIPPET> 367*8c35d5eeSXin Li function D() { 368*8c35d5eeSXin Li goog.base(this) 369*8c35d5eeSXin Li } 370*8c35d5eeSXin Li goog.inherits(D, B); 371*8c35d5eeSXin Li 372*8c35d5eeSXin Li D.prototype.method = function() { 373*8c35d5eeSXin Li ... 374*8c35d5eeSXin Li }; 375*8c35d5eeSXin Li </CODE_SNIPPET> 376*8c35d5eeSXin Li </BODY> 377*8c35d5eeSXin Li </STYLEPOINT> 378*8c35d5eeSXin Li 379*8c35d5eeSXin Li <STYLEPOINT title="Method and property definitions"> 380*8c35d5eeSXin Li <SUMMARY><code>/** @constructor */ 381*8c35d5eeSXin Li function SomeConstructor() { 382*8c35d5eeSXin Li this.someProperty = 1; 383*8c35d5eeSXin Li } 384*8c35d5eeSXin Li Foo.prototype.someMethod = function() { ... };</code></SUMMARY> 385*8c35d5eeSXin Li <BODY> 386*8c35d5eeSXin Li <p>While there are several ways to attach methods and properties to an 387*8c35d5eeSXin Li object created via "new", the preferred style for methods 388*8c35d5eeSXin Li is:</p> 389*8c35d5eeSXin Li <CODE_SNIPPET> 390*8c35d5eeSXin Li Foo.prototype.bar = function() { 391*8c35d5eeSXin Li /* ... */ 392*8c35d5eeSXin Li }; 393*8c35d5eeSXin Li </CODE_SNIPPET> 394*8c35d5eeSXin Li <p>The preferred style for other properties is to initialize the field 395*8c35d5eeSXin Li in the constructor:</p> 396*8c35d5eeSXin Li <CODE_SNIPPET> 397*8c35d5eeSXin Li /** @constructor */ 398*8c35d5eeSXin Li function Foo() { 399*8c35d5eeSXin Li this.bar = value; 400*8c35d5eeSXin Li } 401*8c35d5eeSXin Li </CODE_SNIPPET> 402*8c35d5eeSXin Li <SUBSECTION title="Why?"> 403*8c35d5eeSXin Li <p>Current JavaScript engines optimize based on the "shape" 404*8c35d5eeSXin Li of an object, <a href="https://developers.google.com/v8/design#prop_access"> 405*8c35d5eeSXin Li adding a property to an object (including overriding 406*8c35d5eeSXin Li a value set on the prototype) changes the shape and can degrade 407*8c35d5eeSXin Li performance.</a></p> 408*8c35d5eeSXin Li </SUBSECTION> 409*8c35d5eeSXin Li </BODY> 410*8c35d5eeSXin Li </STYLEPOINT> 411*8c35d5eeSXin Li 412*8c35d5eeSXin Li <STYLEPOINT title="delete"> 413*8c35d5eeSXin Li <SUMMARY>Prefer <code>this.foo = null</code>.</SUMMARY> 414*8c35d5eeSXin Li <BODY> 415*8c35d5eeSXin Li <CODE_SNIPPET> 416*8c35d5eeSXin Li Foo.prototype.dispose = function() { 417*8c35d5eeSXin Li this.property_ = null; 418*8c35d5eeSXin Li }; 419*8c35d5eeSXin Li </CODE_SNIPPET> 420*8c35d5eeSXin Li <p>Instead of:</p> 421*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 422*8c35d5eeSXin Li Foo.prototype.dispose = function() { 423*8c35d5eeSXin Li delete this.property_; 424*8c35d5eeSXin Li }; 425*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 426*8c35d5eeSXin Li <p>In modern JavaScript engines, changing the number of properties on an 427*8c35d5eeSXin Li object is much slower than reassigning the values. The delete keyword 428*8c35d5eeSXin Li should be avoided except when it is necessary to remove a property 429*8c35d5eeSXin Li from an object's iterated list of keys, or to change the result of 430*8c35d5eeSXin Li <code>if (key in obj)</code>.</p> 431*8c35d5eeSXin Li </BODY> 432*8c35d5eeSXin Li </STYLEPOINT> 433*8c35d5eeSXin Li 434*8c35d5eeSXin Li <STYLEPOINT title="Closures"> 435*8c35d5eeSXin Li <SUMMARY>Yes, but be careful.</SUMMARY> 436*8c35d5eeSXin Li <BODY> 437*8c35d5eeSXin Li <p>The ability to create closures is perhaps the most useful and often 438*8c35d5eeSXin Li overlooked feature of JS. Here is 439*8c35d5eeSXin Li <a href="http://jibbering.com/faq/faq_notes/closures.html"> 440*8c35d5eeSXin Li a good description of how closures work</a>.</p> 441*8c35d5eeSXin Li <p>One thing to keep in mind, however, is that a closure keeps a pointer 442*8c35d5eeSXin Li to its enclosing scope. As a result, attaching a closure to a DOM 443*8c35d5eeSXin Li element can create a circular reference and thus, a memory leak. For 444*8c35d5eeSXin Li example, in the following code:</p> 445*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 446*8c35d5eeSXin Li function foo(element, a, b) { 447*8c35d5eeSXin Li element.onclick = function() { /* uses a and b */ }; 448*8c35d5eeSXin Li } 449*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 450*8c35d5eeSXin Li <p>the function closure keeps a reference to <code>element</code>, 451*8c35d5eeSXin Li <code>a</code>, and <code>b</code> even if it never uses 452*8c35d5eeSXin Li <code>element</code>. Since <code>element</code> also keeps a 453*8c35d5eeSXin Li reference to the closure, we have a cycle that won't be cleaned up by 454*8c35d5eeSXin Li garbage collection. In these situations, the code can be structured 455*8c35d5eeSXin Li as follows:</p> 456*8c35d5eeSXin Li <CODE_SNIPPET> 457*8c35d5eeSXin Li function foo(element, a, b) { 458*8c35d5eeSXin Li element.onclick = bar(a, b); 459*8c35d5eeSXin Li } 460*8c35d5eeSXin Li 461*8c35d5eeSXin Li function bar(a, b) { 462*8c35d5eeSXin Li return function() { /* uses a and b */ }; 463*8c35d5eeSXin Li } 464*8c35d5eeSXin Li </CODE_SNIPPET> 465*8c35d5eeSXin Li </BODY> 466*8c35d5eeSXin Li </STYLEPOINT> 467*8c35d5eeSXin Li 468*8c35d5eeSXin Li <STYLEPOINT title="eval()"> 469*8c35d5eeSXin Li <SUMMARY> 470*8c35d5eeSXin Li Only for code loaders and REPL (Read–eval–print loop) 471*8c35d5eeSXin Li </SUMMARY> 472*8c35d5eeSXin Li <BODY> 473*8c35d5eeSXin Li <p><code>eval()</code> makes for confusing semantics and is dangerous 474*8c35d5eeSXin Li to use if the string being <code>eval()</code>'d contains user input. 475*8c35d5eeSXin Li There's usually a better, clearer, and safer way to write your code, 476*8c35d5eeSXin Li so its use is generally not permitted.</p> 477*8c35d5eeSXin Li 478*8c35d5eeSXin Li <p>For RPC you can always use JSON and read the result using 479*8c35d5eeSXin Li <code>JSON.parse()</code> instead of <code>eval()</code>.</p> 480*8c35d5eeSXin Li 481*8c35d5eeSXin Li <p>Let's assume we have a server that returns something like this:</p> 482*8c35d5eeSXin Li 483*8c35d5eeSXin Li <CODE_SNIPPET> 484*8c35d5eeSXin Li { 485*8c35d5eeSXin Li "name": "Alice", 486*8c35d5eeSXin Li "id": 31502, 487*8c35d5eeSXin Li "email": "[email protected]" 488*8c35d5eeSXin Li } 489*8c35d5eeSXin Li </CODE_SNIPPET> 490*8c35d5eeSXin Li 491*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 492*8c35d5eeSXin Li var userInfo = eval(feed); 493*8c35d5eeSXin Li var email = userInfo['email']; 494*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 495*8c35d5eeSXin Li 496*8c35d5eeSXin Li <p>If the feed was modified to include malicious JavaScript code, then 497*8c35d5eeSXin Li if we use <code>eval</code> then that code will be executed.</p> 498*8c35d5eeSXin Li 499*8c35d5eeSXin Li <CODE_SNIPPET> 500*8c35d5eeSXin Li var userInfo = JSON.parse(feed); 501*8c35d5eeSXin Li var email = userInfo['email']; 502*8c35d5eeSXin Li </CODE_SNIPPET> 503*8c35d5eeSXin Li 504*8c35d5eeSXin Li <p>With <code>JSON.parse</code>, invalid JSON (including all executable 505*8c35d5eeSXin Li JavaScript) will cause an exception to be thrown.</p> 506*8c35d5eeSXin Li 507*8c35d5eeSXin Li </BODY> 508*8c35d5eeSXin Li </STYLEPOINT> 509*8c35d5eeSXin Li 510*8c35d5eeSXin Li <STYLEPOINT title="with() {}"> 511*8c35d5eeSXin Li <SUMMARY>No</SUMMARY> 512*8c35d5eeSXin Li <BODY> 513*8c35d5eeSXin Li <p>Using <code>with</code> clouds the semantics of your program. 514*8c35d5eeSXin Li Because the object of the <code>with</code> can have properties that 515*8c35d5eeSXin Li collide with local variables, it can drastically change the meaning 516*8c35d5eeSXin Li of your program. For example, what does this do?</p> 517*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 518*8c35d5eeSXin Li with (foo) { 519*8c35d5eeSXin Li var x = 3; 520*8c35d5eeSXin Li return x; 521*8c35d5eeSXin Li } 522*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 523*8c35d5eeSXin Li <p>Answer: anything. The local variable <code>x</code> could be 524*8c35d5eeSXin Li clobbered by a property of <code>foo</code> and perhaps it even has 525*8c35d5eeSXin Li a setter, in which case assigning <code>3</code> could cause lots of 526*8c35d5eeSXin Li other code to execute. Don't use <code>with</code>.</p> 527*8c35d5eeSXin Li </BODY> 528*8c35d5eeSXin Li </STYLEPOINT> 529*8c35d5eeSXin Li 530*8c35d5eeSXin Li <STYLEPOINT title="this"> 531*8c35d5eeSXin Li <SUMMARY> 532*8c35d5eeSXin Li Only in object constructors, methods, and in setting up closures 533*8c35d5eeSXin Li </SUMMARY> 534*8c35d5eeSXin Li <BODY> 535*8c35d5eeSXin Li <p>The semantics of <code>this</code> can be tricky. At times it refers 536*8c35d5eeSXin Li to the global object (in most places), the scope of the caller (in 537*8c35d5eeSXin Li <code>eval</code>), a node in the DOM tree (when attached using an 538*8c35d5eeSXin Li event handler HTML attribute), a newly created object (in a 539*8c35d5eeSXin Li constructor), or some other object (if function was 540*8c35d5eeSXin Li <code>call()</code>ed or <code>apply()</code>ed).</p> 541*8c35d5eeSXin Li <p>Because this is so easy to get wrong, limit its use to those places 542*8c35d5eeSXin Li where it is required:</p> 543*8c35d5eeSXin Li <ul> 544*8c35d5eeSXin Li <li>in constructors</li> 545*8c35d5eeSXin Li <li>in methods of objects (including in the creation of closures)</li> 546*8c35d5eeSXin Li </ul> 547*8c35d5eeSXin Li </BODY> 548*8c35d5eeSXin Li </STYLEPOINT> 549*8c35d5eeSXin Li 550*8c35d5eeSXin Li <STYLEPOINT title="for-in loop"> 551*8c35d5eeSXin Li <SUMMARY> 552*8c35d5eeSXin Li Only for iterating over keys in an object/map/hash 553*8c35d5eeSXin Li </SUMMARY> 554*8c35d5eeSXin Li <BODY> 555*8c35d5eeSXin Li <p><code>for-in</code> loops are often incorrectly used to loop over 556*8c35d5eeSXin Li the elements in an <code>Array</code>. This is however very error 557*8c35d5eeSXin Li prone because it does not loop from <code>0</code> to 558*8c35d5eeSXin Li <code>length - 1</code> but over all the present keys in the object 559*8c35d5eeSXin Li and its prototype chain. Here are a few cases where it fails:</p> 560*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 561*8c35d5eeSXin Li function printArray(arr) { 562*8c35d5eeSXin Li for (var key in arr) { 563*8c35d5eeSXin Li print(arr[key]); 564*8c35d5eeSXin Li } 565*8c35d5eeSXin Li } 566*8c35d5eeSXin Li 567*8c35d5eeSXin Li printArray([0,1,2,3]); // This works. 568*8c35d5eeSXin Li 569*8c35d5eeSXin Li var a = new Array(10); 570*8c35d5eeSXin Li printArray(a); // This is wrong. 571*8c35d5eeSXin Li 572*8c35d5eeSXin Li a = document.getElementsByTagName('*'); 573*8c35d5eeSXin Li printArray(a); // This is wrong. 574*8c35d5eeSXin Li 575*8c35d5eeSXin Li a = [0,1,2,3]; 576*8c35d5eeSXin Li a.buhu = 'wine'; 577*8c35d5eeSXin Li printArray(a); // This is wrong again. 578*8c35d5eeSXin Li 579*8c35d5eeSXin Li a = new Array; 580*8c35d5eeSXin Li a[3] = 3; 581*8c35d5eeSXin Li printArray(a); // This is wrong again. 582*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 583*8c35d5eeSXin Li <p>Always use normal for loops when using arrays.</p> 584*8c35d5eeSXin Li <CODE_SNIPPET> 585*8c35d5eeSXin Li function printArray(arr) { 586*8c35d5eeSXin Li var l = arr.length; 587*8c35d5eeSXin Li for (var i = 0; i < l; i++) { 588*8c35d5eeSXin Li print(arr[i]); 589*8c35d5eeSXin Li } 590*8c35d5eeSXin Li } 591*8c35d5eeSXin Li </CODE_SNIPPET> 592*8c35d5eeSXin Li </BODY> 593*8c35d5eeSXin Li </STYLEPOINT> 594*8c35d5eeSXin Li 595*8c35d5eeSXin Li <STYLEPOINT title="Associative Arrays"> 596*8c35d5eeSXin Li <SUMMARY> 597*8c35d5eeSXin Li Never use <code>Array</code> as a map/hash/associative array 598*8c35d5eeSXin Li </SUMMARY> 599*8c35d5eeSXin Li <BODY> 600*8c35d5eeSXin Li <p>Associative <code>Array</code>s are not allowed... or more precisely 601*8c35d5eeSXin Li you are not allowed to use non number indexes for arrays. If you need 602*8c35d5eeSXin Li a map/hash use <code>Object</code> instead of <code>Array</code> in 603*8c35d5eeSXin Li these cases because the features that you want are actually features 604*8c35d5eeSXin Li of <code>Object</code> and not of <code>Array</code>. 605*8c35d5eeSXin Li <code>Array</code> just happens to extend <code>Object</code> (like 606*8c35d5eeSXin Li any other object in JS and therefore you might as well have used 607*8c35d5eeSXin Li <code>Date</code>, <code>RegExp</code> or <code>String</code>).</p> 608*8c35d5eeSXin Li </BODY> 609*8c35d5eeSXin Li </STYLEPOINT> 610*8c35d5eeSXin Li 611*8c35d5eeSXin Li <STYLEPOINT title="Multiline string literals"> 612*8c35d5eeSXin Li <SUMMARY>No</SUMMARY> 613*8c35d5eeSXin Li <BODY> 614*8c35d5eeSXin Li <p>Do not do this:</p> 615*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 616*8c35d5eeSXin Li var myString = 'A rather long string of English text, an error message \ 617*8c35d5eeSXin Li actually that just keeps going and going -- an error \ 618*8c35d5eeSXin Li message to make the Energizer bunny blush (right through \ 619*8c35d5eeSXin Li those Schwarzenegger shades)! Where was I? Oh yes, \ 620*8c35d5eeSXin Li you\'ve got an error and all the extraneous whitespace is \ 621*8c35d5eeSXin Li just gravy. Have a nice day.'; 622*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 623*8c35d5eeSXin Li <p>The whitespace at the beginning of each line can't be safely stripped 624*8c35d5eeSXin Li at compile time; whitespace after the slash will result in tricky 625*8c35d5eeSXin Li errors. </p> 626*8c35d5eeSXin Li <p>Use string concatenation instead:</p> 627*8c35d5eeSXin Li <CODE_SNIPPET> 628*8c35d5eeSXin Li var myString = 'A rather long string of English text, an error message ' + 629*8c35d5eeSXin Li 'actually that just keeps going and going -- an error ' + 630*8c35d5eeSXin Li 'message to make the Energizer bunny blush (right through ' + 631*8c35d5eeSXin Li 'those Schwarzenegger shades)! Where was I? Oh yes, ' + 632*8c35d5eeSXin Li 'you\'ve got an error and all the extraneous whitespace is ' + 633*8c35d5eeSXin Li 'just gravy. Have a nice day.'; 634*8c35d5eeSXin Li </CODE_SNIPPET> 635*8c35d5eeSXin Li </BODY> 636*8c35d5eeSXin Li </STYLEPOINT> 637*8c35d5eeSXin Li 638*8c35d5eeSXin Li <STYLEPOINT title="Array and Object literals"> 639*8c35d5eeSXin Li <SUMMARY>Yes</SUMMARY> 640*8c35d5eeSXin Li <BODY> 641*8c35d5eeSXin Li <p>Use <code>Array</code> and <code>Object</code> literals instead of 642*8c35d5eeSXin Li <code>Array</code> and <code>Object</code> constructors.</p> 643*8c35d5eeSXin Li <p>Array constructors are error-prone due to their arguments.</p> 644*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 645*8c35d5eeSXin Li // Length is 3. 646*8c35d5eeSXin Li var a1 = new Array(x1, x2, x3); 647*8c35d5eeSXin Li 648*8c35d5eeSXin Li // Length is 2. 649*8c35d5eeSXin Li var a2 = new Array(x1, x2); 650*8c35d5eeSXin Li 651*8c35d5eeSXin Li // If x1 is a number and it is a natural number the length will be x1. 652*8c35d5eeSXin Li // If x1 is a number but not a natural number this will throw an exception. 653*8c35d5eeSXin Li // Otherwise the array will have one element with x1 as its value. 654*8c35d5eeSXin Li var a3 = new Array(x1); 655*8c35d5eeSXin Li 656*8c35d5eeSXin Li // Length is 0. 657*8c35d5eeSXin Li var a4 = new Array(); 658*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 659*8c35d5eeSXin Li <p>Because of this, if someone changes the code to pass 1 argument 660*8c35d5eeSXin Li instead of 2 arguments, the array might not have the expected 661*8c35d5eeSXin Li length.</p> 662*8c35d5eeSXin Li <p>To avoid these kinds of weird cases, always use the more readable 663*8c35d5eeSXin Li array literal.</p> 664*8c35d5eeSXin Li <CODE_SNIPPET> 665*8c35d5eeSXin Li var a = [x1, x2, x3]; 666*8c35d5eeSXin Li var a2 = [x1, x2]; 667*8c35d5eeSXin Li var a3 = [x1]; 668*8c35d5eeSXin Li var a4 = []; 669*8c35d5eeSXin Li </CODE_SNIPPET> 670*8c35d5eeSXin Li <p>Object constructors don't have the same problems, but for readability 671*8c35d5eeSXin Li and consistency object literals should be used.</p> 672*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 673*8c35d5eeSXin Li var o = new Object(); 674*8c35d5eeSXin Li 675*8c35d5eeSXin Li var o2 = new Object(); 676*8c35d5eeSXin Li o2.a = 0; 677*8c35d5eeSXin Li o2.b = 1; 678*8c35d5eeSXin Li o2.c = 2; 679*8c35d5eeSXin Li o2['strange key'] = 3; 680*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 681*8c35d5eeSXin Li <p>Should be written as:</p> 682*8c35d5eeSXin Li <CODE_SNIPPET> 683*8c35d5eeSXin Li var o = {}; 684*8c35d5eeSXin Li 685*8c35d5eeSXin Li var o2 = { 686*8c35d5eeSXin Li a: 0, 687*8c35d5eeSXin Li b: 1, 688*8c35d5eeSXin Li c: 2, 689*8c35d5eeSXin Li 'strange key': 3 690*8c35d5eeSXin Li }; 691*8c35d5eeSXin Li </CODE_SNIPPET> 692*8c35d5eeSXin Li </BODY> 693*8c35d5eeSXin Li </STYLEPOINT> 694*8c35d5eeSXin Li 695*8c35d5eeSXin Li <STYLEPOINT title="Modifying prototypes of builtin objects"> 696*8c35d5eeSXin Li <SUMMARY>No</SUMMARY> 697*8c35d5eeSXin Li <BODY> 698*8c35d5eeSXin Li <p>Modifying builtins like <code>Object.prototype</code> and 699*8c35d5eeSXin Li <code>Array.prototype</code> are strictly forbidden. Modifying other 700*8c35d5eeSXin Li builtins like <code>Function.prototype</code> is less dangerous but 701*8c35d5eeSXin Li still leads to hard to debug issues in production and should be 702*8c35d5eeSXin Li avoided.</p> 703*8c35d5eeSXin Li </BODY> 704*8c35d5eeSXin Li </STYLEPOINT> 705*8c35d5eeSXin Li 706*8c35d5eeSXin Li <STYLEPOINT title="Internet Explorer's Conditional Comments"> 707*8c35d5eeSXin Li <SUMMARY>No</SUMMARY> 708*8c35d5eeSXin Li <BODY> 709*8c35d5eeSXin Li <p>Don't do this:</p> 710*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 711*8c35d5eeSXin Li var f = function () { 712*8c35d5eeSXin Li /*@cc_on if (@_jscript) { return 2* @*/ 3; /*@ } @*/ 713*8c35d5eeSXin Li }; 714*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 715*8c35d5eeSXin Li <p>Conditional Comments hinder automated tools as they can vary the 716*8c35d5eeSXin Li JavaScript syntax tree at runtime.</p> 717*8c35d5eeSXin Li </BODY> 718*8c35d5eeSXin Li </STYLEPOINT> 719*8c35d5eeSXin Li </CATEGORY> 720*8c35d5eeSXin Li 721*8c35d5eeSXin Li <CATEGORY title="JavaScript Style Rules"> 722*8c35d5eeSXin Li <STYLEPOINT title="Naming"> 723*8c35d5eeSXin Li <SUMMARY> 724*8c35d5eeSXin Li <p>In general, use 725*8c35d5eeSXin Li <code>functionNamesLikeThis</code>, 726*8c35d5eeSXin Li <code>variableNamesLikeThis</code>, 727*8c35d5eeSXin Li <code>ClassNamesLikeThis</code>, 728*8c35d5eeSXin Li <code>EnumNamesLikeThis</code>, 729*8c35d5eeSXin Li <code>methodNamesLikeThis</code>, 730*8c35d5eeSXin Li <code>CONSTANT_VALUES_LIKE_THIS</code>, 731*8c35d5eeSXin Li <code>foo.namespaceNamesLikeThis.bar</code>, and 732*8c35d5eeSXin Li <code>filenameslikethis.js</code>. 733*8c35d5eeSXin Li </p> 734*8c35d5eeSXin Li </SUMMARY> 735*8c35d5eeSXin Li <BODY> 736*8c35d5eeSXin Li <SUBSECTION title="Properties and methods"> 737*8c35d5eeSXin Li <ul> 738*8c35d5eeSXin Li <li><em>Private</em> properties and methods should be named with a 739*8c35d5eeSXin Li trailing underscore. 740*8c35d5eeSXin Li </li> 741*8c35d5eeSXin Li <li><em>Protected</em> properties and methods should be 742*8c35d5eeSXin Li named without a trailing underscore (like public ones).</li> 743*8c35d5eeSXin Li </ul> 744*8c35d5eeSXin Li <p>For more information on <em>private</em> and <em>protected</em>, 745*8c35d5eeSXin Li read the section on 746*8c35d5eeSXin Li <a href="#Visibility__private_and_protected_fields_"> 747*8c35d5eeSXin Li visibility</a>. 748*8c35d5eeSXin Li </p> 749*8c35d5eeSXin Li 750*8c35d5eeSXin Li 751*8c35d5eeSXin Li 752*8c35d5eeSXin Li 753*8c35d5eeSXin Li </SUBSECTION> 754*8c35d5eeSXin Li 755*8c35d5eeSXin Li <SUBSECTION title="Method and function parameter"> 756*8c35d5eeSXin Li <p>Optional function arguments start with <code>opt_</code>.</p> 757*8c35d5eeSXin Li <p>Functions that take a variable number of arguments should have the 758*8c35d5eeSXin Li last argument named <code>var_args</code>. You may not refer to 759*8c35d5eeSXin Li <code>var_args</code> in the code; use the <code>arguments</code> 760*8c35d5eeSXin Li array.</p> 761*8c35d5eeSXin Li <p>Optional and variable arguments can also be specified in 762*8c35d5eeSXin Li <code>@param</code> annotations. Although either convention is 763*8c35d5eeSXin Li acceptable to the compiler, using both together is preferred.</p> 764*8c35d5eeSXin Li 765*8c35d5eeSXin Li </SUBSECTION> 766*8c35d5eeSXin Li 767*8c35d5eeSXin Li <SUBSECTION title="Getters and Setters"> 768*8c35d5eeSXin Li <p>EcmaScript 5 getters and setters for properties are discouraged. 769*8c35d5eeSXin Li However, if they are used, then getters must not change observable 770*8c35d5eeSXin Li state.</p> 771*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 772*8c35d5eeSXin Li /** 773*8c35d5eeSXin Li * WRONG -- Do NOT do this. 774*8c35d5eeSXin Li */ 775*8c35d5eeSXin Li var foo = { get next() { return this.nextId++; } }; 776*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 777*8c35d5eeSXin Li </SUBSECTION> 778*8c35d5eeSXin Li 779*8c35d5eeSXin Li <SUBSECTION title="Accessor functions"> 780*8c35d5eeSXin Li <p>Getters and setters methods for properties are not required. 781*8c35d5eeSXin Li However, if they are used, then getters must be named 782*8c35d5eeSXin Li <code>getFoo()</code> and setters must be named 783*8c35d5eeSXin Li <code>setFoo(value)</code>. (For boolean getters, 784*8c35d5eeSXin Li <code>isFoo()</code> is also acceptable, and often sounds more 785*8c35d5eeSXin Li natural.)</p> 786*8c35d5eeSXin Li </SUBSECTION> 787*8c35d5eeSXin Li 788*8c35d5eeSXin Li <SUBSECTION title="Namespaces"> 789*8c35d5eeSXin Li <p>JavaScript has no inherent packaging or namespacing support.</p> 790*8c35d5eeSXin Li <p>Global name conflicts are difficult to debug, and can cause 791*8c35d5eeSXin Li intractable problems when two projects try to integrate. In order 792*8c35d5eeSXin Li to make it possible to share common JavaScript code, we've adopted 793*8c35d5eeSXin Li conventions to prevent collisions. </p> 794*8c35d5eeSXin Li <SUBSUBSECTION title="Use namespaces for global code"> 795*8c35d5eeSXin Li <p><em>ALWAYS</em> prefix identifiers in the global scope with a 796*8c35d5eeSXin Li unique pseudo namespace related to the project or library. If you 797*8c35d5eeSXin Li are working on "Project Sloth", a reasonable pseudo namespace 798*8c35d5eeSXin Li would be <code>sloth.*</code>.</p> 799*8c35d5eeSXin Li <CODE_SNIPPET> 800*8c35d5eeSXin Li var sloth = {}; 801*8c35d5eeSXin Li 802*8c35d5eeSXin Li sloth.sleep = function() { 803*8c35d5eeSXin Li ... 804*8c35d5eeSXin Li }; 805*8c35d5eeSXin Li </CODE_SNIPPET> 806*8c35d5eeSXin Li 807*8c35d5eeSXin Li 808*8c35d5eeSXin Li <p>Many JavaScript libraries, including 809*8c35d5eeSXin Li <a href="https://code.google.com/closure/library/"> 810*8c35d5eeSXin Li the Closure Library 811*8c35d5eeSXin Li </a> 812*8c35d5eeSXin Li and 813*8c35d5eeSXin Li <a href="http://www.dojotoolkit.org/"> 814*8c35d5eeSXin Li Dojo toolkit 815*8c35d5eeSXin Li </a> 816*8c35d5eeSXin Li give you high-level functions for declaring your namespaces. 817*8c35d5eeSXin Li Be consistent about how you declare your namespaces.</p> 818*8c35d5eeSXin Li <CODE_SNIPPET> 819*8c35d5eeSXin Li goog.provide('sloth'); 820*8c35d5eeSXin Li 821*8c35d5eeSXin Li sloth.sleep = function() { 822*8c35d5eeSXin Li ... 823*8c35d5eeSXin Li }; 824*8c35d5eeSXin Li </CODE_SNIPPET> 825*8c35d5eeSXin Li </SUBSUBSECTION> 826*8c35d5eeSXin Li <SUBSUBSECTION title="Respect namespace ownership"> 827*8c35d5eeSXin Li <p>When choosing a child-namespace, make sure that the owners of the 828*8c35d5eeSXin Li parent namespace know what you are doing. If you start a project 829*8c35d5eeSXin Li that creates hats for sloths, make sure that the Sloth team knows 830*8c35d5eeSXin Li that you're using <code>sloth.hats</code>.</p> 831*8c35d5eeSXin Li 832*8c35d5eeSXin Li </SUBSUBSECTION> 833*8c35d5eeSXin Li <SUBSUBSECTION title="Use different namespaces for external code and internal code"> 834*8c35d5eeSXin Li <p>"External code" is code that comes from outside your codebase, 835*8c35d5eeSXin Li and is compiled independently. Internal and external names should 836*8c35d5eeSXin Li be kept strictly separate. If you're using an external library 837*8c35d5eeSXin Li that makes things available in <code>foo.hats.*</code>, your 838*8c35d5eeSXin Li internal code should not define all its symbols in 839*8c35d5eeSXin Li <code>foo.hats.*</code>, because it will break if the other 840*8c35d5eeSXin Li team defines new symbols.</p> 841*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 842*8c35d5eeSXin Li foo.require('foo.hats'); 843*8c35d5eeSXin Li 844*8c35d5eeSXin Li /** 845*8c35d5eeSXin Li * WRONG -- Do NOT do this. 846*8c35d5eeSXin Li * @constructor 847*8c35d5eeSXin Li * @extends {foo.hats.RoundHat} 848*8c35d5eeSXin Li */ 849*8c35d5eeSXin Li foo.hats.BowlerHat = function() { 850*8c35d5eeSXin Li }; 851*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 852*8c35d5eeSXin Li <p>If you need to define new APIs on an external namespace, then you 853*8c35d5eeSXin Li should explicitly export the public API functions, and only those 854*8c35d5eeSXin Li functions. Your internal code should call the internal APIs by 855*8c35d5eeSXin Li their internal names, for consistency and so that the compiler 856*8c35d5eeSXin Li can optimize them better.</p> 857*8c35d5eeSXin Li <CODE_SNIPPET> 858*8c35d5eeSXin Li foo.provide('googleyhats.BowlerHat'); 859*8c35d5eeSXin Li 860*8c35d5eeSXin Li foo.require('foo.hats'); 861*8c35d5eeSXin Li 862*8c35d5eeSXin Li /** 863*8c35d5eeSXin Li * @constructor 864*8c35d5eeSXin Li * @extends {foo.hats.RoundHat} 865*8c35d5eeSXin Li */ 866*8c35d5eeSXin Li googleyhats.BowlerHat = function() { 867*8c35d5eeSXin Li ... 868*8c35d5eeSXin Li }; 869*8c35d5eeSXin Li 870*8c35d5eeSXin Li goog.exportSymbol('foo.hats.BowlerHat', googleyhats.BowlerHat); 871*8c35d5eeSXin Li </CODE_SNIPPET> 872*8c35d5eeSXin Li 873*8c35d5eeSXin Li 874*8c35d5eeSXin Li </SUBSUBSECTION> 875*8c35d5eeSXin Li <SUBSUBSECTION title="Alias long type names to improve readability"> 876*8c35d5eeSXin Li <p>Use local aliases for fully-qualified types if doing so improves 877*8c35d5eeSXin Li readability. The name of a local alias should match the last part 878*8c35d5eeSXin Li of the type.</p> 879*8c35d5eeSXin Li <CODE_SNIPPET> 880*8c35d5eeSXin Li /** 881*8c35d5eeSXin Li * @constructor 882*8c35d5eeSXin Li */ 883*8c35d5eeSXin Li some.long.namespace.MyClass = function() { 884*8c35d5eeSXin Li }; 885*8c35d5eeSXin Li 886*8c35d5eeSXin Li /** 887*8c35d5eeSXin Li * @param {some.long.namespace.MyClass} a 888*8c35d5eeSXin Li */ 889*8c35d5eeSXin Li some.long.namespace.MyClass.staticHelper = function(a) { 890*8c35d5eeSXin Li ... 891*8c35d5eeSXin Li }; 892*8c35d5eeSXin Li 893*8c35d5eeSXin Li myapp.main = function() { 894*8c35d5eeSXin Li var MyClass = some.long.namespace.MyClass; 895*8c35d5eeSXin Li var staticHelper = some.long.namespace.MyClass.staticHelper; 896*8c35d5eeSXin Li staticHelper(new MyClass()); 897*8c35d5eeSXin Li }; 898*8c35d5eeSXin Li </CODE_SNIPPET> 899*8c35d5eeSXin Li <p>Do not create local aliases of namespaces. Namespaces should only 900*8c35d5eeSXin Li be aliased using <a href="#goog-scope">goog.scope</a>.</p> 901*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 902*8c35d5eeSXin Li myapp.main = function() { 903*8c35d5eeSXin Li var namespace = some.long.namespace; 904*8c35d5eeSXin Li namespace.MyClass.staticHelper(new namespace.MyClass()); 905*8c35d5eeSXin Li }; 906*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 907*8c35d5eeSXin Li <p>Avoid accessing properties of an aliased type, unless it is an 908*8c35d5eeSXin Li enum.</p> 909*8c35d5eeSXin Li <CODE_SNIPPET> 910*8c35d5eeSXin Li /** @enum {string} */ 911*8c35d5eeSXin Li some.long.namespace.Fruit = { 912*8c35d5eeSXin Li APPLE: 'a', 913*8c35d5eeSXin Li BANANA: 'b' 914*8c35d5eeSXin Li }; 915*8c35d5eeSXin Li 916*8c35d5eeSXin Li myapp.main = function() { 917*8c35d5eeSXin Li var Fruit = some.long.namespace.Fruit; 918*8c35d5eeSXin Li switch (fruit) { 919*8c35d5eeSXin Li case Fruit.APPLE: 920*8c35d5eeSXin Li ... 921*8c35d5eeSXin Li case Fruit.BANANA: 922*8c35d5eeSXin Li ... 923*8c35d5eeSXin Li } 924*8c35d5eeSXin Li }; 925*8c35d5eeSXin Li </CODE_SNIPPET> 926*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 927*8c35d5eeSXin Li myapp.main = function() { 928*8c35d5eeSXin Li var MyClass = some.long.namespace.MyClass; 929*8c35d5eeSXin Li MyClass.staticHelper(null); 930*8c35d5eeSXin Li }; 931*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 932*8c35d5eeSXin Li <p>Never create aliases in the global scope. Use them only in 933*8c35d5eeSXin Li function blocks.</p> 934*8c35d5eeSXin Li </SUBSUBSECTION> 935*8c35d5eeSXin Li </SUBSECTION> 936*8c35d5eeSXin Li <SUBSECTION title="Filenames"> 937*8c35d5eeSXin Li <p>Filenames should be all lowercase in order to avoid confusion on 938*8c35d5eeSXin Li case-sensitive platforms. Filenames should end in <code>.js</code>, 939*8c35d5eeSXin Li and should contain no punctuation except for <code>-</code> or 940*8c35d5eeSXin Li <code>_</code> (prefer <code>-</code> to <code>_</code>).</p> 941*8c35d5eeSXin Li </SUBSECTION> 942*8c35d5eeSXin Li 943*8c35d5eeSXin Li </BODY> 944*8c35d5eeSXin Li </STYLEPOINT> 945*8c35d5eeSXin Li 946*8c35d5eeSXin Li <STYLEPOINT title="Custom toString() methods"> 947*8c35d5eeSXin Li <SUMMARY> 948*8c35d5eeSXin Li Must always succeed without side effects. 949*8c35d5eeSXin Li </SUMMARY> 950*8c35d5eeSXin Li <BODY> 951*8c35d5eeSXin Li <p>You can control how your objects string-ify themselves by defining a 952*8c35d5eeSXin Li custom <code>toString()</code> method. This is fine, but you need 953*8c35d5eeSXin Li to ensure that your method (1) always succeeds and (2) does not have 954*8c35d5eeSXin Li side-effects. If your method doesn't meet these criteria, it's very 955*8c35d5eeSXin Li easy to run into serious problems. For example, if 956*8c35d5eeSXin Li <code>toString()</code> calls a method that does an 957*8c35d5eeSXin Li <code>assert</code>, <code>assert</code> might try to output the name 958*8c35d5eeSXin Li of the object in which it failed, which of course requires calling 959*8c35d5eeSXin Li <code>toString()</code>.</p> 960*8c35d5eeSXin Li </BODY> 961*8c35d5eeSXin Li </STYLEPOINT> 962*8c35d5eeSXin Li 963*8c35d5eeSXin Li <STYLEPOINT title="Deferred initialization"> 964*8c35d5eeSXin Li <SUMMARY>OK</SUMMARY> 965*8c35d5eeSXin Li <BODY> 966*8c35d5eeSXin Li <p>It isn't always possible to initialize variables at the point of 967*8c35d5eeSXin Li declaration, so deferred initialization is fine.</p> 968*8c35d5eeSXin Li </BODY> 969*8c35d5eeSXin Li </STYLEPOINT> 970*8c35d5eeSXin Li 971*8c35d5eeSXin Li <STYLEPOINT title="Explicit scope"> 972*8c35d5eeSXin Li <SUMMARY>Always</SUMMARY> 973*8c35d5eeSXin Li <BODY> 974*8c35d5eeSXin Li <p>Always use explicit scope - doing so increases portability and 975*8c35d5eeSXin Li clarity. For example, don't rely on <code>window</code> being in the 976*8c35d5eeSXin Li scope chain. You might want to use your function in another 977*8c35d5eeSXin Li application for which <code>window</code> is not the content 978*8c35d5eeSXin Li window.</p> 979*8c35d5eeSXin Li </BODY> 980*8c35d5eeSXin Li </STYLEPOINT> 981*8c35d5eeSXin Li 982*8c35d5eeSXin Li <STYLEPOINT title="Code formatting"> 983*8c35d5eeSXin Li <SUMMARY>Expand for more information.</SUMMARY> 984*8c35d5eeSXin Li <BODY> 985*8c35d5eeSXin Li <p>We follow the <a href="cppguide.html#Formatting">C++ formatting 986*8c35d5eeSXin Li rules</a> in spirit, with the following additional clarifications.</p> 987*8c35d5eeSXin Li <SUBSECTION title="Curly Braces"> 988*8c35d5eeSXin Li <p>Because of implicit semicolon insertion, always start your curly 989*8c35d5eeSXin Li braces on the same line as whatever they're opening. For 990*8c35d5eeSXin Li example:</p> 991*8c35d5eeSXin Li <CODE_SNIPPET> 992*8c35d5eeSXin Li if (something) { 993*8c35d5eeSXin Li // ... 994*8c35d5eeSXin Li } else { 995*8c35d5eeSXin Li // ... 996*8c35d5eeSXin Li } 997*8c35d5eeSXin Li </CODE_SNIPPET> 998*8c35d5eeSXin Li </SUBSECTION> 999*8c35d5eeSXin Li <SUBSECTION title="Array and Object Initializers"> 1000*8c35d5eeSXin Li <p>Single-line array and object initializers are allowed when they 1001*8c35d5eeSXin Li fit on a line:</p> 1002*8c35d5eeSXin Li <CODE_SNIPPET> 1003*8c35d5eeSXin Li var arr = [1, 2, 3]; // No space after [ or before ]. 1004*8c35d5eeSXin Li var obj = {a: 1, b: 2, c: 3}; // No space after { or before }. 1005*8c35d5eeSXin Li </CODE_SNIPPET> 1006*8c35d5eeSXin Li <p>Multiline array initializers and object initializers are indented 1007*8c35d5eeSXin Li 2 spaces, with the braces on their own line, just like blocks.</p> 1008*8c35d5eeSXin Li <CODE_SNIPPET> 1009*8c35d5eeSXin Li // Object initializer. 1010*8c35d5eeSXin Li var inset = { 1011*8c35d5eeSXin Li top: 10, 1012*8c35d5eeSXin Li right: 20, 1013*8c35d5eeSXin Li bottom: 15, 1014*8c35d5eeSXin Li left: 12 1015*8c35d5eeSXin Li }; 1016*8c35d5eeSXin Li 1017*8c35d5eeSXin Li // Array initializer. 1018*8c35d5eeSXin Li this.rows_ = [ 1019*8c35d5eeSXin Li '"Slartibartfast" <[email protected]>', 1020*8c35d5eeSXin Li '"Zaphod Beeblebrox" <[email protected]>', 1021*8c35d5eeSXin Li '"Ford Prefect" <[email protected]>', 1022*8c35d5eeSXin Li '"Arthur Dent" <[email protected]>', 1023*8c35d5eeSXin Li '"Marvin the Paranoid Android" <[email protected]>', 1024*8c35d5eeSXin Li '[email protected]' 1025*8c35d5eeSXin Li ]; 1026*8c35d5eeSXin Li 1027*8c35d5eeSXin Li // Used in a method call. 1028*8c35d5eeSXin Li goog.dom.createDom(goog.dom.TagName.DIV, { 1029*8c35d5eeSXin Li id: 'foo', 1030*8c35d5eeSXin Li className: 'some-css-class', 1031*8c35d5eeSXin Li style: 'display:none' 1032*8c35d5eeSXin Li }, 'Hello, world!'); 1033*8c35d5eeSXin Li </CODE_SNIPPET> 1034*8c35d5eeSXin Li <p>Long identifiers or values present problems for aligned 1035*8c35d5eeSXin Li initialization lists, so always prefer non-aligned initialization. 1036*8c35d5eeSXin Li For example:</p> 1037*8c35d5eeSXin Li <CODE_SNIPPET> 1038*8c35d5eeSXin Li CORRECT_Object.prototype = { 1039*8c35d5eeSXin Li a: 0, 1040*8c35d5eeSXin Li b: 1, 1041*8c35d5eeSXin Li lengthyName: 2 1042*8c35d5eeSXin Li }; 1043*8c35d5eeSXin Li </CODE_SNIPPET> 1044*8c35d5eeSXin Li <p>Not like this:</p> 1045*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 1046*8c35d5eeSXin Li WRONG_Object.prototype = { 1047*8c35d5eeSXin Li a : 0, 1048*8c35d5eeSXin Li b : 1, 1049*8c35d5eeSXin Li lengthyName: 2 1050*8c35d5eeSXin Li }; 1051*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 1052*8c35d5eeSXin Li </SUBSECTION> 1053*8c35d5eeSXin Li <SUBSECTION title="Function Arguments"> 1054*8c35d5eeSXin Li <p>When possible, all function arguments should be listed on the same 1055*8c35d5eeSXin Li line. If doing so would exceed the 80-column limit, the arguments 1056*8c35d5eeSXin Li must be line-wrapped in a readable way. To save space, you may wrap 1057*8c35d5eeSXin Li as close to 80 as possible, or put each argument on its own line to 1058*8c35d5eeSXin Li enhance readability. The indentation may be either four spaces, or 1059*8c35d5eeSXin Li aligned to the parenthesis. Below are the most common patterns for 1060*8c35d5eeSXin Li argument wrapping:</p> 1061*8c35d5eeSXin Li <CODE_SNIPPET> 1062*8c35d5eeSXin Li // Four-space, wrap at 80. Works with very long function names, survives 1063*8c35d5eeSXin Li // renaming without reindenting, low on space. 1064*8c35d5eeSXin Li goog.foo.bar.doThingThatIsVeryDifficultToExplain = function( 1065*8c35d5eeSXin Li veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, 1066*8c35d5eeSXin Li tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) { 1067*8c35d5eeSXin Li // ... 1068*8c35d5eeSXin Li }; 1069*8c35d5eeSXin Li 1070*8c35d5eeSXin Li // Four-space, one argument per line. Works with long function names, 1071*8c35d5eeSXin Li // survives renaming, and emphasizes each argument. 1072*8c35d5eeSXin Li goog.foo.bar.doThingThatIsVeryDifficultToExplain = function( 1073*8c35d5eeSXin Li veryDescriptiveArgumentNumberOne, 1074*8c35d5eeSXin Li veryDescriptiveArgumentTwo, 1075*8c35d5eeSXin Li tableModelEventHandlerProxy, 1076*8c35d5eeSXin Li artichokeDescriptorAdapterIterator) { 1077*8c35d5eeSXin Li // ... 1078*8c35d5eeSXin Li }; 1079*8c35d5eeSXin Li 1080*8c35d5eeSXin Li // Parenthesis-aligned indentation, wrap at 80. Visually groups arguments, 1081*8c35d5eeSXin Li // low on space. 1082*8c35d5eeSXin Li function foo(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, 1083*8c35d5eeSXin Li tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) { 1084*8c35d5eeSXin Li // ... 1085*8c35d5eeSXin Li } 1086*8c35d5eeSXin Li 1087*8c35d5eeSXin Li // Parenthesis-aligned, one argument per line. Emphasizes each 1088*8c35d5eeSXin Li // individual argument. 1089*8c35d5eeSXin Li function bar(veryDescriptiveArgumentNumberOne, 1090*8c35d5eeSXin Li veryDescriptiveArgumentTwo, 1091*8c35d5eeSXin Li tableModelEventHandlerProxy, 1092*8c35d5eeSXin Li artichokeDescriptorAdapterIterator) { 1093*8c35d5eeSXin Li // ... 1094*8c35d5eeSXin Li } 1095*8c35d5eeSXin Li </CODE_SNIPPET> 1096*8c35d5eeSXin Li <p>When the function call is itself indented, you're free to start the 1097*8c35d5eeSXin Li 4-space indent relative to the beginning of the original statement 1098*8c35d5eeSXin Li or relative to the beginning of the current function call. 1099*8c35d5eeSXin Li The following are all acceptable indentation styles.</p> 1100*8c35d5eeSXin Li <CODE_SNIPPET> 1101*8c35d5eeSXin Li if (veryLongFunctionNameA( 1102*8c35d5eeSXin Li veryLongArgumentName) || 1103*8c35d5eeSXin Li veryLongFunctionNameB( 1104*8c35d5eeSXin Li veryLongArgumentName)) { 1105*8c35d5eeSXin Li veryLongFunctionNameC(veryLongFunctionNameD( 1106*8c35d5eeSXin Li veryLongFunctioNameE( 1107*8c35d5eeSXin Li veryLongFunctionNameF))); 1108*8c35d5eeSXin Li } 1109*8c35d5eeSXin Li </CODE_SNIPPET> 1110*8c35d5eeSXin Li </SUBSECTION> 1111*8c35d5eeSXin Li <SUBSECTION title="Passing Anonymous Functions"> 1112*8c35d5eeSXin Li <p>When declaring an anonymous function in the list of arguments for 1113*8c35d5eeSXin Li a function call, the body of the function is indented two spaces 1114*8c35d5eeSXin Li from the left edge of the statement, or two spaces from the left 1115*8c35d5eeSXin Li edge of the function keyword. This is to make the body of the 1116*8c35d5eeSXin Li anonymous function easier to read (i.e. not be all squished up into 1117*8c35d5eeSXin Li the right half of the screen).</p> 1118*8c35d5eeSXin Li <CODE_SNIPPET> 1119*8c35d5eeSXin Li prefix.something.reallyLongFunctionName('whatever', function(a1, a2) { 1120*8c35d5eeSXin Li if (a1.equals(a2)) { 1121*8c35d5eeSXin Li someOtherLongFunctionName(a1); 1122*8c35d5eeSXin Li } else { 1123*8c35d5eeSXin Li andNowForSomethingCompletelyDifferent(a2.parrot); 1124*8c35d5eeSXin Li } 1125*8c35d5eeSXin Li }); 1126*8c35d5eeSXin Li 1127*8c35d5eeSXin Li var names = prefix.something.myExcellentMapFunction( 1128*8c35d5eeSXin Li verboselyNamedCollectionOfItems, 1129*8c35d5eeSXin Li function(item) { 1130*8c35d5eeSXin Li return item.name; 1131*8c35d5eeSXin Li }); 1132*8c35d5eeSXin Li </CODE_SNIPPET> 1133*8c35d5eeSXin Li </SUBSECTION> 1134*8c35d5eeSXin Li <SUBSECTION title="Aliasing with goog.scope"> 1135*8c35d5eeSXin Li <a name="goog-scope"/> 1136*8c35d5eeSXin Li <p> 1137*8c35d5eeSXin Li <a href="https://docs.google.com/document/pub?id=1ETFAuh2kaXMVL-vafUYhaWlhl6b5D9TOvboVg7Zl68Y"><code>goog.scope</code></a> 1138*8c35d5eeSXin Li may be used to shorten references to 1139*8c35d5eeSXin Li namespaced symbols in programs using 1140*8c35d5eeSXin Li <a href="https://code.google.com/closure/library/">the Closure 1141*8c35d5eeSXin Li Library</a>.</p> 1142*8c35d5eeSXin Li <p>Only one <code>goog.scope</code> invocation may be added per 1143*8c35d5eeSXin Li file. Always place it in the global scope.</p> 1144*8c35d5eeSXin Li <p>The opening <code>goog.scope(function() {</code> invocation 1145*8c35d5eeSXin Li must be preceded by exactly one blank line and follow any 1146*8c35d5eeSXin Li <code>goog.provide</code> statements, <code>goog.require</code> 1147*8c35d5eeSXin Li statements, or top-level comments. The invocation must be closed on 1148*8c35d5eeSXin Li the last line in the file. Append <code>// goog.scope</code> to the 1149*8c35d5eeSXin Li closing statement of the scope. Separate the comment from the 1150*8c35d5eeSXin Li semicolon by two spaces.</p> 1151*8c35d5eeSXin Li <p>Similar to C++ namespaces, do not indent under goog.scope 1152*8c35d5eeSXin Li declarations. Instead, continue from the 0 column.</p> 1153*8c35d5eeSXin Li <p>Only alias names that will not be re-assigned to another object 1154*8c35d5eeSXin Li (e.g., most constructors, enums, and namespaces). Do not do 1155*8c35d5eeSXin Li this (see below for how to alias a constructor):</p> 1156*8c35d5eeSXin Li 1157*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 1158*8c35d5eeSXin Li goog.scope(function() { 1159*8c35d5eeSXin Li var Button = goog.ui.Button; 1160*8c35d5eeSXin Li 1161*8c35d5eeSXin Li Button = function() { ... }; 1162*8c35d5eeSXin Li ... 1163*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 1164*8c35d5eeSXin Li 1165*8c35d5eeSXin Li <p>Names must be the same as the last property of the global that they 1166*8c35d5eeSXin Li are aliasing.</p> 1167*8c35d5eeSXin Li 1168*8c35d5eeSXin Li <CODE_SNIPPET> 1169*8c35d5eeSXin Li goog.provide('my.module.SomeType'); 1170*8c35d5eeSXin Li 1171*8c35d5eeSXin Li goog.require('goog.dom'); 1172*8c35d5eeSXin Li goog.require('goog.ui.Button'); 1173*8c35d5eeSXin Li 1174*8c35d5eeSXin Li goog.scope(function() { 1175*8c35d5eeSXin Li var Button = goog.ui.Button; 1176*8c35d5eeSXin Li var dom = goog.dom; 1177*8c35d5eeSXin Li 1178*8c35d5eeSXin Li // Alias new types <b>after</b> the constructor declaration. 1179*8c35d5eeSXin Li my.module.SomeType = function() { ... }; 1180*8c35d5eeSXin Li var SomeType = my.module.SomeType; 1181*8c35d5eeSXin Li 1182*8c35d5eeSXin Li // Declare methods on the prototype as usual: 1183*8c35d5eeSXin Li SomeType.prototype.findButton = function() { 1184*8c35d5eeSXin Li // Button as aliased above. 1185*8c35d5eeSXin Li this.button = new Button(dom.getElement('my-button')); 1186*8c35d5eeSXin Li }; 1187*8c35d5eeSXin Li ... 1188*8c35d5eeSXin Li }); // goog.scope 1189*8c35d5eeSXin Li </CODE_SNIPPET> 1190*8c35d5eeSXin Li </SUBSECTION> 1191*8c35d5eeSXin Li <SUBSECTION title="Indenting wrapped lines"> 1192*8c35d5eeSXin Li <p>Except for <a href="#Array_and_Object_literals">array literals, 1193*8c35d5eeSXin Li object literals</a>, and anonymous functions, all wrapped lines 1194*8c35d5eeSXin Li should be indented either left-aligned to a sibling expression 1195*8c35d5eeSXin Li above, or four spaces (not two spaces) deeper than a parent 1196*8c35d5eeSXin Li expression (where "sibling" and "parent" refer to parenthesis 1197*8c35d5eeSXin Li nesting level). 1198*8c35d5eeSXin Li </p> 1199*8c35d5eeSXin Li 1200*8c35d5eeSXin Li <CODE_SNIPPET> 1201*8c35d5eeSXin Li someWonderfulHtml = '<div class="' + getClassesForWonderfulHtml()'">' + 1202*8c35d5eeSXin Li getEvenMoreHtml(someReallyInterestingValues, moreValues, 1203*8c35d5eeSXin Li evenMoreParams, 'a duck', true, 72, 1204*8c35d5eeSXin Li slightlyMoreMonkeys(0xfff)) + 1205*8c35d5eeSXin Li '</div>'; 1206*8c35d5eeSXin Li 1207*8c35d5eeSXin Li thisIsAVeryLongVariableName = 1208*8c35d5eeSXin Li hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine(); 1209*8c35d5eeSXin Li 1210*8c35d5eeSXin Li thisIsAVeryLongVariableName = siblingOne + siblingTwo + siblingThree + 1211*8c35d5eeSXin Li siblingFour + siblingFive + siblingSix + siblingSeven + 1212*8c35d5eeSXin Li moreSiblingExpressions + allAtTheSameIndentationLevel; 1213*8c35d5eeSXin Li 1214*8c35d5eeSXin Li thisIsAVeryLongVariableName = operandOne + operandTwo + operandThree + 1215*8c35d5eeSXin Li operandFour + operandFive * ( 1216*8c35d5eeSXin Li aNestedChildExpression + shouldBeIndentedMore); 1217*8c35d5eeSXin Li 1218*8c35d5eeSXin Li someValue = this.foo( 1219*8c35d5eeSXin Li shortArg, 1220*8c35d5eeSXin Li 'Some really long string arg - this is a pretty common case, actually.', 1221*8c35d5eeSXin Li shorty2, 1222*8c35d5eeSXin Li this.bar()); 1223*8c35d5eeSXin Li 1224*8c35d5eeSXin Li if (searchableCollection(allYourStuff).contains(theStuffYouWant) && 1225*8c35d5eeSXin Li !ambientNotification.isActive() && (client.isAmbientSupported() || 1226*8c35d5eeSXin Li client.alwaysTryAmbientAnyways())) { 1227*8c35d5eeSXin Li ambientNotification.activate(); 1228*8c35d5eeSXin Li } 1229*8c35d5eeSXin Li </CODE_SNIPPET> 1230*8c35d5eeSXin Li </SUBSECTION> 1231*8c35d5eeSXin Li <SUBSECTION title="Blank lines"> 1232*8c35d5eeSXin Li <p>Use newlines to group logically related pieces of code. 1233*8c35d5eeSXin Li For example:</p> 1234*8c35d5eeSXin Li <CODE_SNIPPET> 1235*8c35d5eeSXin Li doSomethingTo(x); 1236*8c35d5eeSXin Li doSomethingElseTo(x); 1237*8c35d5eeSXin Li andThen(x); 1238*8c35d5eeSXin Li 1239*8c35d5eeSXin Li nowDoSomethingWith(y); 1240*8c35d5eeSXin Li 1241*8c35d5eeSXin Li andNowWith(z); 1242*8c35d5eeSXin Li </CODE_SNIPPET> 1243*8c35d5eeSXin Li </SUBSECTION> 1244*8c35d5eeSXin Li <SUBSECTION title="Binary and Ternary Operators"> 1245*8c35d5eeSXin Li <p>Always put the operator on the preceding line. Otherwise, 1246*8c35d5eeSXin Li line breaks and indentation follow the same rules as in other 1247*8c35d5eeSXin Li Google style guides. This operator placement was initially agreed 1248*8c35d5eeSXin Li upon out of concerns about automatic semicolon insertion. In fact, 1249*8c35d5eeSXin Li semicolon insertion cannot happen before a binary operator, but new 1250*8c35d5eeSXin Li code should stick to this style for consistency.</p> 1251*8c35d5eeSXin Li <CODE_SNIPPET> 1252*8c35d5eeSXin Li var x = a ? b : c; // All on one line if it will fit. 1253*8c35d5eeSXin Li 1254*8c35d5eeSXin Li // Indentation +4 is OK. 1255*8c35d5eeSXin Li var y = a ? 1256*8c35d5eeSXin Li longButSimpleOperandB : longButSimpleOperandC; 1257*8c35d5eeSXin Li 1258*8c35d5eeSXin Li // Indenting to the line position of the first operand is also OK. 1259*8c35d5eeSXin Li var z = a ? 1260*8c35d5eeSXin Li moreComplicatedB : 1261*8c35d5eeSXin Li moreComplicatedC; 1262*8c35d5eeSXin Li </CODE_SNIPPET> 1263*8c35d5eeSXin Li <p>This includes the dot operator.</p> 1264*8c35d5eeSXin Li <CODE_SNIPPET> 1265*8c35d5eeSXin Li var x = foo.bar(). 1266*8c35d5eeSXin Li doSomething(). 1267*8c35d5eeSXin Li doSomethingElse(); 1268*8c35d5eeSXin Li </CODE_SNIPPET> 1269*8c35d5eeSXin Li </SUBSECTION> 1270*8c35d5eeSXin Li </BODY> 1271*8c35d5eeSXin Li </STYLEPOINT> 1272*8c35d5eeSXin Li 1273*8c35d5eeSXin Li <STYLEPOINT title="Parentheses"> 1274*8c35d5eeSXin Li <SUMMARY>Only where required</SUMMARY> 1275*8c35d5eeSXin Li <BODY> 1276*8c35d5eeSXin Li <p>Use sparingly and in general only where required by the syntax 1277*8c35d5eeSXin Li and semantics.</p> 1278*8c35d5eeSXin Li <p>Never use parentheses for unary operators such as 1279*8c35d5eeSXin Li <code>delete</code>, <code>typeof</code> and <code>void</code> or 1280*8c35d5eeSXin Li after keywords such as <code>return</code>, <code>throw</code> as 1281*8c35d5eeSXin Li well as others (<code>case</code>, <code>in</code> or 1282*8c35d5eeSXin Li <code>new</code>).</p> 1283*8c35d5eeSXin Li </BODY> 1284*8c35d5eeSXin Li </STYLEPOINT> 1285*8c35d5eeSXin Li 1286*8c35d5eeSXin Li <STYLEPOINT title="Strings"> 1287*8c35d5eeSXin Li <SUMMARY>Prefer ' over "</SUMMARY> 1288*8c35d5eeSXin Li <BODY> 1289*8c35d5eeSXin Li <p>For consistency single-quotes (') are preferred to double-quotes ("). 1290*8c35d5eeSXin Li This is helpful when creating strings that include HTML:</p> 1291*8c35d5eeSXin Li <CODE_SNIPPET> 1292*8c35d5eeSXin Li var msg = 'This is <a href="http://foo">some HTML</a>'; 1293*8c35d5eeSXin Li </CODE_SNIPPET> 1294*8c35d5eeSXin Li </BODY> 1295*8c35d5eeSXin Li </STYLEPOINT> 1296*8c35d5eeSXin Li 1297*8c35d5eeSXin Li <STYLEPOINT title="Visibility (private and protected fields)"> 1298*8c35d5eeSXin Li <SUMMARY>Encouraged, use JSDoc annotations <code>@private</code> and 1299*8c35d5eeSXin Li <code>@protected</code></SUMMARY> 1300*8c35d5eeSXin Li <BODY> 1301*8c35d5eeSXin Li <p>We recommend the use of the JSDoc annotations <code>@private</code> and 1302*8c35d5eeSXin Li <code>@protected</code> to indicate visibility levels for classes, 1303*8c35d5eeSXin Li functions, and properties.</p> 1304*8c35d5eeSXin Li <p>The --jscomp_warning=visibility compiler flag turns on compiler 1305*8c35d5eeSXin Li warnings for visibility violations. See 1306*8c35d5eeSXin Li <a href="https://code.google.com/p/closure-compiler/wiki/Warnings"> 1307*8c35d5eeSXin Li Closure Compiler 1308*8c35d5eeSXin Li Warnings</a>. 1309*8c35d5eeSXin Li </p> 1310*8c35d5eeSXin Li <p><code>@private</code> global variables and functions are only 1311*8c35d5eeSXin Li accessible to code in the same file.</p> 1312*8c35d5eeSXin Li <p>Constructors marked <code>@private</code> may only be instantiated by 1313*8c35d5eeSXin Li code in the same file and by their static and instance members. 1314*8c35d5eeSXin Li <code>@private</code> constructors may also be accessed anywhere in the 1315*8c35d5eeSXin Li same file for their public static properties and by the 1316*8c35d5eeSXin Li <code>instanceof</code> operator.</p> 1317*8c35d5eeSXin Li <p>Global variables, functions, and constructors should never be 1318*8c35d5eeSXin Li annotated <code>@protected</code>.</p> 1319*8c35d5eeSXin Li <CODE_SNIPPET> 1320*8c35d5eeSXin Li // File 1. 1321*8c35d5eeSXin Li // AA_PrivateClass_ and AA_init_ are accessible because they are global 1322*8c35d5eeSXin Li // and in the same file. 1323*8c35d5eeSXin Li 1324*8c35d5eeSXin Li /** 1325*8c35d5eeSXin Li * @private 1326*8c35d5eeSXin Li * @constructor 1327*8c35d5eeSXin Li */ 1328*8c35d5eeSXin Li AA_PrivateClass_ = function() { 1329*8c35d5eeSXin Li }; 1330*8c35d5eeSXin Li 1331*8c35d5eeSXin Li /** @private */ 1332*8c35d5eeSXin Li function AA_init_() { 1333*8c35d5eeSXin Li return new AA_PrivateClass_(); 1334*8c35d5eeSXin Li } 1335*8c35d5eeSXin Li 1336*8c35d5eeSXin Li AA_init_(); 1337*8c35d5eeSXin Li </CODE_SNIPPET> 1338*8c35d5eeSXin Li <p><code>@private</code> properties are accessible to all code in the 1339*8c35d5eeSXin Li same file, plus all static methods and instance methods of that class 1340*8c35d5eeSXin Li that "owns" the property, if the property belongs to a class. They 1341*8c35d5eeSXin Li cannot be accessed or overridden from a subclass in a different file.</p> 1342*8c35d5eeSXin Li <p><code>@protected</code> properties are accessible to all code in the 1343*8c35d5eeSXin Li same file, plus any static methods and instance methods of any subclass 1344*8c35d5eeSXin Li of a class that "owns" the property.</p> 1345*8c35d5eeSXin Li <p>Note that these semantics differ from those of C++ and Java, in that 1346*8c35d5eeSXin Li they grant private and protected access to all code in the same file, 1347*8c35d5eeSXin Li not just in the same class or class hierarchy. Also, unlike in C++, 1348*8c35d5eeSXin Li private properties cannot be overridden by a subclass. 1349*8c35d5eeSXin Li </p> 1350*8c35d5eeSXin Li <CODE_SNIPPET> 1351*8c35d5eeSXin Li // File 1. 1352*8c35d5eeSXin Li 1353*8c35d5eeSXin Li /** @constructor */ 1354*8c35d5eeSXin Li AA_PublicClass = function() { 1355*8c35d5eeSXin Li /** @private */ 1356*8c35d5eeSXin Li this.privateProp_ = 2; 1357*8c35d5eeSXin Li 1358*8c35d5eeSXin Li /** @protected */ 1359*8c35d5eeSXin Li this.protectedProp = 4; 1360*8c35d5eeSXin Li }; 1361*8c35d5eeSXin Li 1362*8c35d5eeSXin Li /** @private */ 1363*8c35d5eeSXin Li AA_PublicClass.staticPrivateProp_ = 1; 1364*8c35d5eeSXin Li 1365*8c35d5eeSXin Li /** @protected */ 1366*8c35d5eeSXin Li AA_PublicClass.staticProtectedProp = 31; 1367*8c35d5eeSXin Li 1368*8c35d5eeSXin Li /** @private */ 1369*8c35d5eeSXin Li AA_PublicClass.prototype.privateMethod_ = function() {}; 1370*8c35d5eeSXin Li 1371*8c35d5eeSXin Li /** @protected */ 1372*8c35d5eeSXin Li AA_PublicClass.prototype.protectedMethod = function() {}; 1373*8c35d5eeSXin Li 1374*8c35d5eeSXin Li // File 2. 1375*8c35d5eeSXin Li 1376*8c35d5eeSXin Li /** 1377*8c35d5eeSXin Li * @return {number} The number of ducks we've arranged in a row. 1378*8c35d5eeSXin Li */ 1379*8c35d5eeSXin Li AA_PublicClass.prototype.method = function() { 1380*8c35d5eeSXin Li // Legal accesses of these two properties. 1381*8c35d5eeSXin Li return this.privateProp_ + AA_PublicClass.staticPrivateProp_; 1382*8c35d5eeSXin Li }; 1383*8c35d5eeSXin Li 1384*8c35d5eeSXin Li // File 3. 1385*8c35d5eeSXin Li 1386*8c35d5eeSXin Li /** 1387*8c35d5eeSXin Li * @constructor 1388*8c35d5eeSXin Li * @extends {AA_PublicClass} 1389*8c35d5eeSXin Li */ 1390*8c35d5eeSXin Li AA_SubClass = function() { 1391*8c35d5eeSXin Li // Legal access of a protected static property. 1392*8c35d5eeSXin Li AA_PublicClass.staticProtectedProp = this.method(); 1393*8c35d5eeSXin Li }; 1394*8c35d5eeSXin Li goog.inherits(AA_SubClass, AA_PublicClass); 1395*8c35d5eeSXin Li 1396*8c35d5eeSXin Li /** 1397*8c35d5eeSXin Li * @return {number} The number of ducks we've arranged in a row. 1398*8c35d5eeSXin Li */ 1399*8c35d5eeSXin Li AA_SubClass.prototype.method = function() { 1400*8c35d5eeSXin Li // Legal access of a protected instance property. 1401*8c35d5eeSXin Li return this.protectedProp; 1402*8c35d5eeSXin Li }; 1403*8c35d5eeSXin Li </CODE_SNIPPET> 1404*8c35d5eeSXin Li 1405*8c35d5eeSXin Li <p>Notice that in JavaScript, there is no distinction between a type 1406*8c35d5eeSXin Li (like <code>AA_PrivateClass_</code>) and the constructor for that 1407*8c35d5eeSXin Li type. There is no way to express both that a type is public and its 1408*8c35d5eeSXin Li constructor is private (because the constructor could easily be aliased 1409*8c35d5eeSXin Li in a way that would defeat the privacy check).</p> 1410*8c35d5eeSXin Li </BODY> 1411*8c35d5eeSXin Li </STYLEPOINT> 1412*8c35d5eeSXin Li 1413*8c35d5eeSXin Li <STYLEPOINT title="JavaScript Types"> 1414*8c35d5eeSXin Li <SUMMARY>Encouraged and enforced by the compiler.</SUMMARY> 1415*8c35d5eeSXin Li <BODY> 1416*8c35d5eeSXin Li <a name="JsTypes"/> 1417*8c35d5eeSXin Li <p>When documenting a type in JSDoc, be as specific and accurate as 1418*8c35d5eeSXin Li possible. The types we support are based on the 1419*8c35d5eeSXin Li <a href="http://wiki.ecmascript.org/doku.php?id=spec:spec"> 1420*8c35d5eeSXin Li EcmaScript 4 spec</a>.</p> 1421*8c35d5eeSXin Li <SUBSECTION title="The JavaScript Type Language"> 1422*8c35d5eeSXin Li <p>The ES4 proposal contained a language for specifying JavaScript 1423*8c35d5eeSXin Li types. We use this language in JsDoc to express the types of 1424*8c35d5eeSXin Li function parameters and return values.</p> 1425*8c35d5eeSXin Li 1426*8c35d5eeSXin Li <p>As the ES4 proposal has evolved, this language has changed. The 1427*8c35d5eeSXin Li compiler still supports old syntaxes for types, but those syntaxes 1428*8c35d5eeSXin Li are deprecated.</p> 1429*8c35d5eeSXin Li 1430*8c35d5eeSXin Li <p/> 1431*8c35d5eeSXin Li <table border="1" style="border-collapse:collapse" cellpadding="4"> 1432*8c35d5eeSXin Li <thead> 1433*8c35d5eeSXin Li <tr> 1434*8c35d5eeSXin Li <th>Syntax Name</th> 1435*8c35d5eeSXin Li <th>Syntax</th> 1436*8c35d5eeSXin Li <th>Description</th> 1437*8c35d5eeSXin Li <th>Deprecated Syntaxes</th> 1438*8c35d5eeSXin Li </tr> 1439*8c35d5eeSXin Li </thead> 1440*8c35d5eeSXin Li <tbody> 1441*8c35d5eeSXin Li <tr> 1442*8c35d5eeSXin Li <td>Primitive Type</td> 1443*8c35d5eeSXin Li <td> 1444*8c35d5eeSXin Li There are 5 primitive types in JavaScript: 1445*8c35d5eeSXin Li <code>{null}</code>, 1446*8c35d5eeSXin Li <code>{undefined}</code>, 1447*8c35d5eeSXin Li <code>{boolean}</code>, 1448*8c35d5eeSXin Li <code>{number}</code>, and 1449*8c35d5eeSXin Li <code>{string}</code>. 1450*8c35d5eeSXin Li </td> 1451*8c35d5eeSXin Li <td>Simply the name of a type.</td> 1452*8c35d5eeSXin Li <td/> 1453*8c35d5eeSXin Li </tr> 1454*8c35d5eeSXin Li 1455*8c35d5eeSXin Li <tr> 1456*8c35d5eeSXin Li <td>Instance Type</td> 1457*8c35d5eeSXin Li <td> 1458*8c35d5eeSXin Li <code>{Object}</code><br/> 1459*8c35d5eeSXin Li An instance of Object or null.<p/> 1460*8c35d5eeSXin Li <code>{Function}</code><br/> 1461*8c35d5eeSXin Li An instance of Function or null.<p/> 1462*8c35d5eeSXin Li <code>{EventTarget}</code><br/> 1463*8c35d5eeSXin Li An instance of a constructor that implements the EventTarget 1464*8c35d5eeSXin Li interface, or null. 1465*8c35d5eeSXin Li </td> 1466*8c35d5eeSXin Li <td>An instance of a constructor or interface function.<p/> 1467*8c35d5eeSXin Li 1468*8c35d5eeSXin Li Constructor functions are functions defined with the 1469*8c35d5eeSXin Li <code>@constructor</code> JSDoc tag. 1470*8c35d5eeSXin Li Interface functions are functions defined with the 1471*8c35d5eeSXin Li <code>@interface</code> JSDoc tag.<p/> 1472*8c35d5eeSXin Li 1473*8c35d5eeSXin Li By default, instance types will accept null. This is the only 1474*8c35d5eeSXin Li type syntax that makes the type nullable. Other type syntaxes 1475*8c35d5eeSXin Li in this table will not accept null. 1476*8c35d5eeSXin Li </td> 1477*8c35d5eeSXin Li <td/> 1478*8c35d5eeSXin Li </tr> 1479*8c35d5eeSXin Li 1480*8c35d5eeSXin Li <tr> 1481*8c35d5eeSXin Li <td>Enum Type</td> 1482*8c35d5eeSXin Li <td> 1483*8c35d5eeSXin Li <code>{goog.events.EventType}</code><br/> 1484*8c35d5eeSXin Li One of the properties of the object literal initializer 1485*8c35d5eeSXin Li of <code>goog.events.EventType</code>. 1486*8c35d5eeSXin Li </td> 1487*8c35d5eeSXin Li <td>An enum must be initialized as an object literal, or as 1488*8c35d5eeSXin Li an alias of another enum, annotated with the <code>@enum</code> 1489*8c35d5eeSXin Li JSDoc tag. The properties of this literal are the instances 1490*8c35d5eeSXin Li of the enum. The syntax of the enum is defined 1491*8c35d5eeSXin Li <a href="#enums">below</a>.<p/> 1492*8c35d5eeSXin Li 1493*8c35d5eeSXin Li Note that this is one of the few things in our type system 1494*8c35d5eeSXin Li that were not in the ES4 spec. 1495*8c35d5eeSXin Li </td> 1496*8c35d5eeSXin Li <td/> 1497*8c35d5eeSXin Li </tr> 1498*8c35d5eeSXin Li 1499*8c35d5eeSXin Li <tr> 1500*8c35d5eeSXin Li <td>Type Application</td> 1501*8c35d5eeSXin Li <td> 1502*8c35d5eeSXin Li <code>{Array.<string>}</code><br/>An array of strings.<p/> 1503*8c35d5eeSXin Li <code>{Object.<string, number>}</code> 1504*8c35d5eeSXin Li <br/>An object in which the keys are strings and the values 1505*8c35d5eeSXin Li are numbers. 1506*8c35d5eeSXin Li </td> 1507*8c35d5eeSXin Li <td>Parameterizes a type, by applying a set of type arguments 1508*8c35d5eeSXin Li to that type. The idea is analogous to generics in Java. 1509*8c35d5eeSXin Li </td> 1510*8c35d5eeSXin Li <td/> 1511*8c35d5eeSXin Li </tr> 1512*8c35d5eeSXin Li 1513*8c35d5eeSXin Li <tr> 1514*8c35d5eeSXin Li <td>Type Union</td> 1515*8c35d5eeSXin Li <td> 1516*8c35d5eeSXin Li <code>{(number|boolean)}</code><br/>A number or a boolean. 1517*8c35d5eeSXin Li </td> 1518*8c35d5eeSXin Li <td>Indicates that a value might have type A OR type B.<p/> 1519*8c35d5eeSXin Li 1520*8c35d5eeSXin Li The parentheses may be omitted at the top-level 1521*8c35d5eeSXin Li expression, but the parentheses should be included in 1522*8c35d5eeSXin Li sub-expressions to avoid ambiguity.<br/> 1523*8c35d5eeSXin Li <code>{number|boolean}</code><br/> 1524*8c35d5eeSXin Li <code>{function(): (number|boolean)}</code> 1525*8c35d5eeSXin Li </td> 1526*8c35d5eeSXin Li <td> 1527*8c35d5eeSXin Li <code>{(number,boolean)}</code>,<br/> 1528*8c35d5eeSXin Li <code>{(number||boolean)}</code> 1529*8c35d5eeSXin Li </td> 1530*8c35d5eeSXin Li </tr> 1531*8c35d5eeSXin Li 1532*8c35d5eeSXin Li <tr> 1533*8c35d5eeSXin Li <td>Nullable type</td> 1534*8c35d5eeSXin Li <td> 1535*8c35d5eeSXin Li <code>{?number}</code><br/> A number or null. 1536*8c35d5eeSXin Li </td> 1537*8c35d5eeSXin Li <td>Shorthand for the union of the null type with any 1538*8c35d5eeSXin Li other type. This is just syntactic sugar. 1539*8c35d5eeSXin Li </td> 1540*8c35d5eeSXin Li <td> 1541*8c35d5eeSXin Li <code>{number?}</code> 1542*8c35d5eeSXin Li </td> 1543*8c35d5eeSXin Li </tr> 1544*8c35d5eeSXin Li 1545*8c35d5eeSXin Li <tr> 1546*8c35d5eeSXin Li <td>Non-nullable type</td> 1547*8c35d5eeSXin Li <td> 1548*8c35d5eeSXin Li <code>{!Object}</code><br/> An Object, but never the 1549*8c35d5eeSXin Li <code>null</code> value. 1550*8c35d5eeSXin Li </td> 1551*8c35d5eeSXin Li <td>Filters null out of nullable types. Most often used 1552*8c35d5eeSXin Li with instance types, which are nullable by default. 1553*8c35d5eeSXin Li </td> 1554*8c35d5eeSXin Li <td> 1555*8c35d5eeSXin Li <code>{Object!}</code> 1556*8c35d5eeSXin Li </td> 1557*8c35d5eeSXin Li </tr> 1558*8c35d5eeSXin Li 1559*8c35d5eeSXin Li <tr> 1560*8c35d5eeSXin Li <td>Record Type</td> 1561*8c35d5eeSXin Li <td> 1562*8c35d5eeSXin Li <code>{{myNum: number, myObject}}</code> 1563*8c35d5eeSXin Li <br/>An anonymous type with the given type members. 1564*8c35d5eeSXin Li </td> 1565*8c35d5eeSXin Li <td> 1566*8c35d5eeSXin Li <p>Indicates that the value has the specified members with the 1567*8c35d5eeSXin Li specified types. In this case, <code>myNum</code> with a 1568*8c35d5eeSXin Li type <code>number</code> and <code>myObject</code> with any 1569*8c35d5eeSXin Li type.</p> 1570*8c35d5eeSXin Li <p>Notice that the braces are part of the type syntax. For 1571*8c35d5eeSXin Li example, to denote an <code>Array</code> of objects that 1572*8c35d5eeSXin Li have a <code>length</code> property, you might write 1573*8c35d5eeSXin Li <code>Array.<{length}></code>.</p> 1574*8c35d5eeSXin Li </td> 1575*8c35d5eeSXin Li <td/> 1576*8c35d5eeSXin Li </tr> 1577*8c35d5eeSXin Li 1578*8c35d5eeSXin Li <tr> 1579*8c35d5eeSXin Li <td>Function Type</td> 1580*8c35d5eeSXin Li <td> 1581*8c35d5eeSXin Li <code>{function(string, boolean)}</code><br/> 1582*8c35d5eeSXin Li A function that takes two arguments (a string and a boolean), 1583*8c35d5eeSXin Li and has an unknown return value.<br/> 1584*8c35d5eeSXin Li </td> 1585*8c35d5eeSXin Li <td>Specifies a function.</td> 1586*8c35d5eeSXin Li <td/> 1587*8c35d5eeSXin Li </tr> 1588*8c35d5eeSXin Li 1589*8c35d5eeSXin Li <tr> 1590*8c35d5eeSXin Li <td>Function Return Type</td> 1591*8c35d5eeSXin Li <td> 1592*8c35d5eeSXin Li <code>{function(): number}</code><br/> 1593*8c35d5eeSXin Li A function that takes no arguments and returns a number.<br/> 1594*8c35d5eeSXin Li </td> 1595*8c35d5eeSXin Li <td>Specifies a function return type.</td> 1596*8c35d5eeSXin Li <td/> 1597*8c35d5eeSXin Li </tr> 1598*8c35d5eeSXin Li 1599*8c35d5eeSXin Li <tr> 1600*8c35d5eeSXin Li <td>Function <code>this</code> Type</td> 1601*8c35d5eeSXin Li <td> 1602*8c35d5eeSXin Li <code>{function(this:goog.ui.Menu, string)}</code><br/> 1603*8c35d5eeSXin Li A function that takes one argument (a string), and executes 1604*8c35d5eeSXin Li in the context of a goog.ui.Menu. 1605*8c35d5eeSXin Li </td> 1606*8c35d5eeSXin Li <td>Specifies the context type of a function type.</td> 1607*8c35d5eeSXin Li <td/> 1608*8c35d5eeSXin Li </tr> 1609*8c35d5eeSXin Li 1610*8c35d5eeSXin Li <tr> 1611*8c35d5eeSXin Li <td>Function <code>new</code> Type</td> 1612*8c35d5eeSXin Li <td> 1613*8c35d5eeSXin Li <code>{function(new:goog.ui.Menu, string)}</code><br/> 1614*8c35d5eeSXin Li A constructor that takes one argument (a string), and 1615*8c35d5eeSXin Li creates a new instance of goog.ui.Menu when called 1616*8c35d5eeSXin Li with the 'new' keyword. 1617*8c35d5eeSXin Li </td> 1618*8c35d5eeSXin Li <td>Specifies the constructed type of a constructor.</td> 1619*8c35d5eeSXin Li <td/> 1620*8c35d5eeSXin Li </tr> 1621*8c35d5eeSXin Li 1622*8c35d5eeSXin Li <tr> 1623*8c35d5eeSXin Li <td>Variable arguments</td> 1624*8c35d5eeSXin Li <td> 1625*8c35d5eeSXin Li <code>{function(string, ...[number]): number}</code><br/> 1626*8c35d5eeSXin Li A function that takes one argument (a string), and then a 1627*8c35d5eeSXin Li variable number of arguments that must be numbers. 1628*8c35d5eeSXin Li </td> 1629*8c35d5eeSXin Li <td>Specifies variable arguments to a function.</td> 1630*8c35d5eeSXin Li <td/> 1631*8c35d5eeSXin Li </tr> 1632*8c35d5eeSXin Li 1633*8c35d5eeSXin Li <tr> 1634*8c35d5eeSXin Li <td> 1635*8c35d5eeSXin Li <a name="var-args-annotation"/> 1636*8c35d5eeSXin Li Variable arguments (in <code>@param</code> annotations) 1637*8c35d5eeSXin Li </td> 1638*8c35d5eeSXin Li <td> 1639*8c35d5eeSXin Li <code>@param {...number} var_args</code><br/> 1640*8c35d5eeSXin Li A variable number of arguments to an annotated function. 1641*8c35d5eeSXin Li </td> 1642*8c35d5eeSXin Li <td> 1643*8c35d5eeSXin Li Specifies that the annotated function accepts a variable 1644*8c35d5eeSXin Li number of arguments. 1645*8c35d5eeSXin Li </td> 1646*8c35d5eeSXin Li <td/> 1647*8c35d5eeSXin Li </tr> 1648*8c35d5eeSXin Li 1649*8c35d5eeSXin Li <tr> 1650*8c35d5eeSXin Li <td>Function <a href="#optional">optional arguments</a></td> 1651*8c35d5eeSXin Li <td> 1652*8c35d5eeSXin Li <code>{function(?string=, number=)}</code><br/> 1653*8c35d5eeSXin Li A function that takes one optional, nullable string and one 1654*8c35d5eeSXin Li optional number as arguments. The <code>=</code> syntax is 1655*8c35d5eeSXin Li only for <code>function</code> type declarations. 1656*8c35d5eeSXin Li </td> 1657*8c35d5eeSXin Li <td>Specifies optional arguments to a function.</td> 1658*8c35d5eeSXin Li <td/> 1659*8c35d5eeSXin Li </tr> 1660*8c35d5eeSXin Li 1661*8c35d5eeSXin Li <tr> 1662*8c35d5eeSXin Li <td> 1663*8c35d5eeSXin Li <a name="optional-arg-annotation"/> 1664*8c35d5eeSXin Li Function <a href="#optional">optional arguments</a> 1665*8c35d5eeSXin Li (in <code>@param</code> annotations) 1666*8c35d5eeSXin Li </td> 1667*8c35d5eeSXin Li <td> 1668*8c35d5eeSXin Li <code>@param {number=} opt_argument</code><br/> 1669*8c35d5eeSXin Li An optional parameter of type <code>number</code>. 1670*8c35d5eeSXin Li </td> 1671*8c35d5eeSXin Li <td>Specifies that the annotated function accepts an optional 1672*8c35d5eeSXin Li argument.</td> 1673*8c35d5eeSXin Li <td/> 1674*8c35d5eeSXin Li </tr> 1675*8c35d5eeSXin Li 1676*8c35d5eeSXin Li <tr> 1677*8c35d5eeSXin Li <td>The ALL type</td> 1678*8c35d5eeSXin Li <td><code>{*}</code></td> 1679*8c35d5eeSXin Li <td>Indicates that the variable can take on any type.</td> 1680*8c35d5eeSXin Li <td/> 1681*8c35d5eeSXin Li </tr> 1682*8c35d5eeSXin Li 1683*8c35d5eeSXin Li <tr> 1684*8c35d5eeSXin Li <td>The UNKNOWN type</td> 1685*8c35d5eeSXin Li <td><code>{?}</code></td> 1686*8c35d5eeSXin Li <td>Indicates that the variable can take on any type, 1687*8c35d5eeSXin Li and the compiler should not type-check any uses of it.</td> 1688*8c35d5eeSXin Li <td/> 1689*8c35d5eeSXin Li </tr> 1690*8c35d5eeSXin Li </tbody> 1691*8c35d5eeSXin Li </table> 1692*8c35d5eeSXin Li </SUBSECTION> 1693*8c35d5eeSXin Li <SUBSECTION title="Types in JavaScript"> 1694*8c35d5eeSXin Li <p/> 1695*8c35d5eeSXin Li <table border="1" style="border-collapse:collapse" cellpadding="4"> 1696*8c35d5eeSXin Li <thead> 1697*8c35d5eeSXin Li <tr> 1698*8c35d5eeSXin Li <th>Type Example</th> 1699*8c35d5eeSXin Li <th>Value Examples</th> 1700*8c35d5eeSXin Li <th>Description</th> 1701*8c35d5eeSXin Li </tr> 1702*8c35d5eeSXin Li </thead> 1703*8c35d5eeSXin Li <tbody> 1704*8c35d5eeSXin Li 1705*8c35d5eeSXin Li <tr> 1706*8c35d5eeSXin Li <td>number</td> 1707*8c35d5eeSXin Li <td> 1708*8c35d5eeSXin Li <CODE_SNIPPET> 1709*8c35d5eeSXin Li 1 1710*8c35d5eeSXin Li 1.0 1711*8c35d5eeSXin Li -5 1712*8c35d5eeSXin Li 1e5 1713*8c35d5eeSXin Li Math.PI 1714*8c35d5eeSXin Li </CODE_SNIPPET> 1715*8c35d5eeSXin Li </td> 1716*8c35d5eeSXin Li <td/> 1717*8c35d5eeSXin Li </tr> 1718*8c35d5eeSXin Li 1719*8c35d5eeSXin Li <tr> 1720*8c35d5eeSXin Li <td>Number</td> 1721*8c35d5eeSXin Li <td> 1722*8c35d5eeSXin Li <CODE_SNIPPET> 1723*8c35d5eeSXin Li new Number(true) 1724*8c35d5eeSXin Li </CODE_SNIPPET> 1725*8c35d5eeSXin Li </td> 1726*8c35d5eeSXin Li <td> 1727*8c35d5eeSXin Li <a href="#Wrapper_objects_for_primitive_types"> 1728*8c35d5eeSXin Li Number object 1729*8c35d5eeSXin Li </a> 1730*8c35d5eeSXin Li </td> 1731*8c35d5eeSXin Li </tr> 1732*8c35d5eeSXin Li 1733*8c35d5eeSXin Li <tr> 1734*8c35d5eeSXin Li <td>string</td> 1735*8c35d5eeSXin Li <td> 1736*8c35d5eeSXin Li <CODE_SNIPPET> 1737*8c35d5eeSXin Li 'Hello' 1738*8c35d5eeSXin Li "World" 1739*8c35d5eeSXin Li String(42) 1740*8c35d5eeSXin Li </CODE_SNIPPET> 1741*8c35d5eeSXin Li </td> 1742*8c35d5eeSXin Li <td> 1743*8c35d5eeSXin Li String value 1744*8c35d5eeSXin Li </td> 1745*8c35d5eeSXin Li </tr> 1746*8c35d5eeSXin Li 1747*8c35d5eeSXin Li <tr> 1748*8c35d5eeSXin Li <td>String</td> 1749*8c35d5eeSXin Li <td> 1750*8c35d5eeSXin Li <CODE_SNIPPET> 1751*8c35d5eeSXin Li new String('Hello') 1752*8c35d5eeSXin Li new String(42) 1753*8c35d5eeSXin Li </CODE_SNIPPET> 1754*8c35d5eeSXin Li </td> 1755*8c35d5eeSXin Li <td> 1756*8c35d5eeSXin Li <a href="#Wrapper_objects_for_primitive_types"> 1757*8c35d5eeSXin Li String object 1758*8c35d5eeSXin Li </a> 1759*8c35d5eeSXin Li </td> 1760*8c35d5eeSXin Li </tr> 1761*8c35d5eeSXin Li 1762*8c35d5eeSXin Li <tr> 1763*8c35d5eeSXin Li <td>boolean</td> 1764*8c35d5eeSXin Li <td> 1765*8c35d5eeSXin Li <CODE_SNIPPET> 1766*8c35d5eeSXin Li true 1767*8c35d5eeSXin Li false 1768*8c35d5eeSXin Li Boolean(0) 1769*8c35d5eeSXin Li </CODE_SNIPPET> 1770*8c35d5eeSXin Li </td> 1771*8c35d5eeSXin Li <td> 1772*8c35d5eeSXin Li Boolean value 1773*8c35d5eeSXin Li </td> 1774*8c35d5eeSXin Li </tr> 1775*8c35d5eeSXin Li 1776*8c35d5eeSXin Li <tr> 1777*8c35d5eeSXin Li <td>Boolean</td> 1778*8c35d5eeSXin Li <td> 1779*8c35d5eeSXin Li <CODE_SNIPPET> 1780*8c35d5eeSXin Li new Boolean(true) 1781*8c35d5eeSXin Li </CODE_SNIPPET> 1782*8c35d5eeSXin Li </td> 1783*8c35d5eeSXin Li <td> 1784*8c35d5eeSXin Li <a href="#Wrapper_objects_for_primitive_types"> 1785*8c35d5eeSXin Li Boolean object 1786*8c35d5eeSXin Li </a> 1787*8c35d5eeSXin Li </td> 1788*8c35d5eeSXin Li </tr> 1789*8c35d5eeSXin Li 1790*8c35d5eeSXin Li <tr> 1791*8c35d5eeSXin Li <td>RegExp</td> 1792*8c35d5eeSXin Li <td> 1793*8c35d5eeSXin Li <CODE_SNIPPET> 1794*8c35d5eeSXin Li new RegExp('hello') 1795*8c35d5eeSXin Li /world/g 1796*8c35d5eeSXin Li </CODE_SNIPPET></td><td> 1797*8c35d5eeSXin Li </td> 1798*8c35d5eeSXin Li </tr> 1799*8c35d5eeSXin Li 1800*8c35d5eeSXin Li <tr> 1801*8c35d5eeSXin Li <td>Date</td> 1802*8c35d5eeSXin Li <td> 1803*8c35d5eeSXin Li <CODE_SNIPPET> 1804*8c35d5eeSXin Li new Date 1805*8c35d5eeSXin Li new Date() 1806*8c35d5eeSXin Li </CODE_SNIPPET></td> 1807*8c35d5eeSXin Li <td/> 1808*8c35d5eeSXin Li </tr> 1809*8c35d5eeSXin Li 1810*8c35d5eeSXin Li <tr> 1811*8c35d5eeSXin Li <td> 1812*8c35d5eeSXin Li 1813*8c35d5eeSXin Li null 1814*8c35d5eeSXin Li 1815*8c35d5eeSXin Li </td> 1816*8c35d5eeSXin Li <td> 1817*8c35d5eeSXin Li <CODE_SNIPPET> 1818*8c35d5eeSXin Li null 1819*8c35d5eeSXin Li </CODE_SNIPPET> 1820*8c35d5eeSXin Li </td> 1821*8c35d5eeSXin Li <td/> 1822*8c35d5eeSXin Li </tr> 1823*8c35d5eeSXin Li 1824*8c35d5eeSXin Li <tr> 1825*8c35d5eeSXin Li <td> 1826*8c35d5eeSXin Li 1827*8c35d5eeSXin Li undefined 1828*8c35d5eeSXin Li 1829*8c35d5eeSXin Li </td> 1830*8c35d5eeSXin Li <td> 1831*8c35d5eeSXin Li <CODE_SNIPPET> 1832*8c35d5eeSXin Li undefined 1833*8c35d5eeSXin Li </CODE_SNIPPET> 1834*8c35d5eeSXin Li </td> 1835*8c35d5eeSXin Li <td/> 1836*8c35d5eeSXin Li </tr> 1837*8c35d5eeSXin Li 1838*8c35d5eeSXin Li <tr> 1839*8c35d5eeSXin Li <td>void</td> 1840*8c35d5eeSXin Li <td> 1841*8c35d5eeSXin Li <CODE_SNIPPET> 1842*8c35d5eeSXin Li function f() { 1843*8c35d5eeSXin Li return; 1844*8c35d5eeSXin Li } 1845*8c35d5eeSXin Li </CODE_SNIPPET> 1846*8c35d5eeSXin Li </td> 1847*8c35d5eeSXin Li <td>No return value</td> 1848*8c35d5eeSXin Li </tr> 1849*8c35d5eeSXin Li 1850*8c35d5eeSXin Li <tr> 1851*8c35d5eeSXin Li <td>Array</td> 1852*8c35d5eeSXin Li <td> 1853*8c35d5eeSXin Li <CODE_SNIPPET> 1854*8c35d5eeSXin Li ['foo', 0.3, null] 1855*8c35d5eeSXin Li [] 1856*8c35d5eeSXin Li </CODE_SNIPPET> 1857*8c35d5eeSXin Li </td> 1858*8c35d5eeSXin Li <td>Untyped Array</td> 1859*8c35d5eeSXin Li </tr> 1860*8c35d5eeSXin Li 1861*8c35d5eeSXin Li <tr> 1862*8c35d5eeSXin Li <td>Array.<number></td> 1863*8c35d5eeSXin Li <td> 1864*8c35d5eeSXin Li <CODE_SNIPPET> 1865*8c35d5eeSXin Li [11, 22, 33] 1866*8c35d5eeSXin Li </CODE_SNIPPET> 1867*8c35d5eeSXin Li </td> 1868*8c35d5eeSXin Li <td> 1869*8c35d5eeSXin Li An Array of numbers 1870*8c35d5eeSXin Li </td> 1871*8c35d5eeSXin Li </tr> 1872*8c35d5eeSXin Li 1873*8c35d5eeSXin Li <tr> 1874*8c35d5eeSXin Li <td>Array.<Array.<string>></td> 1875*8c35d5eeSXin Li <td> 1876*8c35d5eeSXin Li <CODE_SNIPPET> 1877*8c35d5eeSXin Li [['one', 'two', 'three'], ['foo', 'bar']] 1878*8c35d5eeSXin Li </CODE_SNIPPET> 1879*8c35d5eeSXin Li </td> 1880*8c35d5eeSXin Li <td>Array of Arrays of strings</td> 1881*8c35d5eeSXin Li </tr> 1882*8c35d5eeSXin Li 1883*8c35d5eeSXin Li <tr> 1884*8c35d5eeSXin Li <td>Object</td> 1885*8c35d5eeSXin Li <td> 1886*8c35d5eeSXin Li <CODE_SNIPPET> 1887*8c35d5eeSXin Li {} 1888*8c35d5eeSXin Li {foo: 'abc', bar: 123, baz: null} 1889*8c35d5eeSXin Li </CODE_SNIPPET> 1890*8c35d5eeSXin Li </td> 1891*8c35d5eeSXin Li <td/> 1892*8c35d5eeSXin Li </tr> 1893*8c35d5eeSXin Li 1894*8c35d5eeSXin Li <tr> 1895*8c35d5eeSXin Li <td>Object.<string></td> 1896*8c35d5eeSXin Li <td> 1897*8c35d5eeSXin Li <CODE_SNIPPET> 1898*8c35d5eeSXin Li {'foo': 'bar'} 1899*8c35d5eeSXin Li </CODE_SNIPPET> 1900*8c35d5eeSXin Li </td> 1901*8c35d5eeSXin Li <td> 1902*8c35d5eeSXin Li An Object in which the values are strings. 1903*8c35d5eeSXin Li </td> 1904*8c35d5eeSXin Li </tr> 1905*8c35d5eeSXin Li 1906*8c35d5eeSXin Li <tr> 1907*8c35d5eeSXin Li <td>Object.<number, string></td> 1908*8c35d5eeSXin Li <td> 1909*8c35d5eeSXin Li <CODE_SNIPPET> 1910*8c35d5eeSXin Li var obj = {}; 1911*8c35d5eeSXin Li obj[1] = 'bar'; 1912*8c35d5eeSXin Li </CODE_SNIPPET> 1913*8c35d5eeSXin Li </td> 1914*8c35d5eeSXin Li <td> 1915*8c35d5eeSXin Li An Object in which the keys are numbers and the values are 1916*8c35d5eeSXin Li strings. <p/>Note that in JavaScript, the keys are always 1917*8c35d5eeSXin Li implicitly converted to strings, so 1918*8c35d5eeSXin Li <code>obj['1'] == obj[1]</code>. 1919*8c35d5eeSXin Li So the key will always be a string in for...in loops. But the 1920*8c35d5eeSXin Li compiler will verify the type of the key when indexing into 1921*8c35d5eeSXin Li the object. 1922*8c35d5eeSXin Li </td> 1923*8c35d5eeSXin Li </tr> 1924*8c35d5eeSXin Li 1925*8c35d5eeSXin Li <tr> 1926*8c35d5eeSXin Li <td>Function</td> 1927*8c35d5eeSXin Li <td> 1928*8c35d5eeSXin Li <CODE_SNIPPET> 1929*8c35d5eeSXin Li function(x, y) { 1930*8c35d5eeSXin Li return x * y; 1931*8c35d5eeSXin Li } 1932*8c35d5eeSXin Li </CODE_SNIPPET> 1933*8c35d5eeSXin Li </td> 1934*8c35d5eeSXin Li <td> 1935*8c35d5eeSXin Li <a href="#Wrapper_objects_for_primitive_types"> 1936*8c35d5eeSXin Li Function object 1937*8c35d5eeSXin Li </a> 1938*8c35d5eeSXin Li </td> 1939*8c35d5eeSXin Li </tr> 1940*8c35d5eeSXin Li 1941*8c35d5eeSXin Li <tr> 1942*8c35d5eeSXin Li <td>function(number, number): number</td> 1943*8c35d5eeSXin Li <td> 1944*8c35d5eeSXin Li <CODE_SNIPPET> 1945*8c35d5eeSXin Li function(x, y) { 1946*8c35d5eeSXin Li return x * y; 1947*8c35d5eeSXin Li } 1948*8c35d5eeSXin Li </CODE_SNIPPET> 1949*8c35d5eeSXin Li </td> 1950*8c35d5eeSXin Li <td>function value</td> 1951*8c35d5eeSXin Li </tr> 1952*8c35d5eeSXin Li 1953*8c35d5eeSXin Li <tr> 1954*8c35d5eeSXin Li <td><a name="constructor-tag">SomeClass</a></td> 1955*8c35d5eeSXin Li <td> 1956*8c35d5eeSXin Li <CODE_SNIPPET> 1957*8c35d5eeSXin Li /** @constructor */ 1958*8c35d5eeSXin Li function SomeClass() {} 1959*8c35d5eeSXin Li 1960*8c35d5eeSXin Li new SomeClass(); 1961*8c35d5eeSXin Li </CODE_SNIPPET> 1962*8c35d5eeSXin Li </td> 1963*8c35d5eeSXin Li <td/> 1964*8c35d5eeSXin Li </tr> 1965*8c35d5eeSXin Li 1966*8c35d5eeSXin Li <tr> 1967*8c35d5eeSXin Li <td>SomeInterface</td> 1968*8c35d5eeSXin Li <td> 1969*8c35d5eeSXin Li <CODE_SNIPPET> 1970*8c35d5eeSXin Li /** @interface */ 1971*8c35d5eeSXin Li function SomeInterface() {} 1972*8c35d5eeSXin Li 1973*8c35d5eeSXin Li SomeInterface.prototype.draw = function() {}; 1974*8c35d5eeSXin Li </CODE_SNIPPET> 1975*8c35d5eeSXin Li </td> 1976*8c35d5eeSXin Li <td/> 1977*8c35d5eeSXin Li </tr> 1978*8c35d5eeSXin Li 1979*8c35d5eeSXin Li <tr> 1980*8c35d5eeSXin Li <td>project.MyClass</td> 1981*8c35d5eeSXin Li <td> 1982*8c35d5eeSXin Li <CODE_SNIPPET> 1983*8c35d5eeSXin Li /** @constructor */ 1984*8c35d5eeSXin Li project.MyClass = function () {} 1985*8c35d5eeSXin Li 1986*8c35d5eeSXin Li new project.MyClass() 1987*8c35d5eeSXin Li </CODE_SNIPPET> 1988*8c35d5eeSXin Li </td> 1989*8c35d5eeSXin Li <td/> 1990*8c35d5eeSXin Li </tr> 1991*8c35d5eeSXin Li 1992*8c35d5eeSXin Li <tr> 1993*8c35d5eeSXin Li <td>project.MyEnum</td> 1994*8c35d5eeSXin Li <td> 1995*8c35d5eeSXin Li <CODE_SNIPPET> 1996*8c35d5eeSXin Li /** @enum {string} */ 1997*8c35d5eeSXin Li project.MyEnum = { 1998*8c35d5eeSXin Li /** The color blue. */ 1999*8c35d5eeSXin Li BLUE: '#0000dd', 2000*8c35d5eeSXin Li /** The color red. */ 2001*8c35d5eeSXin Li RED: '#dd0000' 2002*8c35d5eeSXin Li }; 2003*8c35d5eeSXin Li </CODE_SNIPPET> 2004*8c35d5eeSXin Li </td> 2005*8c35d5eeSXin Li <td><a name="enums">Enumeration</a><p/> 2006*8c35d5eeSXin Li JSDoc comments on enum values are optional. 2007*8c35d5eeSXin Li </td> 2008*8c35d5eeSXin Li </tr> 2009*8c35d5eeSXin Li 2010*8c35d5eeSXin Li <tr> 2011*8c35d5eeSXin Li <td>Element</td> 2012*8c35d5eeSXin Li <td> 2013*8c35d5eeSXin Li <CODE_SNIPPET> 2014*8c35d5eeSXin Li document.createElement('div') 2015*8c35d5eeSXin Li </CODE_SNIPPET> 2016*8c35d5eeSXin Li </td> 2017*8c35d5eeSXin Li <td>Elements in the DOM.</td> 2018*8c35d5eeSXin Li </tr> 2019*8c35d5eeSXin Li 2020*8c35d5eeSXin Li <tr> 2021*8c35d5eeSXin Li <td>Node</td> 2022*8c35d5eeSXin Li <td> 2023*8c35d5eeSXin Li <CODE_SNIPPET> 2024*8c35d5eeSXin Li document.body.firstChild 2025*8c35d5eeSXin Li </CODE_SNIPPET> 2026*8c35d5eeSXin Li </td> 2027*8c35d5eeSXin Li <td>Nodes in the DOM.</td> 2028*8c35d5eeSXin Li </tr> 2029*8c35d5eeSXin Li 2030*8c35d5eeSXin Li <tr> 2031*8c35d5eeSXin Li <td>HTMLInputElement</td> 2032*8c35d5eeSXin Li <td> 2033*8c35d5eeSXin Li <CODE_SNIPPET> 2034*8c35d5eeSXin Li htmlDocument.getElementsByTagName('input')[0] 2035*8c35d5eeSXin Li </CODE_SNIPPET> 2036*8c35d5eeSXin Li </td> 2037*8c35d5eeSXin Li <td>A specific type of DOM element.</td> 2038*8c35d5eeSXin Li </tr> 2039*8c35d5eeSXin Li </tbody> 2040*8c35d5eeSXin Li </table> 2041*8c35d5eeSXin Li </SUBSECTION> 2042*8c35d5eeSXin Li 2043*8c35d5eeSXin Li <SUBSECTION title="Type Casts"> 2044*8c35d5eeSXin Li <p>In cases where type-checking doesn't accurately infer the type of 2045*8c35d5eeSXin Li an expression, it is possible to add a type cast comment by adding a 2046*8c35d5eeSXin Li type annotation comment and enclosing the expression in 2047*8c35d5eeSXin Li parentheses. The parentheses are required.</p> 2048*8c35d5eeSXin Li 2049*8c35d5eeSXin Li <CODE_SNIPPET> 2050*8c35d5eeSXin Li /** @type {number} */ (x) 2051*8c35d5eeSXin Li </CODE_SNIPPET> 2052*8c35d5eeSXin Li </SUBSECTION> 2053*8c35d5eeSXin Li 2054*8c35d5eeSXin Li <SUBSECTION title="Nullable vs. Optional Parameters and Properties"> 2055*8c35d5eeSXin Li <a name="optional"/> 2056*8c35d5eeSXin Li <p>Because JavaScript is a loosely-typed language, it is very 2057*8c35d5eeSXin Li important to understand the subtle differences between optional, 2058*8c35d5eeSXin Li nullable, and undefined function parameters and class 2059*8c35d5eeSXin Li properties.</p> 2060*8c35d5eeSXin Li 2061*8c35d5eeSXin Li <p>Instances of classes and interfaces are nullable by default. 2062*8c35d5eeSXin Li For example, the following declaration</p> 2063*8c35d5eeSXin Li 2064*8c35d5eeSXin Li <CODE_SNIPPET> 2065*8c35d5eeSXin Li /** 2066*8c35d5eeSXin Li * Some class, initialized with a value. 2067*8c35d5eeSXin Li * @param {Object} value Some value. 2068*8c35d5eeSXin Li * @constructor 2069*8c35d5eeSXin Li */ 2070*8c35d5eeSXin Li function MyClass(value) { 2071*8c35d5eeSXin Li /** 2072*8c35d5eeSXin Li * Some value. 2073*8c35d5eeSXin Li * @type {Object} 2074*8c35d5eeSXin Li * @private 2075*8c35d5eeSXin Li */ 2076*8c35d5eeSXin Li this.myValue_ = value; 2077*8c35d5eeSXin Li } 2078*8c35d5eeSXin Li </CODE_SNIPPET> 2079*8c35d5eeSXin Li 2080*8c35d5eeSXin Li <p>tells the compiler that the <code>myValue_</code> property holds 2081*8c35d5eeSXin Li either an Object or null. If <code>myValue_</code> must never be 2082*8c35d5eeSXin Li null, it should be declared like this:</p> 2083*8c35d5eeSXin Li 2084*8c35d5eeSXin Li <CODE_SNIPPET> 2085*8c35d5eeSXin Li /** 2086*8c35d5eeSXin Li * Some class, initialized with a non-null value. 2087*8c35d5eeSXin Li * @param {!Object} value Some value. 2088*8c35d5eeSXin Li * @constructor 2089*8c35d5eeSXin Li */ 2090*8c35d5eeSXin Li function MyClass(value) { 2091*8c35d5eeSXin Li /** 2092*8c35d5eeSXin Li * Some value. 2093*8c35d5eeSXin Li * @type {!Object} 2094*8c35d5eeSXin Li * @private 2095*8c35d5eeSXin Li */ 2096*8c35d5eeSXin Li this.myValue_ = value; 2097*8c35d5eeSXin Li } 2098*8c35d5eeSXin Li </CODE_SNIPPET> 2099*8c35d5eeSXin Li 2100*8c35d5eeSXin Li <p>This way, if the compiler can determine that somewhere in the code 2101*8c35d5eeSXin Li <code>MyClass</code> is initialized with a null value, it will issue 2102*8c35d5eeSXin Li a warning.</p> 2103*8c35d5eeSXin Li 2104*8c35d5eeSXin Li 2105*8c35d5eeSXin Li 2106*8c35d5eeSXin Li <p>Optional parameters to functions may be undefined at runtime, so if 2107*8c35d5eeSXin Li they are assigned to class properties, those properties must be 2108*8c35d5eeSXin Li declared accordingly:</p> 2109*8c35d5eeSXin Li 2110*8c35d5eeSXin Li <CODE_SNIPPET> 2111*8c35d5eeSXin Li /** 2112*8c35d5eeSXin Li * Some class, initialized with an optional value. 2113*8c35d5eeSXin Li * @param {Object=} opt_value Some value (optional). 2114*8c35d5eeSXin Li * @constructor 2115*8c35d5eeSXin Li */ 2116*8c35d5eeSXin Li function MyClass(opt_value) { 2117*8c35d5eeSXin Li /** 2118*8c35d5eeSXin Li * Some value. 2119*8c35d5eeSXin Li * @type {Object|undefined} 2120*8c35d5eeSXin Li * @private 2121*8c35d5eeSXin Li */ 2122*8c35d5eeSXin Li this.myValue_ = opt_value; 2123*8c35d5eeSXin Li } 2124*8c35d5eeSXin Li </CODE_SNIPPET> 2125*8c35d5eeSXin Li 2126*8c35d5eeSXin Li <p>This tells the compiler that <code>myValue_</code> may hold an 2127*8c35d5eeSXin Li Object, null, or remain undefined.</p> 2128*8c35d5eeSXin Li 2129*8c35d5eeSXin Li <p>Note that the optional parameter <code>opt_value</code> is declared 2130*8c35d5eeSXin Li to be of type <code>{Object=}</code>, not 2131*8c35d5eeSXin Li <code>{Object|undefined}</code>. This is because optional 2132*8c35d5eeSXin Li parameters may, by definition, be undefined. While there is no harm 2133*8c35d5eeSXin Li in explicitly declaring an optional parameter as possibly undefined, 2134*8c35d5eeSXin Li it is both unnecessary and makes the code harder to read.</p> 2135*8c35d5eeSXin Li 2136*8c35d5eeSXin Li <p>Finally, note that being nullable and being optional are orthogonal 2137*8c35d5eeSXin Li properties. The following four declarations are all different:</p> 2138*8c35d5eeSXin Li 2139*8c35d5eeSXin Li <CODE_SNIPPET> 2140*8c35d5eeSXin Li /** 2141*8c35d5eeSXin Li * Takes four arguments, two of which are nullable, and two of which are 2142*8c35d5eeSXin Li * optional. 2143*8c35d5eeSXin Li * @param {!Object} nonNull Mandatory (must not be undefined), must not be null. 2144*8c35d5eeSXin Li * @param {Object} mayBeNull Mandatory (must not be undefined), may be null. 2145*8c35d5eeSXin Li * @param {!Object=} opt_nonNull Optional (may be undefined), but if present, 2146*8c35d5eeSXin Li * must not be null! 2147*8c35d5eeSXin Li * @param {Object=} opt_mayBeNull Optional (may be undefined), may be null. 2148*8c35d5eeSXin Li */ 2149*8c35d5eeSXin Li function strangeButTrue(nonNull, mayBeNull, opt_nonNull, opt_mayBeNull) { 2150*8c35d5eeSXin Li // ... 2151*8c35d5eeSXin Li }; 2152*8c35d5eeSXin Li </CODE_SNIPPET> 2153*8c35d5eeSXin Li </SUBSECTION> 2154*8c35d5eeSXin Li 2155*8c35d5eeSXin Li <SUBSECTION title="Typedefs"> 2156*8c35d5eeSXin Li <a name="Typedefs"/> 2157*8c35d5eeSXin Li <p>Sometimes types can get complicated. A function that accepts 2158*8c35d5eeSXin Li content for an Element might look like:</p> 2159*8c35d5eeSXin Li 2160*8c35d5eeSXin Li <CODE_SNIPPET> 2161*8c35d5eeSXin Li /** 2162*8c35d5eeSXin Li * @param {string} tagName 2163*8c35d5eeSXin Li * @param {(string|Element|Text|Array.<Element>|Array.<Text>)} contents 2164*8c35d5eeSXin Li * @return {!Element} 2165*8c35d5eeSXin Li */ 2166*8c35d5eeSXin Li goog.createElement = function(tagName, contents) { 2167*8c35d5eeSXin Li ... 2168*8c35d5eeSXin Li }; 2169*8c35d5eeSXin Li </CODE_SNIPPET> 2170*8c35d5eeSXin Li 2171*8c35d5eeSXin Li <p>You can define commonly used type expressions with a 2172*8c35d5eeSXin Li <code>@typedef</code> tag. For example,</p> 2173*8c35d5eeSXin Li 2174*8c35d5eeSXin Li <CODE_SNIPPET> 2175*8c35d5eeSXin Li /** @typedef {(string|Element|Text|Array.<Element>|Array.<Text>)} */ 2176*8c35d5eeSXin Li goog.ElementContent; 2177*8c35d5eeSXin Li 2178*8c35d5eeSXin Li /** 2179*8c35d5eeSXin Li * @param {string} tagName 2180*8c35d5eeSXin Li * @param {goog.ElementContent} contents 2181*8c35d5eeSXin Li * @return {!Element} 2182*8c35d5eeSXin Li */ 2183*8c35d5eeSXin Li goog.createElement = function(tagName, contents) { 2184*8c35d5eeSXin Li ... 2185*8c35d5eeSXin Li }; 2186*8c35d5eeSXin Li </CODE_SNIPPET> 2187*8c35d5eeSXin Li </SUBSECTION> 2188*8c35d5eeSXin Li 2189*8c35d5eeSXin Li <SUBSECTION title="Template types"> 2190*8c35d5eeSXin Li <a name="Template_types"/> 2191*8c35d5eeSXin Li <p>The compiler has limited support for template types. It can only 2192*8c35d5eeSXin Li infer the type of <code>this</code> inside an anonymous function 2193*8c35d5eeSXin Li literal from the type of the <code>this</code> argument and whether the 2194*8c35d5eeSXin Li <code>this</code> argument is missing.</p> 2195*8c35d5eeSXin Li 2196*8c35d5eeSXin Li <CODE_SNIPPET> 2197*8c35d5eeSXin Li /** 2198*8c35d5eeSXin Li * @param {function(this:T, ...)} fn 2199*8c35d5eeSXin Li * @param {T} thisObj 2200*8c35d5eeSXin Li * @param {...*} var_args 2201*8c35d5eeSXin Li * @template T 2202*8c35d5eeSXin Li */ 2203*8c35d5eeSXin Li goog.bind = function(fn, thisObj, var_args) { 2204*8c35d5eeSXin Li ... 2205*8c35d5eeSXin Li }; 2206*8c35d5eeSXin Li // Possibly generates a missing property warning. 2207*8c35d5eeSXin Li goog.bind(function() { this.someProperty; }, new SomeClass()); 2208*8c35d5eeSXin Li // Generates an undefined this warning. 2209*8c35d5eeSXin Li goog.bind(function() { this.someProperty; }); 2210*8c35d5eeSXin Li </CODE_SNIPPET> 2211*8c35d5eeSXin Li </SUBSECTION> 2212*8c35d5eeSXin Li </BODY> 2213*8c35d5eeSXin Li </STYLEPOINT> 2214*8c35d5eeSXin Li 2215*8c35d5eeSXin Li <STYLEPOINT title="Comments"> 2216*8c35d5eeSXin Li <SUMMARY>Use JSDoc</SUMMARY> 2217*8c35d5eeSXin Li <BODY> 2218*8c35d5eeSXin Li <p> 2219*8c35d5eeSXin Li We follow the 2220*8c35d5eeSXin Li <a href="cppguide.html#Comments"> 2221*8c35d5eeSXin Li C++ style for comments</a> in spirit. 2222*8c35d5eeSXin Li </p> 2223*8c35d5eeSXin Li 2224*8c35d5eeSXin Li <p>All files, classes, methods and properties should be documented with 2225*8c35d5eeSXin Li <a href="https://code.google.com/p/jsdoc-toolkit/">JSDoc</a> 2226*8c35d5eeSXin Li comments with the appropriate <a href="#JSDoc_Tag_Reference">tags</a> 2227*8c35d5eeSXin Li and <a href="#JsTypes">types</a>. Textual descriptions for properties, 2228*8c35d5eeSXin Li methods, method parameters and method return values should be included 2229*8c35d5eeSXin Li unless obvious from the property, method, or parameter name. 2230*8c35d5eeSXin Li </p> 2231*8c35d5eeSXin Li 2232*8c35d5eeSXin Li <p>Inline comments should be of the <code>//</code> variety.</p> 2233*8c35d5eeSXin Li 2234*8c35d5eeSXin Li <p>Complete sentences are recommended but not required. 2235*8c35d5eeSXin Li Complete sentences should use appropriate capitalization 2236*8c35d5eeSXin Li and punctuation.</p> 2237*8c35d5eeSXin Li 2238*8c35d5eeSXin Li <SUBSECTION title="Comment Syntax"> 2239*8c35d5eeSXin Li <p>The JSDoc syntax is based on 2240*8c35d5eeSXin Li <a href="https://www.oracle.com/technetwork/java/javase/documentation/index-137868.html"> 2241*8c35d5eeSXin Li JavaDoc</a>. Many tools extract metadata from JSDoc comments to 2242*8c35d5eeSXin Li perform code validation and optimizations. These comments must be 2243*8c35d5eeSXin Li well-formed.</p> 2244*8c35d5eeSXin Li 2245*8c35d5eeSXin Li <CODE_SNIPPET> 2246*8c35d5eeSXin Li /** 2247*8c35d5eeSXin Li * A JSDoc comment should begin with a slash and 2 asterisks. 2248*8c35d5eeSXin Li * Inline tags should be enclosed in braces like {@code this}. 2249*8c35d5eeSXin Li * @desc Block tags should always start on their own line. 2250*8c35d5eeSXin Li */ 2251*8c35d5eeSXin Li </CODE_SNIPPET> 2252*8c35d5eeSXin Li </SUBSECTION> 2253*8c35d5eeSXin Li 2254*8c35d5eeSXin Li <SUBSECTION title="JSDoc Indentation"> 2255*8c35d5eeSXin Li <p>If you have to line break a block tag, you should treat this as 2256*8c35d5eeSXin Li breaking a code statement and indent it four spaces.</p> 2257*8c35d5eeSXin Li 2258*8c35d5eeSXin Li <CODE_SNIPPET> 2259*8c35d5eeSXin Li /** 2260*8c35d5eeSXin Li * Illustrates line wrapping for long param/return descriptions. 2261*8c35d5eeSXin Li * @param {string} foo This is a param with a description too long to fit in 2262*8c35d5eeSXin Li * one line. 2263*8c35d5eeSXin Li * @return {number} This returns something that has a description too long to 2264*8c35d5eeSXin Li * fit in one line. 2265*8c35d5eeSXin Li */ 2266*8c35d5eeSXin Li project.MyClass.prototype.method = function(foo) { 2267*8c35d5eeSXin Li return 5; 2268*8c35d5eeSXin Li }; 2269*8c35d5eeSXin Li </CODE_SNIPPET> 2270*8c35d5eeSXin Li 2271*8c35d5eeSXin Li <p>You should not indent the <code>@fileoverview</code> command. You do not have to 2272*8c35d5eeSXin Li indent the <code>@desc</code> command.</p> 2273*8c35d5eeSXin Li 2274*8c35d5eeSXin Li <p>Even though it is not preferred, it is also acceptable to line up 2275*8c35d5eeSXin Li the description.</p> 2276*8c35d5eeSXin Li 2277*8c35d5eeSXin Li <CODE_SNIPPET> 2278*8c35d5eeSXin Li /** 2279*8c35d5eeSXin Li * This is NOT the preferred indentation method. 2280*8c35d5eeSXin Li * @param {string} foo This is a param with a description too long to fit in 2281*8c35d5eeSXin Li * one line. 2282*8c35d5eeSXin Li * @return {number} This returns something that has a description too long to 2283*8c35d5eeSXin Li * fit in one line. 2284*8c35d5eeSXin Li */ 2285*8c35d5eeSXin Li project.MyClass.prototype.method = function(foo) { 2286*8c35d5eeSXin Li return 5; 2287*8c35d5eeSXin Li }; 2288*8c35d5eeSXin Li </CODE_SNIPPET> 2289*8c35d5eeSXin Li </SUBSECTION> 2290*8c35d5eeSXin Li 2291*8c35d5eeSXin Li <SUBSECTION title="HTML in JSDoc"> 2292*8c35d5eeSXin Li <p>Like JavaDoc, JSDoc supports many HTML tags, like <code>, 2293*8c35d5eeSXin Li <pre>, <tt>, <strong>, <ul>, <ol>, 2294*8c35d5eeSXin Li <li>, <a>, and others.</p> 2295*8c35d5eeSXin Li 2296*8c35d5eeSXin Li <p>This means that plaintext formatting is not respected. So, don't 2297*8c35d5eeSXin Li rely on whitespace to format JSDoc:</p> 2298*8c35d5eeSXin Li 2299*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 2300*8c35d5eeSXin Li /** 2301*8c35d5eeSXin Li * Computes weight based on three factors: 2302*8c35d5eeSXin Li * items sent 2303*8c35d5eeSXin Li * items received 2304*8c35d5eeSXin Li * last timestamp 2305*8c35d5eeSXin Li */ 2306*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 2307*8c35d5eeSXin Li 2308*8c35d5eeSXin Li <p>It'll come out like this:</p> 2309*8c35d5eeSXin Li 2310*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 2311*8c35d5eeSXin Li Computes weight based on three factors: items sent items received last timestamp 2312*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 2313*8c35d5eeSXin Li 2314*8c35d5eeSXin Li <p>Instead, do this:</p> 2315*8c35d5eeSXin Li 2316*8c35d5eeSXin Li <CODE_SNIPPET> 2317*8c35d5eeSXin Li /** 2318*8c35d5eeSXin Li * Computes weight based on three factors: 2319*8c35d5eeSXin Li * <ul> 2320*8c35d5eeSXin Li * <li>items sent 2321*8c35d5eeSXin Li * <li>items received 2322*8c35d5eeSXin Li * <li>last timestamp 2323*8c35d5eeSXin Li * </ul> 2324*8c35d5eeSXin Li */ 2325*8c35d5eeSXin Li </CODE_SNIPPET> 2326*8c35d5eeSXin Li 2327*8c35d5eeSXin Li The <a href="https://www.oracle.com/technetwork/java/javase/documentation/index-137868.html"> 2328*8c35d5eeSXin Li JavaDoc</a> style guide is a useful resource on how to write 2329*8c35d5eeSXin Li well-formed doc comments. 2330*8c35d5eeSXin Li </SUBSECTION> 2331*8c35d5eeSXin Li 2332*8c35d5eeSXin Li <SUBSECTION title="Top/File-Level Comments"> 2333*8c35d5eeSXin Li <p> 2334*8c35d5eeSXin Li 2335*8c35d5eeSXin Li A <a href="copyright.html">copyright notice</a> and author information are optional. 2336*8c35d5eeSXin Li File overviews are generally recommended whenever a file consists of 2337*8c35d5eeSXin Li more than a single class definition. The top level comment is 2338*8c35d5eeSXin Li designed to orient readers unfamiliar with the code to what is in 2339*8c35d5eeSXin Li this file. If present, it should provide a description of the 2340*8c35d5eeSXin Li file's contents and any dependencies or compatibility information. 2341*8c35d5eeSXin Li As an example: 2342*8c35d5eeSXin Li </p> 2343*8c35d5eeSXin Li 2344*8c35d5eeSXin Li <CODE_SNIPPET> 2345*8c35d5eeSXin Li /** 2346*8c35d5eeSXin Li * @fileoverview Description of file, its uses and information 2347*8c35d5eeSXin Li * about its dependencies. 2348*8c35d5eeSXin Li */ 2349*8c35d5eeSXin Li </CODE_SNIPPET> 2350*8c35d5eeSXin Li 2351*8c35d5eeSXin Li 2352*8c35d5eeSXin Li </SUBSECTION> 2353*8c35d5eeSXin Li 2354*8c35d5eeSXin Li <SUBSECTION title="Class Comments"> 2355*8c35d5eeSXin Li <p>Classes must be documented with a description and a 2356*8c35d5eeSXin Li <a href="#constructor-tag">type tag that 2357*8c35d5eeSXin Li identifies the constructor</a>. 2358*8c35d5eeSXin Li </p> 2359*8c35d5eeSXin Li 2360*8c35d5eeSXin Li <CODE_SNIPPET> 2361*8c35d5eeSXin Li /** 2362*8c35d5eeSXin Li * Class making something fun and easy. 2363*8c35d5eeSXin Li * @param {string} arg1 An argument that makes this more interesting. 2364*8c35d5eeSXin Li * @param {Array.<number>} arg2 List of numbers to be processed. 2365*8c35d5eeSXin Li * @constructor 2366*8c35d5eeSXin Li * @extends {goog.Disposable} 2367*8c35d5eeSXin Li */ 2368*8c35d5eeSXin Li project.MyClass = function(arg1, arg2) { 2369*8c35d5eeSXin Li // ... 2370*8c35d5eeSXin Li }; 2371*8c35d5eeSXin Li goog.inherits(project.MyClass, goog.Disposable); 2372*8c35d5eeSXin Li </CODE_SNIPPET> 2373*8c35d5eeSXin Li </SUBSECTION> 2374*8c35d5eeSXin Li 2375*8c35d5eeSXin Li <SUBSECTION title="Method and Function Comments"> 2376*8c35d5eeSXin Li <p>Parameter and return types should be documented. The method 2377*8c35d5eeSXin Li description may be omitted if it is obvious from the parameter 2378*8c35d5eeSXin Li or return type descriptions. Method descriptions should start 2379*8c35d5eeSXin Li with a sentence written in the third person declarative voice.</p> 2380*8c35d5eeSXin Li <CODE_SNIPPET> 2381*8c35d5eeSXin Li /** 2382*8c35d5eeSXin Li * Operates on an instance of MyClass and returns something. 2383*8c35d5eeSXin Li * @param {project.MyClass} obj Instance of MyClass which leads to a long 2384*8c35d5eeSXin Li * comment that needs to be wrapped to two lines. 2385*8c35d5eeSXin Li * @return {boolean} Whether something occurred. 2386*8c35d5eeSXin Li */ 2387*8c35d5eeSXin Li function PR_someMethod(obj) { 2388*8c35d5eeSXin Li // ... 2389*8c35d5eeSXin Li } 2390*8c35d5eeSXin Li </CODE_SNIPPET> 2391*8c35d5eeSXin Li </SUBSECTION> 2392*8c35d5eeSXin Li 2393*8c35d5eeSXin Li <SUBSECTION title="Property Comments"> 2394*8c35d5eeSXin Li <CODE_SNIPPET> 2395*8c35d5eeSXin Li /** @constructor */ 2396*8c35d5eeSXin Li project.MyClass = function() { 2397*8c35d5eeSXin Li /** 2398*8c35d5eeSXin Li * Maximum number of things per pane. 2399*8c35d5eeSXin Li * @type {number} 2400*8c35d5eeSXin Li */ 2401*8c35d5eeSXin Li this.someProperty = 4; 2402*8c35d5eeSXin Li } 2403*8c35d5eeSXin Li </CODE_SNIPPET> 2404*8c35d5eeSXin Li </SUBSECTION> 2405*8c35d5eeSXin Li 2406*8c35d5eeSXin Li <SUBSECTION title="JSDoc Tag Reference"> 2407*8c35d5eeSXin Li <a name="JSDoc_Tag_Reference"/> 2408*8c35d5eeSXin Li <p/> 2409*8c35d5eeSXin Li <table border="1" style="border-collapse:collapse" cellpadding="4"> 2410*8c35d5eeSXin Li <thead> 2411*8c35d5eeSXin Li <tr> 2412*8c35d5eeSXin Li <th>Tag</th> 2413*8c35d5eeSXin Li <th>Template & Examples</th> 2414*8c35d5eeSXin Li <th>Description</th> 2415*8c35d5eeSXin Li </tr> 2416*8c35d5eeSXin Li </thead> 2417*8c35d5eeSXin Li <tbody> 2418*8c35d5eeSXin Li <tr> 2419*8c35d5eeSXin Li <td> 2420*8c35d5eeSXin Li <a name="tag-author">@author</a> 2421*8c35d5eeSXin Li 2422*8c35d5eeSXin Li </td> 2423*8c35d5eeSXin Li <td> 2424*8c35d5eeSXin Li <code>@author [email protected] (first last)</code> 2425*8c35d5eeSXin Li <p><i>For example:</i></p> 2426*8c35d5eeSXin Li <CODE_SNIPPET> 2427*8c35d5eeSXin Li /** 2428*8c35d5eeSXin Li * @fileoverview Utilities for handling textareas. 2429*8c35d5eeSXin Li * @author [email protected] (Uthur Pendragon) 2430*8c35d5eeSXin Li */ 2431*8c35d5eeSXin Li </CODE_SNIPPET> 2432*8c35d5eeSXin Li </td> 2433*8c35d5eeSXin Li <td> 2434*8c35d5eeSXin Li Document the author of a file or the owner of a test, 2435*8c35d5eeSXin Li generally only used in the <code>@fileoverview</code> comment. 2436*8c35d5eeSXin Li 2437*8c35d5eeSXin Li </td> 2438*8c35d5eeSXin Li </tr> 2439*8c35d5eeSXin Li 2440*8c35d5eeSXin Li 2441*8c35d5eeSXin Li 2442*8c35d5eeSXin Li <tr> 2443*8c35d5eeSXin Li <td><a name="tag-code">@code</a></td> 2444*8c35d5eeSXin Li <td> 2445*8c35d5eeSXin Li <code>{@code ...}</code> 2446*8c35d5eeSXin Li <p><i>For example:</i></p> 2447*8c35d5eeSXin Li <CODE_SNIPPET> 2448*8c35d5eeSXin Li /** 2449*8c35d5eeSXin Li * Moves to the next position in the selection. 2450*8c35d5eeSXin Li * Throws {@code goog.iter.StopIteration} when it 2451*8c35d5eeSXin Li * passes the end of the range. 2452*8c35d5eeSXin Li * @return {Node} The node at the next position. 2453*8c35d5eeSXin Li */ 2454*8c35d5eeSXin Li goog.dom.RangeIterator.prototype.next = function() { 2455*8c35d5eeSXin Li // ... 2456*8c35d5eeSXin Li }; 2457*8c35d5eeSXin Li </CODE_SNIPPET> 2458*8c35d5eeSXin Li </td> 2459*8c35d5eeSXin Li <td> 2460*8c35d5eeSXin Li Indicates that a term in a JSDoc description is code so it may 2461*8c35d5eeSXin Li be correctly formatted in generated documentation. 2462*8c35d5eeSXin Li </td> 2463*8c35d5eeSXin Li </tr> 2464*8c35d5eeSXin Li 2465*8c35d5eeSXin Li <tr> 2466*8c35d5eeSXin Li <td><a name="tag-const">@const</a></td> 2467*8c35d5eeSXin Li <td> 2468*8c35d5eeSXin Li <code>@const</code><br/> 2469*8c35d5eeSXin Li <code>@const {type}</code> 2470*8c35d5eeSXin Li <p><i>For example:</i></p> 2471*8c35d5eeSXin Li <CODE_SNIPPET> 2472*8c35d5eeSXin Li /** @const */ var MY_BEER = 'stout'; 2473*8c35d5eeSXin Li 2474*8c35d5eeSXin Li /** 2475*8c35d5eeSXin Li * My namespace's favorite kind of beer. 2476*8c35d5eeSXin Li * @const {string} 2477*8c35d5eeSXin Li */ 2478*8c35d5eeSXin Li mynamespace.MY_BEER = 'stout'; 2479*8c35d5eeSXin Li 2480*8c35d5eeSXin Li /** @const */ MyClass.MY_BEER = 'stout'; 2481*8c35d5eeSXin Li 2482*8c35d5eeSXin Li /** 2483*8c35d5eeSXin Li * Initializes the request. 2484*8c35d5eeSXin Li * @const 2485*8c35d5eeSXin Li */ 2486*8c35d5eeSXin Li mynamespace.Request.prototype.initialize = function() { 2487*8c35d5eeSXin Li // This method cannot be overridden in a subclass. 2488*8c35d5eeSXin Li }; 2489*8c35d5eeSXin Li </CODE_SNIPPET> 2490*8c35d5eeSXin Li </td> 2491*8c35d5eeSXin Li <td> 2492*8c35d5eeSXin Li <p>Marks a variable (or property) as read-only and suitable 2493*8c35d5eeSXin Li for inlining.</p> 2494*8c35d5eeSXin Li 2495*8c35d5eeSXin Li <p>A <code>@const</code> variable is an immutable pointer to 2496*8c35d5eeSXin Li a value. If a variable or property marked as 2497*8c35d5eeSXin Li <code>@const</code> is overwritten, JSCompiler will give 2498*8c35d5eeSXin Li warnings.</p> 2499*8c35d5eeSXin Li 2500*8c35d5eeSXin Li <p>The type declaration of a constant value can be omitted 2501*8c35d5eeSXin Li if it can be clearly inferred. An additional comment about 2502*8c35d5eeSXin Li the variable is optional.</p> 2503*8c35d5eeSXin Li 2504*8c35d5eeSXin Li <p>When <code>@const</code> is applied to a method, it 2505*8c35d5eeSXin Li implies the method is not only not overwritable, but also 2506*8c35d5eeSXin Li that the method is <em>finalized</em> — 2507*8c35d5eeSXin Li not overridable in subclasses.</p> 2508*8c35d5eeSXin Li 2509*8c35d5eeSXin Li <p>For more on <code>@const</code>, see the 2510*8c35d5eeSXin Li <a href="#Constants">Constants</a> section.</p> 2511*8c35d5eeSXin Li 2512*8c35d5eeSXin Li </td> 2513*8c35d5eeSXin Li </tr> 2514*8c35d5eeSXin Li 2515*8c35d5eeSXin Li <tr> 2516*8c35d5eeSXin Li <td><a name="tag-constructor">@constructor</a></td> 2517*8c35d5eeSXin Li <td> 2518*8c35d5eeSXin Li <code>@constructor</code> 2519*8c35d5eeSXin Li <p><i>For example:</i></p> 2520*8c35d5eeSXin Li <CODE_SNIPPET> 2521*8c35d5eeSXin Li /** 2522*8c35d5eeSXin Li * A rectangle. 2523*8c35d5eeSXin Li * @constructor 2524*8c35d5eeSXin Li */ 2525*8c35d5eeSXin Li function GM_Rect() { 2526*8c35d5eeSXin Li ... 2527*8c35d5eeSXin Li } 2528*8c35d5eeSXin Li </CODE_SNIPPET> 2529*8c35d5eeSXin Li </td> 2530*8c35d5eeSXin Li <td> 2531*8c35d5eeSXin Li Used in a class's documentation to indicate the constructor. 2532*8c35d5eeSXin Li </td> 2533*8c35d5eeSXin Li </tr> 2534*8c35d5eeSXin Li 2535*8c35d5eeSXin Li <tr> 2536*8c35d5eeSXin Li <td><a name="tag-define">@define</a></td> 2537*8c35d5eeSXin Li <td> 2538*8c35d5eeSXin Li <code>@define {Type} description</code> 2539*8c35d5eeSXin Li <p><i>For example:</i></p> 2540*8c35d5eeSXin Li <CODE_SNIPPET> 2541*8c35d5eeSXin Li /** @define {boolean} */ 2542*8c35d5eeSXin Li var TR_FLAGS_ENABLE_DEBUG = true; 2543*8c35d5eeSXin Li 2544*8c35d5eeSXin Li /** 2545*8c35d5eeSXin Li * @define {boolean} Whether we know at compile-time that 2546*8c35d5eeSXin Li * the browser is IE. 2547*8c35d5eeSXin Li */ 2548*8c35d5eeSXin Li goog.userAgent.ASSUME_IE = false; 2549*8c35d5eeSXin Li </CODE_SNIPPET> 2550*8c35d5eeSXin Li </td> 2551*8c35d5eeSXin Li <td> 2552*8c35d5eeSXin Li Indicates a constant that can be overridden by the compiler at 2553*8c35d5eeSXin Li compile-time. In the example, the compiler flag 2554*8c35d5eeSXin Li <code>--define='goog.userAgent.ASSUME_IE=true'</code> 2555*8c35d5eeSXin Li could be specified in the BUILD file to indicate that the 2556*8c35d5eeSXin Li constant <code>goog.userAgent.ASSUME_IE</code> should be replaced 2557*8c35d5eeSXin Li with <code>true</code>. 2558*8c35d5eeSXin Li </td> 2559*8c35d5eeSXin Li </tr> 2560*8c35d5eeSXin Li 2561*8c35d5eeSXin Li <tr> 2562*8c35d5eeSXin Li <td><a name="tag-deprecated">@deprecated</a></td> 2563*8c35d5eeSXin Li <td> 2564*8c35d5eeSXin Li <code>@deprecated Description</code> 2565*8c35d5eeSXin Li <p><i>For example:</i></p> 2566*8c35d5eeSXin Li <CODE_SNIPPET> 2567*8c35d5eeSXin Li /** 2568*8c35d5eeSXin Li * Determines whether a node is a field. 2569*8c35d5eeSXin Li * @return {boolean} True if the contents of 2570*8c35d5eeSXin Li * the element are editable, but the element 2571*8c35d5eeSXin Li * itself is not. 2572*8c35d5eeSXin Li * @deprecated Use isField(). 2573*8c35d5eeSXin Li */ 2574*8c35d5eeSXin Li BN_EditUtil.isTopEditableField = function(node) { 2575*8c35d5eeSXin Li // ... 2576*8c35d5eeSXin Li }; 2577*8c35d5eeSXin Li </CODE_SNIPPET> 2578*8c35d5eeSXin Li </td> 2579*8c35d5eeSXin Li <td> 2580*8c35d5eeSXin Li Used to tell that a function, method or property should not be 2581*8c35d5eeSXin Li used any more. Always provide instructions on what callers 2582*8c35d5eeSXin Li should use instead. 2583*8c35d5eeSXin Li </td> 2584*8c35d5eeSXin Li </tr> 2585*8c35d5eeSXin Li 2586*8c35d5eeSXin Li <tr> 2587*8c35d5eeSXin Li <td><a name="tag-dict">@dict</a></td> 2588*8c35d5eeSXin Li <td> 2589*8c35d5eeSXin Li <code>@dict Description</code> 2590*8c35d5eeSXin Li <p><i>For example:</i></p> 2591*8c35d5eeSXin Li <CODE_SNIPPET> 2592*8c35d5eeSXin Li /** 2593*8c35d5eeSXin Li * @constructor 2594*8c35d5eeSXin Li * @dict 2595*8c35d5eeSXin Li */ 2596*8c35d5eeSXin Li function Foo(x) { 2597*8c35d5eeSXin Li this['x'] = x; 2598*8c35d5eeSXin Li } 2599*8c35d5eeSXin Li var obj = new Foo(123); 2600*8c35d5eeSXin Li var num = obj.x; // warning 2601*8c35d5eeSXin Li 2602*8c35d5eeSXin Li (/** @dict */ { x: 1 }).x = 123; // warning 2603*8c35d5eeSXin Li </CODE_SNIPPET> 2604*8c35d5eeSXin Li </td> 2605*8c35d5eeSXin Li <td> 2606*8c35d5eeSXin Li When a constructor (<code>Foo</code> in the example) is 2607*8c35d5eeSXin Li annotated with <code>@dict</code>, you can only use the 2608*8c35d5eeSXin Li bracket notation to access the properties of <code>Foo</code> 2609*8c35d5eeSXin Li objects. 2610*8c35d5eeSXin Li The annotation can also be used directly on object literals. 2611*8c35d5eeSXin Li </td> 2612*8c35d5eeSXin Li </tr> 2613*8c35d5eeSXin Li 2614*8c35d5eeSXin Li <tr> 2615*8c35d5eeSXin Li <td><a name="tag-enum">@enum</a></td> 2616*8c35d5eeSXin Li <td> 2617*8c35d5eeSXin Li <code>@enum {Type}</code> 2618*8c35d5eeSXin Li <p><i>For example:</i></p> 2619*8c35d5eeSXin Li <CODE_SNIPPET> 2620*8c35d5eeSXin Li /** 2621*8c35d5eeSXin Li * Enum for tri-state values. 2622*8c35d5eeSXin Li * @enum {number} 2623*8c35d5eeSXin Li */ 2624*8c35d5eeSXin Li project.TriState = { 2625*8c35d5eeSXin Li TRUE: 1, 2626*8c35d5eeSXin Li FALSE: -1, 2627*8c35d5eeSXin Li MAYBE: 0 2628*8c35d5eeSXin Li }; 2629*8c35d5eeSXin Li </CODE_SNIPPET> 2630*8c35d5eeSXin Li </td> 2631*8c35d5eeSXin Li </tr> 2632*8c35d5eeSXin Li 2633*8c35d5eeSXin Li <tr> 2634*8c35d5eeSXin Li <td><a name="tag-export">@export</a></td> 2635*8c35d5eeSXin Li <td> 2636*8c35d5eeSXin Li <code>@export</code> 2637*8c35d5eeSXin Li <p><i>For example:</i></p> 2638*8c35d5eeSXin Li <CODE_SNIPPET> 2639*8c35d5eeSXin Li /** @export */ 2640*8c35d5eeSXin Li foo.MyPublicClass.prototype.myPublicMethod = function() { 2641*8c35d5eeSXin Li // ... 2642*8c35d5eeSXin Li }; 2643*8c35d5eeSXin Li </CODE_SNIPPET> 2644*8c35d5eeSXin Li </td> 2645*8c35d5eeSXin Li <td> 2646*8c35d5eeSXin Li <p>Given the code on the left, when the compiler is run with 2647*8c35d5eeSXin Li the <code>--generate_exports</code> flag, it will generate the 2648*8c35d5eeSXin Li code:</p> 2649*8c35d5eeSXin Li <CODE_SNIPPET> 2650*8c35d5eeSXin Li goog.exportSymbol('foo.MyPublicClass.prototype.myPublicMethod', 2651*8c35d5eeSXin Li foo.MyPublicClass.prototype.myPublicMethod); 2652*8c35d5eeSXin Li </CODE_SNIPPET> 2653*8c35d5eeSXin Li <p>which will export the symbols to uncompiled code. 2654*8c35d5eeSXin Li Code that uses the <code>@export</code> annotation must either</p> 2655*8c35d5eeSXin Li <ol> 2656*8c35d5eeSXin Li <li>include <code>//javascript/closure/base.js</code>, or</li> 2657*8c35d5eeSXin Li <li>define both <code>goog.exportSymbol</code> and 2658*8c35d5eeSXin Li <code>goog.exportProperty</code> with the same method 2659*8c35d5eeSXin Li signature in their own codebase.</li> 2660*8c35d5eeSXin Li </ol> 2661*8c35d5eeSXin Li </td> 2662*8c35d5eeSXin Li </tr> 2663*8c35d5eeSXin Li 2664*8c35d5eeSXin Li <tr> 2665*8c35d5eeSXin Li <td><a name="tag-expose">@expose</a></td> 2666*8c35d5eeSXin Li <td> 2667*8c35d5eeSXin Li <code>@expose</code> 2668*8c35d5eeSXin Li <p><i>For example:</i></p> 2669*8c35d5eeSXin Li <CODE_SNIPPET> 2670*8c35d5eeSXin Li /** @expose */ 2671*8c35d5eeSXin Li MyClass.prototype.exposedProperty = 3; 2672*8c35d5eeSXin Li </CODE_SNIPPET> 2673*8c35d5eeSXin Li </td> 2674*8c35d5eeSXin Li <td> 2675*8c35d5eeSXin Li <p> 2676*8c35d5eeSXin Li Declares an exposed property. Exposed properties 2677*8c35d5eeSXin Li will not be removed, or renamed, or collapsed, 2678*8c35d5eeSXin Li or optimized in any way by the compiler. No properties 2679*8c35d5eeSXin Li with the same name will be able to be optimized either. 2680*8c35d5eeSXin Li </p> 2681*8c35d5eeSXin Li 2682*8c35d5eeSXin Li <p> 2683*8c35d5eeSXin Li <code>@expose</code> should never be used in library code, 2684*8c35d5eeSXin Li because it will prevent that property from ever getting 2685*8c35d5eeSXin Li removed. 2686*8c35d5eeSXin Li </p> 2687*8c35d5eeSXin Li </td> 2688*8c35d5eeSXin Li </tr> 2689*8c35d5eeSXin Li 2690*8c35d5eeSXin Li <tr> 2691*8c35d5eeSXin Li <td><a name="tag-extends">@extends</a></td> 2692*8c35d5eeSXin Li <td> 2693*8c35d5eeSXin Li <code> 2694*8c35d5eeSXin Li @extends Type<br/> 2695*8c35d5eeSXin Li @extends {Type} 2696*8c35d5eeSXin Li </code> 2697*8c35d5eeSXin Li <p><i>For example:</i></p> 2698*8c35d5eeSXin Li <CODE_SNIPPET> 2699*8c35d5eeSXin Li /** 2700*8c35d5eeSXin Li * Immutable empty node list. 2701*8c35d5eeSXin Li * @constructor 2702*8c35d5eeSXin Li * @extends goog.ds.BasicNodeList 2703*8c35d5eeSXin Li */ 2704*8c35d5eeSXin Li goog.ds.EmptyNodeList = function() { 2705*8c35d5eeSXin Li ... 2706*8c35d5eeSXin Li }; 2707*8c35d5eeSXin Li </CODE_SNIPPET> 2708*8c35d5eeSXin Li </td> 2709*8c35d5eeSXin Li <td> 2710*8c35d5eeSXin Li Used with <code>@constructor</code> to indicate that a class 2711*8c35d5eeSXin Li inherits from another class. Curly braces around the type are 2712*8c35d5eeSXin Li optional. 2713*8c35d5eeSXin Li </td> 2714*8c35d5eeSXin Li </tr> 2715*8c35d5eeSXin Li 2716*8c35d5eeSXin Li <tr> 2717*8c35d5eeSXin Li <td><a name="tag-externs">@externs</a></td> 2718*8c35d5eeSXin Li <td> 2719*8c35d5eeSXin Li <code>@externs</code> 2720*8c35d5eeSXin Li <p><i>For example:</i></p> 2721*8c35d5eeSXin Li <CODE_SNIPPET> 2722*8c35d5eeSXin Li /** 2723*8c35d5eeSXin Li * @fileoverview This is an externs file. 2724*8c35d5eeSXin Li * @externs 2725*8c35d5eeSXin Li */ 2726*8c35d5eeSXin Li 2727*8c35d5eeSXin Li var document; 2728*8c35d5eeSXin Li </CODE_SNIPPET> 2729*8c35d5eeSXin Li </td> 2730*8c35d5eeSXin Li <td> 2731*8c35d5eeSXin Li <p> 2732*8c35d5eeSXin Li Declares an 2733*8c35d5eeSXin Li 2734*8c35d5eeSXin Li externs file. 2735*8c35d5eeSXin Li </p> 2736*8c35d5eeSXin Li 2737*8c35d5eeSXin Li 2738*8c35d5eeSXin Li </td> 2739*8c35d5eeSXin Li </tr> 2740*8c35d5eeSXin Li 2741*8c35d5eeSXin Li <tr> 2742*8c35d5eeSXin Li <td><a name="tag-fileoverview">@fileoverview</a></td> 2743*8c35d5eeSXin Li <td> 2744*8c35d5eeSXin Li <code>@fileoverview Description</code> 2745*8c35d5eeSXin Li <p><i>For example:</i></p> 2746*8c35d5eeSXin Li <CODE_SNIPPET> 2747*8c35d5eeSXin Li /** 2748*8c35d5eeSXin Li * @fileoverview Utilities for doing things that require this very long 2749*8c35d5eeSXin Li * but not indented comment. 2750*8c35d5eeSXin Li * @author [email protected] (Uthur Pendragon) 2751*8c35d5eeSXin Li */ 2752*8c35d5eeSXin Li </CODE_SNIPPET> 2753*8c35d5eeSXin Li </td> 2754*8c35d5eeSXin Li <td>Makes the comment block provide file level information.</td> 2755*8c35d5eeSXin Li </tr> 2756*8c35d5eeSXin Li 2757*8c35d5eeSXin Li <tr> 2758*8c35d5eeSXin Li <td><a name="tag-implements">@implements</a></td> 2759*8c35d5eeSXin Li <td> 2760*8c35d5eeSXin Li <code> 2761*8c35d5eeSXin Li @implements Type<br/> 2762*8c35d5eeSXin Li @implements {Type} 2763*8c35d5eeSXin Li </code> 2764*8c35d5eeSXin Li <p><i>For example:</i></p> 2765*8c35d5eeSXin Li <CODE_SNIPPET> 2766*8c35d5eeSXin Li /** 2767*8c35d5eeSXin Li * A shape. 2768*8c35d5eeSXin Li * @interface 2769*8c35d5eeSXin Li */ 2770*8c35d5eeSXin Li function Shape() {}; 2771*8c35d5eeSXin Li Shape.prototype.draw = function() {}; 2772*8c35d5eeSXin Li 2773*8c35d5eeSXin Li /** 2774*8c35d5eeSXin Li * @constructor 2775*8c35d5eeSXin Li * @implements {Shape} 2776*8c35d5eeSXin Li */ 2777*8c35d5eeSXin Li function Square() {}; 2778*8c35d5eeSXin Li Square.prototype.draw = function() { 2779*8c35d5eeSXin Li ... 2780*8c35d5eeSXin Li }; 2781*8c35d5eeSXin Li </CODE_SNIPPET> 2782*8c35d5eeSXin Li </td> 2783*8c35d5eeSXin Li <td> 2784*8c35d5eeSXin Li Used with <code>@constructor</code> to indicate that a class 2785*8c35d5eeSXin Li implements an interface. Curly braces around the type are 2786*8c35d5eeSXin Li optional. 2787*8c35d5eeSXin Li </td> 2788*8c35d5eeSXin Li </tr> 2789*8c35d5eeSXin Li 2790*8c35d5eeSXin Li <tr> 2791*8c35d5eeSXin Li <td><a name="tag-inheritDoc">@inheritDoc</a></td> 2792*8c35d5eeSXin Li <td> 2793*8c35d5eeSXin Li <code>@inheritDoc</code> 2794*8c35d5eeSXin Li <p><i>For example:</i></p> 2795*8c35d5eeSXin Li <CODE_SNIPPET> 2796*8c35d5eeSXin Li /** @inheritDoc */ 2797*8c35d5eeSXin Li project.SubClass.prototype.toString() { 2798*8c35d5eeSXin Li // ... 2799*8c35d5eeSXin Li }; 2800*8c35d5eeSXin Li </CODE_SNIPPET> 2801*8c35d5eeSXin Li </td> 2802*8c35d5eeSXin Li <td> 2803*8c35d5eeSXin Li <p style="font-weight:bold">Deprecated. Use 2804*8c35d5eeSXin Li <code>@override</code> instead.</p> 2805*8c35d5eeSXin Li 2806*8c35d5eeSXin Li Indicates that a method or property of a subclass 2807*8c35d5eeSXin Li intentionally hides a method or property of the superclass, 2808*8c35d5eeSXin Li and has exactly the same documentation. Notice that 2809*8c35d5eeSXin Li <code>@inheritDoc</code> implies <code>@override</code> 2810*8c35d5eeSXin Li </td> 2811*8c35d5eeSXin Li </tr> 2812*8c35d5eeSXin Li 2813*8c35d5eeSXin Li <tr> 2814*8c35d5eeSXin Li <td><a name="tag-interface">@interface</a></td> 2815*8c35d5eeSXin Li <td> 2816*8c35d5eeSXin Li <code>@interface</code> 2817*8c35d5eeSXin Li <p><i>For example:</i></p> 2818*8c35d5eeSXin Li <CODE_SNIPPET> 2819*8c35d5eeSXin Li /** 2820*8c35d5eeSXin Li * A shape. 2821*8c35d5eeSXin Li * @interface 2822*8c35d5eeSXin Li */ 2823*8c35d5eeSXin Li function Shape() {}; 2824*8c35d5eeSXin Li Shape.prototype.draw = function() {}; 2825*8c35d5eeSXin Li 2826*8c35d5eeSXin Li /** 2827*8c35d5eeSXin Li * A polygon. 2828*8c35d5eeSXin Li * @interface 2829*8c35d5eeSXin Li * @extends {Shape} 2830*8c35d5eeSXin Li */ 2831*8c35d5eeSXin Li function Polygon() {}; 2832*8c35d5eeSXin Li Polygon.prototype.getSides = function() {}; 2833*8c35d5eeSXin Li </CODE_SNIPPET> 2834*8c35d5eeSXin Li </td> 2835*8c35d5eeSXin Li <td> 2836*8c35d5eeSXin Li Used to indicate that the function defines an interface. 2837*8c35d5eeSXin Li </td> 2838*8c35d5eeSXin Li </tr> 2839*8c35d5eeSXin Li 2840*8c35d5eeSXin Li <tr> 2841*8c35d5eeSXin Li <td><a name="tag-lends">@lends</a></td> 2842*8c35d5eeSXin Li <td> 2843*8c35d5eeSXin Li <code>@lends objectName</code><br/> 2844*8c35d5eeSXin Li <code>@lends {objectName}</code> 2845*8c35d5eeSXin Li <p><i>For example:</i></p> 2846*8c35d5eeSXin Li <CODE_SNIPPET> 2847*8c35d5eeSXin Li goog.object.extend( 2848*8c35d5eeSXin Li Button.prototype, 2849*8c35d5eeSXin Li /** @lends {Button.prototype} */ { 2850*8c35d5eeSXin Li isButton: function() { return true; } 2851*8c35d5eeSXin Li }); 2852*8c35d5eeSXin Li </CODE_SNIPPET> 2853*8c35d5eeSXin Li </td> 2854*8c35d5eeSXin Li <td> 2855*8c35d5eeSXin Li Indicates that the keys of an object literal should 2856*8c35d5eeSXin Li be treated as properties of some other object. This annotation 2857*8c35d5eeSXin Li should only appear on object literals.<p/> 2858*8c35d5eeSXin Li 2859*8c35d5eeSXin Li Notice that the name in braces is not a type name like 2860*8c35d5eeSXin Li in other annotations. It's an object name. It names 2861*8c35d5eeSXin Li the object on which the properties are "lent". 2862*8c35d5eeSXin Li For example, <code>@type {Foo}</code> means "an instance of Foo", 2863*8c35d5eeSXin Li but <code>@lends {Foo}</code> means "the constructor Foo".<p/> 2864*8c35d5eeSXin Li 2865*8c35d5eeSXin Li The <a href="https://code.google.com/p/jsdoc-toolkit/wiki/TagLends"> 2866*8c35d5eeSXin Li JSDoc Toolkit docs</a> have more information on this 2867*8c35d5eeSXin Li annotation. 2868*8c35d5eeSXin Li </td> 2869*8c35d5eeSXin Li </tr> 2870*8c35d5eeSXin Li 2871*8c35d5eeSXin Li <tr> 2872*8c35d5eeSXin Li <td><a name="tag-license">@license</a> or 2873*8c35d5eeSXin Li <a name="tag-preserve">@preserve</a></td> 2874*8c35d5eeSXin Li <td> 2875*8c35d5eeSXin Li <code>@license Description</code> 2876*8c35d5eeSXin Li <p><i>For example:</i></p> 2877*8c35d5eeSXin Li <CODE_SNIPPET> 2878*8c35d5eeSXin Li /** 2879*8c35d5eeSXin Li * @preserve Copyright 2009 SomeThirdParty. 2880*8c35d5eeSXin Li * Here is the full license text and copyright 2881*8c35d5eeSXin Li * notice for this file. Note that the notice can span several 2882*8c35d5eeSXin Li * lines and is only terminated by the closing star and slash: 2883*8c35d5eeSXin Li */ 2884*8c35d5eeSXin Li </CODE_SNIPPET> 2885*8c35d5eeSXin Li </td> 2886*8c35d5eeSXin Li <td> 2887*8c35d5eeSXin Li Anything marked by <code>@license</code> or 2888*8c35d5eeSXin Li <code>@preserve</code> will be retained by the compiler and 2889*8c35d5eeSXin Li output at the top of the compiled code for that file. This 2890*8c35d5eeSXin Li annotation allows important notices (such as legal licenses or 2891*8c35d5eeSXin Li copyright text) to survive compilation unchanged. Line breaks 2892*8c35d5eeSXin Li are preserved. 2893*8c35d5eeSXin Li </td> 2894*8c35d5eeSXin Li </tr> 2895*8c35d5eeSXin Li 2896*8c35d5eeSXin Li 2897*8c35d5eeSXin Li 2898*8c35d5eeSXin Li 2899*8c35d5eeSXin Li 2900*8c35d5eeSXin Li <tr> 2901*8c35d5eeSXin Li <td><a name="tag-noalias">@noalias</a></td> 2902*8c35d5eeSXin Li <td> 2903*8c35d5eeSXin Li <code>@noalias</code> 2904*8c35d5eeSXin Li <p><i>For example:</i></p> 2905*8c35d5eeSXin Li <CODE_SNIPPET> 2906*8c35d5eeSXin Li /** @noalias */ 2907*8c35d5eeSXin Li function Range() {} 2908*8c35d5eeSXin Li </CODE_SNIPPET> 2909*8c35d5eeSXin Li </td> 2910*8c35d5eeSXin Li <td> 2911*8c35d5eeSXin Li Used in an externs file to indicate to the compiler that the 2912*8c35d5eeSXin Li variable or function should not be aliased as part of the 2913*8c35d5eeSXin Li alias externals pass of the compiler. 2914*8c35d5eeSXin Li </td> 2915*8c35d5eeSXin Li </tr> 2916*8c35d5eeSXin Li 2917*8c35d5eeSXin Li <tr> 2918*8c35d5eeSXin Li <td><a name="tag-nocompile">@nocompile</a></td> 2919*8c35d5eeSXin Li <td> 2920*8c35d5eeSXin Li <code>@nocompile</code> 2921*8c35d5eeSXin Li <p><i>For example:</i></p> 2922*8c35d5eeSXin Li <CODE_SNIPPET> 2923*8c35d5eeSXin Li /** @nocompile */ 2924*8c35d5eeSXin Li 2925*8c35d5eeSXin Li // JavaScript code 2926*8c35d5eeSXin Li </CODE_SNIPPET> 2927*8c35d5eeSXin Li </td> 2928*8c35d5eeSXin Li <td> 2929*8c35d5eeSXin Li Used at the top of a file to tell the compiler to parse this 2930*8c35d5eeSXin Li file but not compile it. 2931*8c35d5eeSXin Li Code that is not meant for compilation and should be omitted 2932*8c35d5eeSXin Li from compilation tests (such as bootstrap code) uses this 2933*8c35d5eeSXin Li annotation. 2934*8c35d5eeSXin Li Use sparingly. 2935*8c35d5eeSXin Li </td> 2936*8c35d5eeSXin Li </tr> 2937*8c35d5eeSXin Li 2938*8c35d5eeSXin Li <tr> 2939*8c35d5eeSXin Li <td><a name="tag-nosideeffects">@nosideeffects</a></td> 2940*8c35d5eeSXin Li <td> 2941*8c35d5eeSXin Li <code>@nosideeffects</code> 2942*8c35d5eeSXin Li <p><i>For example:</i></p> 2943*8c35d5eeSXin Li <CODE_SNIPPET> 2944*8c35d5eeSXin Li /** @nosideeffects */ 2945*8c35d5eeSXin Li function noSideEffectsFn1() { 2946*8c35d5eeSXin Li // ... 2947*8c35d5eeSXin Li } 2948*8c35d5eeSXin Li 2949*8c35d5eeSXin Li /** @nosideeffects */ 2950*8c35d5eeSXin Li var noSideEffectsFn2 = function() { 2951*8c35d5eeSXin Li // ... 2952*8c35d5eeSXin Li }; 2953*8c35d5eeSXin Li 2954*8c35d5eeSXin Li /** @nosideeffects */ 2955*8c35d5eeSXin Li a.prototype.noSideEffectsFn3 = function() { 2956*8c35d5eeSXin Li // ... 2957*8c35d5eeSXin Li }; 2958*8c35d5eeSXin Li </CODE_SNIPPET> 2959*8c35d5eeSXin Li </td> 2960*8c35d5eeSXin Li <td> 2961*8c35d5eeSXin Li This annotation can be used as part of function and 2962*8c35d5eeSXin Li constructor declarations to indicate that calls to the 2963*8c35d5eeSXin Li declared function have no side-effects. This annotation 2964*8c35d5eeSXin Li allows the compiler to remove calls to these functions if the 2965*8c35d5eeSXin Li return value is not used. 2966*8c35d5eeSXin Li </td> 2967*8c35d5eeSXin Li </tr> 2968*8c35d5eeSXin Li 2969*8c35d5eeSXin Li <tr> 2970*8c35d5eeSXin Li <td><a name="tag-override">@override</a></td> 2971*8c35d5eeSXin Li <td> 2972*8c35d5eeSXin Li <code>@override</code> 2973*8c35d5eeSXin Li <p><i>For example:</i></p> 2974*8c35d5eeSXin Li <CODE_SNIPPET> 2975*8c35d5eeSXin Li /** 2976*8c35d5eeSXin Li * @return {string} Human-readable representation of project.SubClass. 2977*8c35d5eeSXin Li * @override 2978*8c35d5eeSXin Li */ 2979*8c35d5eeSXin Li project.SubClass.prototype.toString = function() { 2980*8c35d5eeSXin Li // ... 2981*8c35d5eeSXin Li }; 2982*8c35d5eeSXin Li </CODE_SNIPPET> 2983*8c35d5eeSXin Li </td> 2984*8c35d5eeSXin Li <td> 2985*8c35d5eeSXin Li Indicates that a method or property of a subclass 2986*8c35d5eeSXin Li intentionally hides a method or property of the superclass. If 2987*8c35d5eeSXin Li no other documentation is included, the method or property 2988*8c35d5eeSXin Li also inherits documentation from its superclass. 2989*8c35d5eeSXin Li </td> 2990*8c35d5eeSXin Li </tr> 2991*8c35d5eeSXin Li 2992*8c35d5eeSXin Li <tr> 2993*8c35d5eeSXin Li <td><a name="tag-param">@param</a></td> 2994*8c35d5eeSXin Li <td> 2995*8c35d5eeSXin Li <code>@param {Type} varname Description</code> 2996*8c35d5eeSXin Li <p><i>For example:</i></p> 2997*8c35d5eeSXin Li <CODE_SNIPPET> 2998*8c35d5eeSXin Li /** 2999*8c35d5eeSXin Li * Queries a Baz for items. 3000*8c35d5eeSXin Li * @param {number} groupNum Subgroup id to query. 3001*8c35d5eeSXin Li * @param {string|number|null} term An itemName, 3002*8c35d5eeSXin Li * or itemId, or null to search everything. 3003*8c35d5eeSXin Li */ 3004*8c35d5eeSXin Li goog.Baz.prototype.query = function(groupNum, term) { 3005*8c35d5eeSXin Li // ... 3006*8c35d5eeSXin Li }; 3007*8c35d5eeSXin Li </CODE_SNIPPET> 3008*8c35d5eeSXin Li </td> 3009*8c35d5eeSXin Li <td> 3010*8c35d5eeSXin Li Used with method, function and constructor calls to document 3011*8c35d5eeSXin Li the arguments of a function.<p/> 3012*8c35d5eeSXin Li 3013*8c35d5eeSXin Li <a href="#JsTypes">Type</a> 3014*8c35d5eeSXin Li names must be enclosed in curly braces. If the type 3015*8c35d5eeSXin Li is omitted, the compiler will not type-check the parameter. 3016*8c35d5eeSXin Li </td> 3017*8c35d5eeSXin Li </tr> 3018*8c35d5eeSXin Li 3019*8c35d5eeSXin Li <tr> 3020*8c35d5eeSXin Li <td><a name="tag-private">@private</a></td> 3021*8c35d5eeSXin Li <td> 3022*8c35d5eeSXin Li <code>@private</code><br/> 3023*8c35d5eeSXin Li <code>@private {type}</code> 3024*8c35d5eeSXin Li <p><i>For example:</i></p> 3025*8c35d5eeSXin Li <CODE_SNIPPET> 3026*8c35d5eeSXin Li /** 3027*8c35d5eeSXin Li * Handlers that are listening to this logger. 3028*8c35d5eeSXin Li * @private {!Array.<Function>} 3029*8c35d5eeSXin Li */ 3030*8c35d5eeSXin Li this.handlers_ = []; 3031*8c35d5eeSXin Li </CODE_SNIPPET> 3032*8c35d5eeSXin Li </td> 3033*8c35d5eeSXin Li <td> 3034*8c35d5eeSXin Li Used in conjunction with a trailing underscore on the method 3035*8c35d5eeSXin Li or property name to indicate that the member is 3036*8c35d5eeSXin Li <a href="#Visibility__private_and_protected_fields_">private</a> and final. 3037*8c35d5eeSXin Li </td> 3038*8c35d5eeSXin Li </tr> 3039*8c35d5eeSXin Li 3040*8c35d5eeSXin Li <tr> 3041*8c35d5eeSXin Li <td><a name="tag-protected">@protected</a></td> 3042*8c35d5eeSXin Li <td> 3043*8c35d5eeSXin Li <code>@protected</code><br/> 3044*8c35d5eeSXin Li <code>@protected {type}</code> 3045*8c35d5eeSXin Li <p><i>For example:</i></p> 3046*8c35d5eeSXin Li <CODE_SNIPPET> 3047*8c35d5eeSXin Li /** 3048*8c35d5eeSXin Li * Sets the component's root element to the given element. 3049*8c35d5eeSXin Li * @param {Element} element Root element for the component. 3050*8c35d5eeSXin Li * @protected 3051*8c35d5eeSXin Li */ 3052*8c35d5eeSXin Li goog.ui.Component.prototype.setElementInternal = function(element) { 3053*8c35d5eeSXin Li // ... 3054*8c35d5eeSXin Li }; 3055*8c35d5eeSXin Li </CODE_SNIPPET> 3056*8c35d5eeSXin Li </td> 3057*8c35d5eeSXin Li <td> 3058*8c35d5eeSXin Li Used to indicate that the member or property is 3059*8c35d5eeSXin Li <a href="#Visibility__private_and_protected_fields_">protected</a>. 3060*8c35d5eeSXin Li Should be used in conjunction with names with no trailing 3061*8c35d5eeSXin Li underscore. 3062*8c35d5eeSXin Li </td> 3063*8c35d5eeSXin Li </tr> 3064*8c35d5eeSXin Li 3065*8c35d5eeSXin Li <tr> 3066*8c35d5eeSXin Li <td><a name="tag-public">@public</a></td> 3067*8c35d5eeSXin Li <td> 3068*8c35d5eeSXin Li <code>@public</code><br/> 3069*8c35d5eeSXin Li <code>@public {type}</code> 3070*8c35d5eeSXin Li <p><i>For example:</i></p> 3071*8c35d5eeSXin Li <CODE_SNIPPET> 3072*8c35d5eeSXin Li /** 3073*8c35d5eeSXin Li * Whether to cancel the event in internal capture/bubble processing. 3074*8c35d5eeSXin Li * @public {boolean} 3075*8c35d5eeSXin Li * @suppress {visiblity} Referencing this outside this package is strongly 3076*8c35d5eeSXin Li * discouraged. 3077*8c35d5eeSXin Li */ 3078*8c35d5eeSXin Li goog.events.Event.prototype.propagationStopped_ = false; 3079*8c35d5eeSXin Li </CODE_SNIPPET> 3080*8c35d5eeSXin Li </td> 3081*8c35d5eeSXin Li <td> 3082*8c35d5eeSXin Li Used to indicate that the member or property is public. Variables and 3083*8c35d5eeSXin Li properties are public by default, so this annotation is rarely necessary. 3084*8c35d5eeSXin Li Should only be used in legacy code that cannot be easily changed to 3085*8c35d5eeSXin Li override the visibility of members that were named as private variables. 3086*8c35d5eeSXin Li </td> 3087*8c35d5eeSXin Li </tr> 3088*8c35d5eeSXin Li 3089*8c35d5eeSXin Li <tr> 3090*8c35d5eeSXin Li <td><a name="tag-return">@return</a></td> 3091*8c35d5eeSXin Li <td> 3092*8c35d5eeSXin Li <code>@return {Type} Description</code> 3093*8c35d5eeSXin Li <p><i>For example:</i></p> 3094*8c35d5eeSXin Li <CODE_SNIPPET> 3095*8c35d5eeSXin Li /** 3096*8c35d5eeSXin Li * @return {string} The hex ID of the last item. 3097*8c35d5eeSXin Li */ 3098*8c35d5eeSXin Li goog.Baz.prototype.getLastId = function() { 3099*8c35d5eeSXin Li // ... 3100*8c35d5eeSXin Li return id; 3101*8c35d5eeSXin Li }; 3102*8c35d5eeSXin Li </CODE_SNIPPET> 3103*8c35d5eeSXin Li </td> 3104*8c35d5eeSXin Li <td> 3105*8c35d5eeSXin Li Used with method and function calls to document the return 3106*8c35d5eeSXin Li type. When writing descriptions for boolean parameters, 3107*8c35d5eeSXin Li prefer "Whether the component is visible" to "True if the 3108*8c35d5eeSXin Li component is visible, false otherwise". If there is no return 3109*8c35d5eeSXin Li value, do not use an <code>@return</code> tag.<p/> 3110*8c35d5eeSXin Li 3111*8c35d5eeSXin Li <a href="#JsTypes">Type</a> 3112*8c35d5eeSXin Li names must be enclosed in curly braces. If the type 3113*8c35d5eeSXin Li is omitted, the compiler will not type-check the return value. 3114*8c35d5eeSXin Li </td> 3115*8c35d5eeSXin Li </tr> 3116*8c35d5eeSXin Li 3117*8c35d5eeSXin Li <tr> 3118*8c35d5eeSXin Li <td><a name="tag-see">@see</a></td> 3119*8c35d5eeSXin Li <td> 3120*8c35d5eeSXin Li <code>@see Link</code> 3121*8c35d5eeSXin Li <p><i>For example:</i></p> 3122*8c35d5eeSXin Li <CODE_SNIPPET> 3123*8c35d5eeSXin Li /** 3124*8c35d5eeSXin Li * Adds a single item, recklessly. 3125*8c35d5eeSXin Li * @see #addSafely 3126*8c35d5eeSXin Li * @see goog.Collect 3127*8c35d5eeSXin Li * @see goog.RecklessAdder#add 3128*8c35d5eeSXin Li ... 3129*8c35d5eeSXin Li </CODE_SNIPPET> 3130*8c35d5eeSXin Li </td> 3131*8c35d5eeSXin Li <td>Reference a lookup to another class function or method.</td> 3132*8c35d5eeSXin Li </tr> 3133*8c35d5eeSXin Li 3134*8c35d5eeSXin Li <tr> 3135*8c35d5eeSXin Li <td><a name="tag-struct">@struct</a></td> 3136*8c35d5eeSXin Li <td> 3137*8c35d5eeSXin Li <code>@struct Description</code> 3138*8c35d5eeSXin Li <p><i>For example:</i></p> 3139*8c35d5eeSXin Li <CODE_SNIPPET> 3140*8c35d5eeSXin Li /** 3141*8c35d5eeSXin Li * @constructor 3142*8c35d5eeSXin Li * @struct 3143*8c35d5eeSXin Li */ 3144*8c35d5eeSXin Li function Foo(x) { 3145*8c35d5eeSXin Li this.x = x; 3146*8c35d5eeSXin Li } 3147*8c35d5eeSXin Li var obj = new Foo(123); 3148*8c35d5eeSXin Li var num = obj['x']; // warning 3149*8c35d5eeSXin Li obj.y = "asdf"; // warning 3150*8c35d5eeSXin Li 3151*8c35d5eeSXin Li Foo.prototype = /** @struct */ { 3152*8c35d5eeSXin Li method1: function() {} 3153*8c35d5eeSXin Li }; 3154*8c35d5eeSXin Li Foo.prototype.method2 = function() {}; // warning 3155*8c35d5eeSXin Li </CODE_SNIPPET> 3156*8c35d5eeSXin Li </td> 3157*8c35d5eeSXin Li <td> 3158*8c35d5eeSXin Li When a constructor (<code>Foo</code> in the example) is 3159*8c35d5eeSXin Li annotated with <code>@struct</code>, you can only use the dot 3160*8c35d5eeSXin Li notation to access the properties of <code>Foo</code> objects. 3161*8c35d5eeSXin Li Also, you cannot add new properties to <code>Foo</code> 3162*8c35d5eeSXin Li objects after they have been created. 3163*8c35d5eeSXin Li The annotation can also be used directly on object literals. 3164*8c35d5eeSXin Li </td> 3165*8c35d5eeSXin Li </tr> 3166*8c35d5eeSXin Li 3167*8c35d5eeSXin Li <tr> 3168*8c35d5eeSXin Li <td><a name="tag-supported">@supported</a></td> 3169*8c35d5eeSXin Li <td> 3170*8c35d5eeSXin Li <code>@supported Description</code> 3171*8c35d5eeSXin Li <p><i>For example:</i></p> 3172*8c35d5eeSXin Li <CODE_SNIPPET> 3173*8c35d5eeSXin Li /** 3174*8c35d5eeSXin Li * @fileoverview Event Manager 3175*8c35d5eeSXin Li * Provides an abstracted interface to the 3176*8c35d5eeSXin Li * browsers' event systems. 3177*8c35d5eeSXin Li * @supported So far tested in IE6 and FF1.5 3178*8c35d5eeSXin Li */ 3179*8c35d5eeSXin Li </CODE_SNIPPET> 3180*8c35d5eeSXin Li </td> 3181*8c35d5eeSXin Li <td> 3182*8c35d5eeSXin Li Used in a fileoverview to indicate what browsers are supported 3183*8c35d5eeSXin Li by the file. 3184*8c35d5eeSXin Li </td> 3185*8c35d5eeSXin Li </tr> 3186*8c35d5eeSXin Li 3187*8c35d5eeSXin Li <tr> 3188*8c35d5eeSXin Li <td><a name="tag-suppress">@suppress</a></td> 3189*8c35d5eeSXin Li <td> 3190*8c35d5eeSXin Li <code> 3191*8c35d5eeSXin Li @suppress {warning1|warning2} 3192*8c35d5eeSXin Li </code> 3193*8c35d5eeSXin Li <code> 3194*8c35d5eeSXin Li @suppress {warning1,warning2} 3195*8c35d5eeSXin Li </code> 3196*8c35d5eeSXin Li <p><i>For example:</i></p> 3197*8c35d5eeSXin Li <CODE_SNIPPET> 3198*8c35d5eeSXin Li /** 3199*8c35d5eeSXin Li * @suppress {deprecated} 3200*8c35d5eeSXin Li */ 3201*8c35d5eeSXin Li function f() { 3202*8c35d5eeSXin Li deprecatedVersionOfF(); 3203*8c35d5eeSXin Li } 3204*8c35d5eeSXin Li </CODE_SNIPPET> 3205*8c35d5eeSXin Li </td> 3206*8c35d5eeSXin Li <td> 3207*8c35d5eeSXin Li Suppresses warnings from tools. Warning categories are 3208*8c35d5eeSXin Li separated by <code>|</code> or <code>,</code>. 3209*8c35d5eeSXin Li 3210*8c35d5eeSXin Li </td> 3211*8c35d5eeSXin Li </tr> 3212*8c35d5eeSXin Li 3213*8c35d5eeSXin Li <tr> 3214*8c35d5eeSXin Li <td><a name="tag-template">@template</a></td> 3215*8c35d5eeSXin Li <td> 3216*8c35d5eeSXin Li <code>@template</code> 3217*8c35d5eeSXin Li <p><i>For example:</i></p> 3218*8c35d5eeSXin Li <CODE_SNIPPET> 3219*8c35d5eeSXin Li /** 3220*8c35d5eeSXin Li * @param {function(this:T, ...)} fn 3221*8c35d5eeSXin Li * @param {T} thisObj 3222*8c35d5eeSXin Li * @param {...*} var_args 3223*8c35d5eeSXin Li * @template T 3224*8c35d5eeSXin Li */ 3225*8c35d5eeSXin Li goog.bind = function(fn, thisObj, var_args) { 3226*8c35d5eeSXin Li ... 3227*8c35d5eeSXin Li }; 3228*8c35d5eeSXin Li </CODE_SNIPPET> 3229*8c35d5eeSXin Li </td> 3230*8c35d5eeSXin Li <td> 3231*8c35d5eeSXin Li This annotation can be used to declare a 3232*8c35d5eeSXin Li <a href="#Template_types">template typename</a>. 3233*8c35d5eeSXin Li </td> 3234*8c35d5eeSXin Li </tr> 3235*8c35d5eeSXin Li 3236*8c35d5eeSXin Li <tr> 3237*8c35d5eeSXin Li <td><a name="tag-this">@this</a></td> 3238*8c35d5eeSXin Li <td> 3239*8c35d5eeSXin Li <code> 3240*8c35d5eeSXin Li @this Type<br/> 3241*8c35d5eeSXin Li @this {Type} 3242*8c35d5eeSXin Li </code> 3243*8c35d5eeSXin Li <p><i>For example:</i></p> 3244*8c35d5eeSXin Li <CODE_SNIPPET> 3245*8c35d5eeSXin Li pinto.chat.RosterWidget.extern('getRosterElement', 3246*8c35d5eeSXin Li /** 3247*8c35d5eeSXin Li * Returns the roster widget element. 3248*8c35d5eeSXin Li * @this pinto.chat.RosterWidget 3249*8c35d5eeSXin Li * @return {Element} 3250*8c35d5eeSXin Li */ 3251*8c35d5eeSXin Li function() { 3252*8c35d5eeSXin Li return this.getWrappedComponent_().getElement(); 3253*8c35d5eeSXin Li }); 3254*8c35d5eeSXin Li </CODE_SNIPPET> 3255*8c35d5eeSXin Li </td> 3256*8c35d5eeSXin Li <td> 3257*8c35d5eeSXin Li The type of the object in whose context a particular method is 3258*8c35d5eeSXin Li called. Required when the <code>this</code> keyword is referenced 3259*8c35d5eeSXin Li from a function that is not a prototype method. 3260*8c35d5eeSXin Li </td> 3261*8c35d5eeSXin Li </tr> 3262*8c35d5eeSXin Li 3263*8c35d5eeSXin Li <tr> 3264*8c35d5eeSXin Li <td><a name="tag-type">@type</a></td> 3265*8c35d5eeSXin Li <td> 3266*8c35d5eeSXin Li <code> 3267*8c35d5eeSXin Li @type Type<br/> 3268*8c35d5eeSXin Li @type {Type} 3269*8c35d5eeSXin Li </code> 3270*8c35d5eeSXin Li <p><i>For example:</i></p> 3271*8c35d5eeSXin Li <CODE_SNIPPET> 3272*8c35d5eeSXin Li /** 3273*8c35d5eeSXin Li * The message hex ID. 3274*8c35d5eeSXin Li * @type {string} 3275*8c35d5eeSXin Li */ 3276*8c35d5eeSXin Li var hexId = hexId; 3277*8c35d5eeSXin Li </CODE_SNIPPET> 3278*8c35d5eeSXin Li </td> 3279*8c35d5eeSXin Li <td> 3280*8c35d5eeSXin Li Identifies the <a href="#JsTypes">type</a> of a variable, 3281*8c35d5eeSXin Li property, or expression. Curly braces are not required around 3282*8c35d5eeSXin Li most types, but some projects mandate them for all types, for 3283*8c35d5eeSXin Li consistency. 3284*8c35d5eeSXin Li </td> 3285*8c35d5eeSXin Li </tr> 3286*8c35d5eeSXin Li 3287*8c35d5eeSXin Li <tr> 3288*8c35d5eeSXin Li <td><a name="tag-typedef">@typedef</a></td> 3289*8c35d5eeSXin Li <td> 3290*8c35d5eeSXin Li <code>@typedef</code> 3291*8c35d5eeSXin Li <p><i>For example:</i></p> 3292*8c35d5eeSXin Li <CODE_SNIPPET> 3293*8c35d5eeSXin Li /** @typedef {(string|number)} */ 3294*8c35d5eeSXin Li goog.NumberLike; 3295*8c35d5eeSXin Li 3296*8c35d5eeSXin Li /** @param {goog.NumberLike} x A number or a string. */ 3297*8c35d5eeSXin Li goog.readNumber = function(x) { 3298*8c35d5eeSXin Li ... 3299*8c35d5eeSXin Li } 3300*8c35d5eeSXin Li </CODE_SNIPPET> 3301*8c35d5eeSXin Li </td> 3302*8c35d5eeSXin Li <td> 3303*8c35d5eeSXin Li This annotation can be used to declare an alias of a more 3304*8c35d5eeSXin Li <a href="#Typedefs">complex type</a>. 3305*8c35d5eeSXin Li </td> 3306*8c35d5eeSXin Li </tr> 3307*8c35d5eeSXin Li 3308*8c35d5eeSXin Li 3309*8c35d5eeSXin Li 3310*8c35d5eeSXin Li </tbody> 3311*8c35d5eeSXin Li </table> 3312*8c35d5eeSXin Li 3313*8c35d5eeSXin Li 3314*8c35d5eeSXin Li 3315*8c35d5eeSXin Li <p> 3316*8c35d5eeSXin Li You may also see other types of JSDoc annotations in third-party 3317*8c35d5eeSXin Li code. These annotations appear in the 3318*8c35d5eeSXin Li <a href="https://code.google.com/p/jsdoc-toolkit/wiki/TagReference"> 3319*8c35d5eeSXin Li JSDoc Toolkit Tag Reference 3320*8c35d5eeSXin Li </a> 3321*8c35d5eeSXin Li but are currently discouraged in Google code. You should consider 3322*8c35d5eeSXin Li them "reserved" names for future use. These include: 3323*8c35d5eeSXin Li <ul> 3324*8c35d5eeSXin Li <li>@augments</li> 3325*8c35d5eeSXin Li <li>@argument</li> 3326*8c35d5eeSXin Li <li>@borrows</li> 3327*8c35d5eeSXin Li <li>@class</li> 3328*8c35d5eeSXin Li <li>@constant</li> 3329*8c35d5eeSXin Li <li>@constructs</li> 3330*8c35d5eeSXin Li <li>@default</li> 3331*8c35d5eeSXin Li <li>@event</li> 3332*8c35d5eeSXin Li <li>@example</li> 3333*8c35d5eeSXin Li <li>@field</li> 3334*8c35d5eeSXin Li <li>@function</li> 3335*8c35d5eeSXin Li <li>@ignore</li> 3336*8c35d5eeSXin Li <li>@inner</li> 3337*8c35d5eeSXin Li <li>@link</li> 3338*8c35d5eeSXin Li <li>@memberOf</li> 3339*8c35d5eeSXin Li <li>@name</li> 3340*8c35d5eeSXin Li <li>@namespace</li> 3341*8c35d5eeSXin Li <li>@property</li> 3342*8c35d5eeSXin Li <li>@public</li> 3343*8c35d5eeSXin Li <li>@requires</li> 3344*8c35d5eeSXin Li <li>@returns</li> 3345*8c35d5eeSXin Li <li>@since</li> 3346*8c35d5eeSXin Li <li>@static</li> 3347*8c35d5eeSXin Li <li>@version</li> 3348*8c35d5eeSXin Li </ul> 3349*8c35d5eeSXin Li </p> 3350*8c35d5eeSXin Li </SUBSECTION> 3351*8c35d5eeSXin Li </BODY> 3352*8c35d5eeSXin Li </STYLEPOINT> 3353*8c35d5eeSXin Li 3354*8c35d5eeSXin Li <STYLEPOINT title="Providing Dependencies With goog.provide"> 3355*8c35d5eeSXin Li <SUMMARY> 3356*8c35d5eeSXin Li Only provide top-level symbols. 3357*8c35d5eeSXin Li </SUMMARY> 3358*8c35d5eeSXin Li <BODY> 3359*8c35d5eeSXin Li <p> 3360*8c35d5eeSXin Li All members defined on a class should be in the same file. So, only 3361*8c35d5eeSXin Li top-level classes should be provided in a file that contains multiple 3362*8c35d5eeSXin Li members defined on the same class (e.g. enums, inner classes, etc). 3363*8c35d5eeSXin Li </p> 3364*8c35d5eeSXin Li <p>Do this:</p> 3365*8c35d5eeSXin Li <CODE_SNIPPET> 3366*8c35d5eeSXin Li goog.provide('namespace.MyClass'); 3367*8c35d5eeSXin Li </CODE_SNIPPET> 3368*8c35d5eeSXin Li <p>Not this:</p> 3369*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 3370*8c35d5eeSXin Li goog.provide('namespace.MyClass'); 3371*8c35d5eeSXin Li goog.provide('namespace.MyClass.Enum'); 3372*8c35d5eeSXin Li goog.provide('namespace.MyClass.InnerClass'); 3373*8c35d5eeSXin Li goog.provide('namespace.MyClass.TypeDef'); 3374*8c35d5eeSXin Li goog.provide('namespace.MyClass.CONSTANT'); 3375*8c35d5eeSXin Li goog.provide('namespace.MyClass.staticMethod'); 3376*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 3377*8c35d5eeSXin Li <p> 3378*8c35d5eeSXin Li Members on namespaces may also be provided: 3379*8c35d5eeSXin Li </p> 3380*8c35d5eeSXin Li <CODE_SNIPPET> 3381*8c35d5eeSXin Li goog.provide('foo.bar'); 3382*8c35d5eeSXin Li goog.provide('foo.bar.method'); 3383*8c35d5eeSXin Li goog.provide('foo.bar.CONSTANT'); 3384*8c35d5eeSXin Li </CODE_SNIPPET> 3385*8c35d5eeSXin Li </BODY> 3386*8c35d5eeSXin Li </STYLEPOINT> 3387*8c35d5eeSXin Li 3388*8c35d5eeSXin Li <STYLEPOINT title="Compiling"> 3389*8c35d5eeSXin Li <SUMMARY>Required</SUMMARY> 3390*8c35d5eeSXin Li <BODY> 3391*8c35d5eeSXin Li 3392*8c35d5eeSXin Li 3393*8c35d5eeSXin Li <p>Use of JS compilers such as the 3394*8c35d5eeSXin Li <a href="https://code.google.com/closure/compiler/">Closure Compiler</a> 3395*8c35d5eeSXin Li is required for all customer-facing code.</p> 3396*8c35d5eeSXin Li 3397*8c35d5eeSXin Li 3398*8c35d5eeSXin Li 3399*8c35d5eeSXin Li 3400*8c35d5eeSXin Li </BODY> 3401*8c35d5eeSXin Li </STYLEPOINT> 3402*8c35d5eeSXin Li 3403*8c35d5eeSXin Li <STYLEPOINT title="Tips and Tricks"> 3404*8c35d5eeSXin Li <SUMMARY>JavaScript tidbits</SUMMARY> 3405*8c35d5eeSXin Li <BODY> 3406*8c35d5eeSXin Li <SUBSECTION title="True and False Boolean Expressions"> 3407*8c35d5eeSXin Li <p>The following are all false in boolean expressions:</p> 3408*8c35d5eeSXin Li <ul> 3409*8c35d5eeSXin Li <li><code>null</code></li> 3410*8c35d5eeSXin Li <li><code>undefined</code></li> 3411*8c35d5eeSXin Li <li><code>''</code> the empty string</li> 3412*8c35d5eeSXin Li <li><code>0</code> the number</li> 3413*8c35d5eeSXin Li </ul> 3414*8c35d5eeSXin Li <p>But be careful, because these are all true:</p> 3415*8c35d5eeSXin Li <ul> 3416*8c35d5eeSXin Li <li><code>'0'</code> the string</li> 3417*8c35d5eeSXin Li <li><code>[]</code> the empty array</li> 3418*8c35d5eeSXin Li <li><code>{}</code> the empty object</li> 3419*8c35d5eeSXin Li </ul> 3420*8c35d5eeSXin Li 3421*8c35d5eeSXin Li <p>This means that instead of this:</p> 3422*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 3423*8c35d5eeSXin Li while (x != null) { 3424*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 3425*8c35d5eeSXin Li <p>you can write this shorter code (as long as you don't expect x to 3426*8c35d5eeSXin Li be 0, or the empty string, or false):</p> 3427*8c35d5eeSXin Li <CODE_SNIPPET> 3428*8c35d5eeSXin Li while (x) { 3429*8c35d5eeSXin Li </CODE_SNIPPET> 3430*8c35d5eeSXin Li 3431*8c35d5eeSXin Li <p>And if you want to check a string to see if it is null or empty, 3432*8c35d5eeSXin Li you could do this:</p> 3433*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 3434*8c35d5eeSXin Li if (y != null && y != '') { 3435*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 3436*8c35d5eeSXin Li <p>But this is shorter and nicer:</p> 3437*8c35d5eeSXin Li <CODE_SNIPPET> 3438*8c35d5eeSXin Li if (y) { 3439*8c35d5eeSXin Li </CODE_SNIPPET> 3440*8c35d5eeSXin Li 3441*8c35d5eeSXin Li <p><strong>Caution:</strong> There are many unintuitive things about 3442*8c35d5eeSXin Li boolean expressions. Here are some of them:</p> 3443*8c35d5eeSXin Li <ul> 3444*8c35d5eeSXin Li <li><code> 3445*8c35d5eeSXin Li Boolean('0') == true<br/> 3446*8c35d5eeSXin Li '0' != true</code></li> 3447*8c35d5eeSXin Li <li><code> 3448*8c35d5eeSXin Li 0 != null<br/> 3449*8c35d5eeSXin Li 0 == []<br/> 3450*8c35d5eeSXin Li 0 == false</code></li> 3451*8c35d5eeSXin Li <li><code> 3452*8c35d5eeSXin Li Boolean(null) == false<br/> 3453*8c35d5eeSXin Li null != true<br/> 3454*8c35d5eeSXin Li null != false</code></li> 3455*8c35d5eeSXin Li <li><code> 3456*8c35d5eeSXin Li Boolean(undefined) == false<br/> 3457*8c35d5eeSXin Li undefined != true<br/> 3458*8c35d5eeSXin Li undefined != false</code></li> 3459*8c35d5eeSXin Li <li><code> 3460*8c35d5eeSXin Li Boolean([]) == true<br/> 3461*8c35d5eeSXin Li [] != true<br/> 3462*8c35d5eeSXin Li [] == false</code></li> 3463*8c35d5eeSXin Li <li><code> 3464*8c35d5eeSXin Li Boolean({}) == true<br/> 3465*8c35d5eeSXin Li {} != true<br/> 3466*8c35d5eeSXin Li {} != false</code></li> 3467*8c35d5eeSXin Li </ul> 3468*8c35d5eeSXin Li </SUBSECTION> 3469*8c35d5eeSXin Li 3470*8c35d5eeSXin Li <SUBSECTION title="Conditional (Ternary) Operator (?:)"> 3471*8c35d5eeSXin Li <p>Instead of this:</p> 3472*8c35d5eeSXin Li <CODE_SNIPPET> 3473*8c35d5eeSXin Li if (val) { 3474*8c35d5eeSXin Li return foo(); 3475*8c35d5eeSXin Li } else { 3476*8c35d5eeSXin Li return bar(); 3477*8c35d5eeSXin Li } 3478*8c35d5eeSXin Li </CODE_SNIPPET> 3479*8c35d5eeSXin Li <p>you can write this:</p> 3480*8c35d5eeSXin Li <CODE_SNIPPET> 3481*8c35d5eeSXin Li return val ? foo() : bar(); 3482*8c35d5eeSXin Li </CODE_SNIPPET> 3483*8c35d5eeSXin Li 3484*8c35d5eeSXin Li <p>The ternary conditional is also useful when generating HTML:</p> 3485*8c35d5eeSXin Li <CODE_SNIPPET> 3486*8c35d5eeSXin Li var html = '<input type="checkbox"' + 3487*8c35d5eeSXin Li (isChecked ? ' checked' : '') + 3488*8c35d5eeSXin Li (isEnabled ? '' : ' disabled') + 3489*8c35d5eeSXin Li ' name="foo">'; 3490*8c35d5eeSXin Li </CODE_SNIPPET> 3491*8c35d5eeSXin Li </SUBSECTION> 3492*8c35d5eeSXin Li 3493*8c35d5eeSXin Li <SUBSECTION title="&& and ||"> 3494*8c35d5eeSXin Li <p>These binary boolean operators are short-circuited, and evaluate 3495*8c35d5eeSXin Li to the last evaluated term.</p> 3496*8c35d5eeSXin Li 3497*8c35d5eeSXin Li <p>"||" has been called the 'default' operator, because instead of 3498*8c35d5eeSXin Li writing this:</p> 3499*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 3500*8c35d5eeSXin Li /** @param {*=} opt_win */ 3501*8c35d5eeSXin Li function foo(opt_win) { 3502*8c35d5eeSXin Li var win; 3503*8c35d5eeSXin Li if (opt_win) { 3504*8c35d5eeSXin Li win = opt_win; 3505*8c35d5eeSXin Li } else { 3506*8c35d5eeSXin Li win = window; 3507*8c35d5eeSXin Li } 3508*8c35d5eeSXin Li // ... 3509*8c35d5eeSXin Li } 3510*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 3511*8c35d5eeSXin Li <p>you can write this:</p> 3512*8c35d5eeSXin Li <CODE_SNIPPET> 3513*8c35d5eeSXin Li /** @param {*=} opt_win */ 3514*8c35d5eeSXin Li function foo(opt_win) { 3515*8c35d5eeSXin Li var win = opt_win || window; 3516*8c35d5eeSXin Li // ... 3517*8c35d5eeSXin Li } 3518*8c35d5eeSXin Li </CODE_SNIPPET> 3519*8c35d5eeSXin Li 3520*8c35d5eeSXin Li <p>"&&" is also useful for shortening code. For instance, 3521*8c35d5eeSXin Li instead of this:</p> 3522*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 3523*8c35d5eeSXin Li if (node) { 3524*8c35d5eeSXin Li if (node.kids) { 3525*8c35d5eeSXin Li if (node.kids[index]) { 3526*8c35d5eeSXin Li foo(node.kids[index]); 3527*8c35d5eeSXin Li } 3528*8c35d5eeSXin Li } 3529*8c35d5eeSXin Li } 3530*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 3531*8c35d5eeSXin Li 3532*8c35d5eeSXin Li <p>you could do this:</p> 3533*8c35d5eeSXin Li <CODE_SNIPPET> 3534*8c35d5eeSXin Li if (node && node.kids && node.kids[index]) { 3535*8c35d5eeSXin Li foo(node.kids[index]); 3536*8c35d5eeSXin Li } 3537*8c35d5eeSXin Li </CODE_SNIPPET> 3538*8c35d5eeSXin Li 3539*8c35d5eeSXin Li <p>or this:</p> 3540*8c35d5eeSXin Li <CODE_SNIPPET> 3541*8c35d5eeSXin Li var kid = node && node.kids && node.kids[index]; 3542*8c35d5eeSXin Li if (kid) { 3543*8c35d5eeSXin Li foo(kid); 3544*8c35d5eeSXin Li } 3545*8c35d5eeSXin Li </CODE_SNIPPET> 3546*8c35d5eeSXin Li 3547*8c35d5eeSXin Li <p>However, this is going a little too far:</p> 3548*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 3549*8c35d5eeSXin Li node && node.kids && node.kids[index] && foo(node.kids[index]); 3550*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 3551*8c35d5eeSXin Li </SUBSECTION> 3552*8c35d5eeSXin Li 3553*8c35d5eeSXin Li <SUBSECTION title="Iterating over Node Lists"> 3554*8c35d5eeSXin Li <p>Node lists are often implemented as node iterators with a filter. 3555*8c35d5eeSXin Li This means that getting a property like length is O(n), and 3556*8c35d5eeSXin Li iterating over the list by re-checking the length will be 3557*8c35d5eeSXin Li O(n^2).</p> 3558*8c35d5eeSXin Li <BAD_CODE_SNIPPET> 3559*8c35d5eeSXin Li var paragraphs = document.getElementsByTagName('p'); 3560*8c35d5eeSXin Li for (var i = 0; i < paragraphs.length; i++) { 3561*8c35d5eeSXin Li doSomething(paragraphs[i]); 3562*8c35d5eeSXin Li } 3563*8c35d5eeSXin Li </BAD_CODE_SNIPPET> 3564*8c35d5eeSXin Li 3565*8c35d5eeSXin Li <p>It is better to do this instead:</p> 3566*8c35d5eeSXin Li <CODE_SNIPPET> 3567*8c35d5eeSXin Li var paragraphs = document.getElementsByTagName('p'); 3568*8c35d5eeSXin Li for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) { 3569*8c35d5eeSXin Li doSomething(paragraph); 3570*8c35d5eeSXin Li } 3571*8c35d5eeSXin Li </CODE_SNIPPET> 3572*8c35d5eeSXin Li 3573*8c35d5eeSXin Li <p>This works well for all collections and arrays as long as the array 3574*8c35d5eeSXin Li does not contain things that are treated as boolean false.</p> 3575*8c35d5eeSXin Li 3576*8c35d5eeSXin Li <p>In cases where you are iterating over the childNodes you can also 3577*8c35d5eeSXin Li use the firstChild and nextSibling properties.</p> 3578*8c35d5eeSXin Li <CODE_SNIPPET> 3579*8c35d5eeSXin Li var parentNode = document.getElementById('foo'); 3580*8c35d5eeSXin Li for (var child = parentNode.firstChild; child; child = child.nextSibling) { 3581*8c35d5eeSXin Li doSomething(child); 3582*8c35d5eeSXin Li } 3583*8c35d5eeSXin Li </CODE_SNIPPET> 3584*8c35d5eeSXin Li </SUBSECTION> 3585*8c35d5eeSXin Li </BODY> 3586*8c35d5eeSXin Li </STYLEPOINT> 3587*8c35d5eeSXin Li </CATEGORY> 3588*8c35d5eeSXin Li 3589*8c35d5eeSXin Li 3590*8c35d5eeSXin Li 3591*8c35d5eeSXin Li <PARTING_WORDS> 3592*8c35d5eeSXin Li <p> 3593*8c35d5eeSXin Li <em>BE CONSISTENT</em>. 3594*8c35d5eeSXin Li </p> 3595*8c35d5eeSXin Li 3596*8c35d5eeSXin Li <p> 3597*8c35d5eeSXin Li If you're editing code, take a few minutes to look at the code 3598*8c35d5eeSXin Li around you and determine its style. If they use spaces around 3599*8c35d5eeSXin Li all their arithmetic operators, you should too. If their 3600*8c35d5eeSXin Li comments have little boxes of hash marks around them, make your 3601*8c35d5eeSXin Li comments have little boxes of hash marks around them too. 3602*8c35d5eeSXin Li </p> 3603*8c35d5eeSXin Li 3604*8c35d5eeSXin Li <p> 3605*8c35d5eeSXin Li The point of having style guidelines is to have a common vocabulary 3606*8c35d5eeSXin Li of coding so people can concentrate on what you're saying rather 3607*8c35d5eeSXin Li than on how you're saying it. We present global style rules here so 3608*8c35d5eeSXin Li people know the vocabulary, but local style is also important. If 3609*8c35d5eeSXin Li code you add to a file looks drastically different from the existing 3610*8c35d5eeSXin Li code around it, it throws readers out of their rhythm when they go to 3611*8c35d5eeSXin Li read it. Avoid this. 3612*8c35d5eeSXin Li </p> 3613*8c35d5eeSXin Li 3614*8c35d5eeSXin Li </PARTING_WORDS> 3615*8c35d5eeSXin Li 3616*8c35d5eeSXin Li <p align="right"> 3617*8c35d5eeSXin Li Revision 2.93 3618*8c35d5eeSXin Li </p> 3619*8c35d5eeSXin Li 3620*8c35d5eeSXin Li 3621*8c35d5eeSXin Li <address> 3622*8c35d5eeSXin Li Aaron Whyte<br/> 3623*8c35d5eeSXin Li Bob Jervis<br/> 3624*8c35d5eeSXin Li Dan Pupius<br/> 3625*8c35d5eeSXin Li Erik Arvidsson<br/> 3626*8c35d5eeSXin Li Fritz Schneider<br/> 3627*8c35d5eeSXin Li Robby Walker<br/> 3628*8c35d5eeSXin Li </address> 3629*8c35d5eeSXin Li</GUIDE> 3630