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