| <?xml version = '1.0'?> |
| <?xml-stylesheet type="text/xsl" href="styleguide.xsl"?> |
| <GUIDE title="Google JavaScript Style Guide"> |
| <p class="revision"> |
| |
| Revision 2.93 |
| </p> |
| |
| <address> |
| Aaron Whyte<br/> |
| Bob Jervis<br/> |
| Dan Pupius<br/> |
| Erik Arvidsson<br/> |
| Fritz Schneider<br/> |
| Robby Walker<br/> |
| </address> |
| <OVERVIEW> |
| <CATEGORY title="Important Note"> |
| <STYLEPOINT title="Displaying Hidden Details in this Guide"> |
| <SUMMARY> |
| This style guide contains many details that are initially |
| hidden from view. They are marked by the triangle icon, which you |
| see here on your left. Click it now. |
| You should see "Hooray" appear below. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Hooray! Now you know you can expand points to get more |
| details. Alternatively, there's a "toggle all" at the |
| top of this document. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| <CATEGORY title="Background"> |
| <p> |
| JavaScript is the main client-side scripting language used |
| |
| by many of Google's open-source |
| projects. |
| This style guide is a list of <em>do</em>s and <em>don't</em>s for |
| JavaScript programs. |
| </p> |
| |
| |
| |
| |
| |
| </CATEGORY> |
| </OVERVIEW> |
| <CATEGORY title="JavaScript Language Rules"> |
| |
| |
| |
| |
| <STYLEPOINT title="var"> |
| <SUMMARY> |
| Declarations with <code>var</code>: Always |
| </SUMMARY> |
| <BODY> |
| <DECISION> |
| When you fail to specify <code>var</code>, |
| the variable gets placed in the global context, potentially clobbering |
| existing values. Also, if there's no declaration, it's hard to tell in |
| what scope a variable lives (e.g., it could be in the Document or |
| Window just as easily as in the local scope). So always declare with |
| <code>var</code>. |
| </DECISION> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Constants"> |
| <SUMMARY> |
| <ul> |
| <li>Use <code>NAMES_LIKE_THIS</code> for constant <em>values</em>.</li> |
| <li>Use <code>@const</code> to indicate a constant (non-overwritable) |
| <em>pointer</em> (a variable or property).</li> |
| <li>Never use the |
| <a href="https://developer.mozilla.org/en/JavaScript/Reference/Statements/const"> |
| <code>const</code> keyword</a> |
| as it's not supported in Internet Explorer.</li> |
| </ul> |
| </SUMMARY> |
| <BODY> |
| <DECISION> |
| <SUBSECTION title="Constant values"> |
| |
| <p>If a value is intended to be <em>constant</em> |
| and <em>immutable</em>, it should be given a name |
| in <code>CONSTANT_VALUE_CASE</code>. |
| <code>ALL_CAPS</code> additionally implies <code>@const</code> |
| (that the value is not overwritable). |
| </p> |
| |
| <p>Primitive types (<code>number</code>, <code>string</code>, |
| <code>boolean</code>) are constant values.</p> |
| |
| <p><code>Objects</code>' |
| immutability is more subjective — objects should be |
| considered immutable only if they do not demonstrate observable |
| state change. This is not enforced by the compiler.</p> |
| |
| |
| </SUBSECTION> |
| |
| <SUBSECTION title="Constant pointers (variables and properties)"> |
| <p>The <code>@const</code> annotation on a variable or property |
| implies that it is not overwritable. This is enforced by the |
| compiler at build time. This behavior is consistent with the |
| <a href="https://developer.mozilla.org/en/JavaScript/Reference/Statements/const"> |
| <code>const</code> keyword</a> (which we do not use due to the |
| lack of support in Internet Explorer).</p> |
| |
| <p>A <code>@const</code> annotation on a method additionally |
| implies that the method cannot not be overridden in subclasses. |
| </p> |
| |
| <p>A <code>@const</code> annotation on a constructor implies the |
| class cannot be subclassed (akin to <code>final</code> in Java). |
| </p> |
| |
| </SUBSECTION> |
| |
| <SUBSECTION title="Examples"> |
| |
| <p>Note that <code>@const</code> does not necessarily imply |
| <code>CONSTANT_VALUES_CASE</code>. |
| |
| However, <code>CONSTANT_VALUES_CASE</code> |
| <em>does</em> imply <code>@const</code>. |
| </p> |
| |
| <CODE_SNIPPET> |
| /** |
| * Request timeout in milliseconds. |
| * @type {number} |
| */ |
| goog.example.TIMEOUT_IN_MILLISECONDS = 60; |
| </CODE_SNIPPET> |
| |
| <p>The number of seconds in a minute never changes. It is a |
| constant value. <code>ALL_CAPS</code> |
| also implies <code>@const</code>, so the constant cannot be |
| overwritten. |
| </p> |
| |
| <p>The open source compiler will allow the symbol to be |
| overwritten because the constant is |
| <em>not</em> marked as <code>@const</code>.</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * Map of URL to response string. |
| * @const |
| */ |
| MyClass.fetchedUrlCache_ = new goog.structs.Map(); |
| </CODE_SNIPPET> |
| |
| <CODE_SNIPPET> |
| /** |
| * Class that cannot be subclassed. |
| * @const |
| * @constructor |
| */ |
| sloth.MyFinalClass = function() {}; |
| </CODE_SNIPPET> |
| |
| <p>In this case, the pointer can never be overwritten, but |
| value is highly mutable and <b>not</b> constant (and thus in |
| <code>camelCase</code>, not <code>ALL_CAPS</code>).</p> |
| </SUBSECTION> |
| |
| </DECISION> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Semicolons"> |
| <SUMMARY> |
| Always use semicolons. |
| </SUMMARY> |
| <BODY> |
| <p>Relying on implicit insertion can cause subtle, hard to debug |
| problems. Don't do it. You're better than that.</p> |
| <p>There are a couple places where missing semicolons are particularly |
| dangerous:</p> |
| <BAD_CODE_SNIPPET> |
| // 1. |
| MyClass.prototype.myMethod = function() { |
| return 42; |
| } // No semicolon here. |
| |
| (function() { |
| // Some initialization code wrapped in a function to create a scope for locals. |
| })(); |
| |
| |
| var x = { |
| 'i': 1, |
| 'j': 2 |
| } // No semicolon here. |
| |
| // 2. Trying to do one thing on Internet Explorer and another on Firefox. |
| // I know you'd never write code like this, but throw me a bone. |
| [ffVersion, ieVersion][isIE](); |
| |
| |
| var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] // No semicolon here. |
| |
| // 3. conditional execution a la bash |
| -1 == resultOfOperation() || die(); |
| </BAD_CODE_SNIPPET> |
| <SUBSECTION title="So what happens?"> |
| <ol> |
| <li>JavaScript error - first the function returning 42 is called |
| with the second function as a parameter, then the number 42 is |
| "called" resulting in an error.</li> |
| <li>You will most likely get a 'no such property in undefined' |
| error at runtime as it tries to call |
| <code>x[ffVersion, ieVersion][isIE]()</code>.</li> |
| <li><code>die</code> is always called since the array minus 1 is |
| <code>NaN</code> which is never equal to anything (not even if |
| <code>resultOfOperation()</code> returns <code>NaN</code>) and |
| <code>THINGS_TO_EAT</code> gets assigned the result of |
| <code>die()</code>.</li> |
| </ol> |
| </SUBSECTION> |
| <SUBSECTION title="Why?"> |
| <p>JavaScript requires statements to end with a semicolon, except when |
| it thinks it can safely infer their existence. In each of these |
| examples, a function declaration or object or array literal is used |
| inside a statement. The closing brackets are not enough to signal |
| the end of the statement. Javascript never ends a statement if the |
| next token is an infix or bracket operator.</p> |
| <p>This has really surprised people, so make sure your assignments end |
| with semicolons.</p> |
| </SUBSECTION> |
| <SUBSECTION title="Clarification: Semicolons and functions"> |
| <p>Semicolons should be included at the end of function expressions, |
| but not at the end of function declarations. The distinction is |
| best illustrated with an example:</p> |
| <CODE_SNIPPET> |
| var foo = function() { |
| return true; |
| }; // semicolon here. |
| |
| function foo() { |
| return true; |
| } // no semicolon here. |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Nested functions"> |
| <SUMMARY>Yes</SUMMARY> |
| <BODY> |
| <p>Nested functions can be very useful, for example in the creation of |
| continuations and for the task of hiding helper functions. Feel free |
| to use them.</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Function Declarations Within Blocks"> |
| <SUMMARY>No</SUMMARY> |
| <BODY> |
| <p>Do not do this:</p> |
| <BAD_CODE_SNIPPET> |
| if (x) { |
| function foo() {} |
| } |
| </BAD_CODE_SNIPPET> |
| |
| <p>While most script engines support Function Declarations within blocks |
| it is not part of ECMAScript (see |
| <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMA-262</a>, |
| clause 13 and 14). Worse implementations are inconsistent with each |
| other and with future EcmaScript proposals. ECMAScript only allows for |
| Function Declarations in the root statement list of a script or |
| function. Instead use a variable initialized with a Function |
| Expression to define a function within a block:</p> |
| <CODE_SNIPPET> |
| if (x) { |
| var foo = function() {}; |
| } |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Exceptions"> |
| <SUMMARY>Yes</SUMMARY> |
| <BODY> |
| <p>You basically can't avoid exceptions if you're doing something |
| non-trivial (using an application development framework, etc.). |
| Go for it.</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Custom exceptions"> |
| <SUMMARY>Yes</SUMMARY> |
| <BODY> |
| <p>Without custom exceptions, returning error information from a |
| function that also returns a value can be tricky, not to mention |
| inelegant. Bad solutions include passing in a reference type to hold |
| error information or always returning Objects with a potential |
| error member. These basically amount to a primitive exception |
| handling hack. Feel free to use custom exceptions when |
| appropriate.</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Standards features"> |
| <SUMMARY>Always preferred over non-standards features</SUMMARY> |
| <BODY> |
| <p>For maximum portability and compatibility, always prefer standards |
| features over non-standards features (e.g., |
| <code>string.charAt(3)</code> over <code>string[3]</code> and element |
| access with DOM functions instead of using an application-specific |
| shorthand).</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Wrapper objects for primitive types"> |
| <SUMMARY>No</SUMMARY> |
| <BODY> |
| <p>There's no reason to use wrapper objects for primitive types, plus |
| they're dangerous:</p> |
| <BAD_CODE_SNIPPET> |
| var x = new Boolean(false); |
| if (x) { |
| alert('hi'); // Shows 'hi'. |
| } |
| </BAD_CODE_SNIPPET> |
| <p>Don't do it!</p> |
| <p>However type casting is fine.</p> |
| <CODE_SNIPPET> |
| var x = Boolean(0); |
| if (x) { |
| alert('hi'); // This will never be alerted. |
| } |
| typeof Boolean(0) == 'boolean'; |
| typeof new Boolean(0) == 'object'; |
| </CODE_SNIPPET> |
| <p>This is very useful for casting things to |
| <code>number</code>, <code>string</code> and <code>boolean</code>.</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Multi-level prototype hierarchies"> |
| <SUMMARY>Not preferred</SUMMARY> |
| <BODY> |
| <p>Multi-level prototype hierarchies are how JavaScript implements |
| inheritance. You have a multi-level hierarchy if you have a |
| user-defined class D with another user-defined class B as its |
| prototype. These hierarchies are much harder to get right than they |
| first appear! </p> |
| |
| <p>For that reason, it is best to use <code>goog.inherits()</code> from |
| <a href="http://code.google.com/closure/library/"> |
| the Closure Library |
| </a> |
| or a similar library function. |
| </p> |
| <CODE_SNIPPET> |
| function D() { |
| goog.base(this) |
| } |
| goog.inherits(D, B); |
| |
| D.prototype.method = function() { |
| ... |
| }; |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Method and property definitions"> |
| <SUMMARY><code>/** @constructor */ |
| function SomeConstructor() { |
| this.someProperty = 1; |
| } |
| Foo.prototype.someMethod = function() { ... };</code></SUMMARY> |
| <BODY> |
| <p>While there are several ways to attach methods and properties to an |
| object created via "new", the preferred style for methods |
| is:</p> |
| <CODE_SNIPPET> |
| Foo.prototype.bar = function() { |
| /* ... */ |
| }; |
| </CODE_SNIPPET> |
| <p>The preferred style for other properties is to initialize the field |
| in the constructor:</p> |
| <CODE_SNIPPET> |
| /** @constructor */ |
| function Foo() { |
| this.bar = value; |
| } |
| </CODE_SNIPPET> |
| <SUBSECTION title="Why?"> |
| <p>Current JavaScript engines optimize based on the "shape" |
| of an object, <a href="https://developers.google.com/v8/design#prop_access"> |
| adding a property to an object (including overriding |
| a value set on the prototype) changes the shape and can degrade |
| performance.</a></p> |
| </SUBSECTION> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="delete"> |
| <SUMMARY>Prefer <code>this.foo = null</code>.</SUMMARY> |
| <BODY> |
| <CODE_SNIPPET> |
| Foo.prototype.dispose = function() { |
| this.property_ = null; |
| }; |
| </CODE_SNIPPET> |
| <p>Instead of:</p> |
| <BAD_CODE_SNIPPET> |
| Foo.prototype.dispose = function() { |
| delete this.property_; |
| }; |
| </BAD_CODE_SNIPPET> |
| <p>In modern JavaScript engines, changing the number of properties on an |
| object is much slower than reassigning the values. The delete keyword |
| should be avoided except when it is necessary to remove a property |
| from an object's iterated list of keys, or to change the result of |
| <code>if (key in obj)</code>.</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Closures"> |
| <SUMMARY>Yes, but be careful.</SUMMARY> |
| <BODY> |
| <p>The ability to create closures is perhaps the most useful and often |
| overlooked feature of JS. Here is |
| <a href="http://jibbering.com/faq/faq_notes/closures.html"> |
| a good description of how closures work</a>.</p> |
| <p>One thing to keep in mind, however, is that a closure keeps a pointer |
| to its enclosing scope. As a result, attaching a closure to a DOM |
| element can create a circular reference and thus, a memory leak. For |
| example, in the following code:</p> |
| <BAD_CODE_SNIPPET> |
| function foo(element, a, b) { |
| element.onclick = function() { /* uses a and b */ }; |
| } |
| </BAD_CODE_SNIPPET> |
| <p>the function closure keeps a reference to <code>element</code>, |
| <code>a</code>, and <code>b</code> even if it never uses |
| <code>element</code>. Since <code>element</code> also keeps a |
| reference to the closure, we have a cycle that won't be cleaned up by |
| garbage collection. In these situations, the code can be structured |
| as follows:</p> |
| <CODE_SNIPPET> |
| function foo(element, a, b) { |
| element.onclick = bar(a, b); |
| } |
| |
| function bar(a, b) { |
| return function() { /* uses a and b */ }; |
| } |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="eval()"> |
| <SUMMARY> |
| Only for code loaders and REPL (Read–eval–print loop) |
| </SUMMARY> |
| <BODY> |
| <p><code>eval()</code> makes for confusing semantics and is dangerous |
| to use if the string being <code>eval()</code>'d contains user input. |
| There's usually a better, clearer, and safer way to write your code, |
| so its use is generally not permitted.</p> |
| |
| <p>For RPC you can always use JSON and read the result using |
| <code>JSON.parse()</code> instead of <code>eval()</code>.</p> |
| |
| <p>Let's assume we have a server that returns something like this:</p> |
| |
| <CODE_SNIPPET> |
| { |
| "name": "Alice", |
| "id": 31502, |
| "email": "looking_glass@example.com" |
| } |
| </CODE_SNIPPET> |
| |
| <BAD_CODE_SNIPPET> |
| var userInfo = eval(feed); |
| var email = userInfo['email']; |
| </BAD_CODE_SNIPPET> |
| |
| <p>If the feed was modified to include malicious JavaScript code, then |
| if we use <code>eval</code> then that code will be executed.</p> |
| |
| <CODE_SNIPPET> |
| var userInfo = JSON.parse(feed); |
| var email = userInfo['email']; |
| </CODE_SNIPPET> |
| |
| <p>With <code>JSON.parse</code>, invalid JSON (including all executable |
| JavaScript) will cause an exception to be thrown.</p> |
| |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="with() {}"> |
| <SUMMARY>No</SUMMARY> |
| <BODY> |
| <p>Using <code>with</code> clouds the semantics of your program. |
| Because the object of the <code>with</code> can have properties that |
| collide with local variables, it can drastically change the meaning |
| of your program. For example, what does this do?</p> |
| <BAD_CODE_SNIPPET> |
| with (foo) { |
| var x = 3; |
| return x; |
| } |
| </BAD_CODE_SNIPPET> |
| <p>Answer: anything. The local variable <code>x</code> could be |
| clobbered by a property of <code>foo</code> and perhaps it even has |
| a setter, in which case assigning <code>3</code> could cause lots of |
| other code to execute. Don't use <code>with</code>.</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="this"> |
| <SUMMARY> |
| Only in object constructors, methods, and in setting up closures |
| </SUMMARY> |
| <BODY> |
| <p>The semantics of <code>this</code> can be tricky. At times it refers |
| to the global object (in most places), the scope of the caller (in |
| <code>eval</code>), a node in the DOM tree (when attached using an |
| event handler HTML attribute), a newly created object (in a |
| constructor), or some other object (if function was |
| <code>call()</code>ed or <code>apply()</code>ed).</p> |
| <p>Because this is so easy to get wrong, limit its use to those places |
| where it is required:</p> |
| <ul> |
| <li>in constructors</li> |
| <li>in methods of objects (including in the creation of closures)</li> |
| </ul> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="for-in loop"> |
| <SUMMARY> |
| Only for iterating over keys in an object/map/hash |
| </SUMMARY> |
| <BODY> |
| <p><code>for-in</code> loops are often incorrectly used to loop over |
| the elements in an <code>Array</code>. This is however very error |
| prone because it does not loop from <code>0</code> to |
| <code>length - 1</code> but over all the present keys in the object |
| and its prototype chain. Here are a few cases where it fails:</p> |
| <BAD_CODE_SNIPPET> |
| function printArray(arr) { |
| for (var key in arr) { |
| print(arr[key]); |
| } |
| } |
| |
| printArray([0,1,2,3]); // This works. |
| |
| var a = new Array(10); |
| printArray(a); // This is wrong. |
| |
| a = document.getElementsByTagName('*'); |
| printArray(a); // This is wrong. |
| |
| a = [0,1,2,3]; |
| a.buhu = 'wine'; |
| printArray(a); // This is wrong again. |
| |
| a = new Array; |
| a[3] = 3; |
| printArray(a); // This is wrong again. |
| </BAD_CODE_SNIPPET> |
| <p>Always use normal for loops when using arrays.</p> |
| <CODE_SNIPPET> |
| function printArray(arr) { |
| var l = arr.length; |
| for (var i = 0; i < l; i++) { |
| print(arr[i]); |
| } |
| } |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Associative Arrays"> |
| <SUMMARY> |
| Never use <code>Array</code> as a map/hash/associative array |
| </SUMMARY> |
| <BODY> |
| <p>Associative <code>Array</code>s are not allowed... or more precisely |
| you are not allowed to use non number indexes for arrays. If you need |
| a map/hash use <code>Object</code> instead of <code>Array</code> in |
| these cases because the features that you want are actually features |
| of <code>Object</code> and not of <code>Array</code>. |
| <code>Array</code> just happens to extend <code>Object</code> (like |
| any other object in JS and therefore you might as well have used |
| <code>Date</code>, <code>RegExp</code> or <code>String</code>).</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Multiline string literals"> |
| <SUMMARY>No</SUMMARY> |
| <BODY> |
| <p>Do not do this:</p> |
| <BAD_CODE_SNIPPET> |
| var myString = 'A rather long string of English text, an error message \ |
| actually that just keeps going and going -- an error \ |
| message to make the Energizer bunny blush (right through \ |
| those Schwarzenegger shades)! Where was I? Oh yes, \ |
| you\'ve got an error and all the extraneous whitespace is \ |
| just gravy. Have a nice day.'; |
| </BAD_CODE_SNIPPET> |
| <p>The whitespace at the beginning of each line can't be safely stripped |
| at compile time; whitespace after the slash will result in tricky |
| errors; and while most script engines support this, it is not part |
| of ECMAScript. </p> |
| <p>Use string concatenation instead:</p> |
| <CODE_SNIPPET> |
| var myString = 'A rather long string of English text, an error message ' + |
| 'actually that just keeps going and going -- an error ' + |
| 'message to make the Energizer bunny blush (right through ' + |
| 'those Schwarzenegger shades)! Where was I? Oh yes, ' + |
| 'you\'ve got an error and all the extraneous whitespace is ' + |
| 'just gravy. Have a nice day.'; |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Array and Object literals"> |
| <SUMMARY>Yes</SUMMARY> |
| <BODY> |
| <p>Use <code>Array</code> and <code>Object</code> literals instead of |
| <code>Array</code> and <code>Object</code> constructors.</p> |
| <p>Array constructors are error-prone due to their arguments.</p> |
| <BAD_CODE_SNIPPET> |
| // Length is 3. |
| var a1 = new Array(x1, x2, x3); |
| |
| // Length is 2. |
| var a2 = new Array(x1, x2); |
| |
| // If x1 is a number and it is a natural number the length will be x1. |
| // If x1 is a number but not a natural number this will throw an exception. |
| // Otherwise the array will have one element with x1 as its value. |
| var a3 = new Array(x1); |
| |
| // Length is 0. |
| var a4 = new Array(); |
| </BAD_CODE_SNIPPET> |
| <p>Because of this, if someone changes the code to pass 1 argument |
| instead of 2 arguments, the array might not have the expected |
| length.</p> |
| <p>To avoid these kinds of weird cases, always use the more readable |
| array literal.</p> |
| <CODE_SNIPPET> |
| var a = [x1, x2, x3]; |
| var a2 = [x1, x2]; |
| var a3 = [x1]; |
| var a4 = []; |
| </CODE_SNIPPET> |
| <p>Object constructors don't have the same problems, but for readability |
| and consistency object literals should be used.</p> |
| <BAD_CODE_SNIPPET> |
| var o = new Object(); |
| |
| var o2 = new Object(); |
| o2.a = 0; |
| o2.b = 1; |
| o2.c = 2; |
| o2['strange key'] = 3; |
| </BAD_CODE_SNIPPET> |
| <p>Should be written as:</p> |
| <CODE_SNIPPET> |
| var o = {}; |
| |
| var o2 = { |
| a: 0, |
| b: 1, |
| c: 2, |
| 'strange key': 3 |
| }; |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Modifying prototypes of builtin objects"> |
| <SUMMARY>No</SUMMARY> |
| <BODY> |
| <p>Modifying builtins like <code>Object.prototype</code> and |
| <code>Array.prototype</code> are strictly forbidden. Modifying other |
| builtins like <code>Function.prototype</code> is less dangerous but |
| still leads to hard to debug issues in production and should be |
| avoided.</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Internet Explorer's Conditional Comments"> |
| <SUMMARY>No</SUMMARY> |
| <BODY> |
| <p>Don't do this:</p> |
| <BAD_CODE_SNIPPET> |
| var f = function () { |
| /*@cc_on if (@_jscript) { return 2* @*/ 3; /*@ } @*/ |
| }; |
| </BAD_CODE_SNIPPET> |
| <p>Conditional Comments hinder automated tools as they can vary the |
| JavaScript syntax tree at runtime.</p> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| |
| <CATEGORY title="JavaScript Style Rules"> |
| <STYLEPOINT title="Naming"> |
| <SUMMARY> |
| <p>In general, use |
| <code>functionNamesLikeThis</code>, |
| <code>variableNamesLikeThis</code>, |
| <code>ClassNamesLikeThis</code>, |
| <code>EnumNamesLikeThis</code>, |
| <code>methodNamesLikeThis</code>, |
| <code>CONSTANT_VALUES_LIKE_THIS</code>, |
| <code>foo.namespaceNamesLikeThis.bar</code>, and |
| <code>filenameslikethis.js</code>. |
| </p> |
| </SUMMARY> |
| <BODY> |
| <SUBSECTION title="Properties and methods"> |
| <ul> |
| <li><em>Private</em> properties and methods should be named with a |
| trailing underscore. |
| </li> |
| <li><em>Protected</em> properties and methods should be |
| named without a trailing underscore (like public ones).</li> |
| </ul> |
| <p>For more information on <em>private</em> and <em>protected</em>, |
| read the section on |
| <a href="#Visibility__private_and_protected_fields_"> |
| visibility</a>. |
| </p> |
| |
| |
| |
| |
| </SUBSECTION> |
| |
| <SUBSECTION title="Method and function parameter"> |
| <p>Optional function arguments start with <code>opt_</code>.</p> |
| <p>Functions that take a variable number of arguments should have the |
| last argument named <code>var_args</code>. You may not refer to |
| <code>var_args</code> in the code; use the <code>arguments</code> |
| array.</p> |
| <p>Optional and variable arguments can also be specified in |
| <code>@param</code> annotations. Although either convention is |
| acceptable to the compiler, using both together is preferred.</p> |
| |
| </SUBSECTION> |
| |
| <SUBSECTION title="Getters and Setters"> |
| <p>EcmaScript 5 getters and setters for properties are discouraged. |
| However, if they are used, then getters must not change observable |
| state.</p> |
| <BAD_CODE_SNIPPET> |
| /** |
| * WRONG -- Do NOT do this. |
| */ |
| var foo = { get next() { return this.nextId++; } }; |
| </BAD_CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="Accessor functions"> |
| <p>Getters and setters methods for properties are not required. |
| However, if they are used, then getters must be named |
| <code>getFoo()</code> and setters must be named |
| <code>setFoo(value)</code>. (For boolean getters, |
| <code>isFoo()</code> is also acceptable, and often sounds more |
| natural.)</p> |
| </SUBSECTION> |
| |
| <SUBSECTION title="Namespaces"> |
| <p>JavaScript has no inherent packaging or namespacing support.</p> |
| <p>Global name conflicts are difficult to debug, and can cause |
| intractable problems when two projects try to integrate. In order |
| to make it possible to share common JavaScript code, we've adopted |
| conventions to prevent collisions. </p> |
| <SUBSUBSECTION title="Use namespaces for global code"> |
| <p><em>ALWAYS</em> prefix identifiers in the global scope with a |
| unique pseudo namespace related to the project or library. If you |
| are working on "Project Sloth", a reasonable pseudo namespace |
| would be <code>sloth.*</code>.</p> |
| <CODE_SNIPPET> |
| var sloth = {}; |
| |
| sloth.sleep = function() { |
| ... |
| }; |
| </CODE_SNIPPET> |
| |
| |
| <p>Many JavaScript libraries, including |
| <a href="http://code.google.com/closure/library/"> |
| the Closure Library |
| </a> |
| and |
| <a href="http://www.dojotoolkit.org/"> |
| Dojo toolkit |
| </a> |
| give you high-level functions for declaring your namespaces. |
| Be consistent about how you declare your namespaces.</p> |
| <CODE_SNIPPET> |
| goog.provide('sloth'); |
| |
| sloth.sleep = function() { |
| ... |
| }; |
| </CODE_SNIPPET> |
| </SUBSUBSECTION> |
| <SUBSUBSECTION title="Respect namespace ownership"> |
| <p>When choosing a child-namespace, make sure that the owners of the |
| parent namespace know what you are doing. If you start a project |
| that creates hats for sloths, make sure that the Sloth team knows |
| that you're using <code>sloth.hats</code>.</p> |
| |
| </SUBSUBSECTION> |
| <SUBSUBSECTION title="Use different namespaces for external code and internal code"> |
| <p>"External code" is code that comes from outside your codebase, |
| and is compiled independently. Internal and external names should |
| be kept strictly separate. If you're using an external library |
| that makes things available in <code>foo.hats.*</code>, your |
| internal code should not define all its symbols in |
| <code>foo.hats.*</code>, because it will break if the other |
| team defines new symbols.</p> |
| <BAD_CODE_SNIPPET> |
| foo.require('foo.hats'); |
| |
| /** |
| * WRONG -- Do NOT do this. |
| * @constructor |
| * @extends {foo.hats.RoundHat} |
| */ |
| foo.hats.BowlerHat = function() { |
| }; |
| </BAD_CODE_SNIPPET> |
| <p>If you need to define new APIs on an external namespace, then you |
| should explicitly export the public API functions, and only those |
| functions. Your internal code should call the internal APIs by |
| their internal names, for consistency and so that the compiler |
| can optimize them better.</p> |
| <CODE_SNIPPET> |
| foo.provide('googleyhats.BowlerHat'); |
| |
| foo.require('foo.hats'); |
| |
| /** |
| * @constructor |
| * @extends {foo.hats.RoundHat} |
| */ |
| googleyhats.BowlerHat = function() { |
| ... |
| }; |
| |
| goog.exportSymbol('foo.hats.BowlerHat', googleyhats.BowlerHat); |
| </CODE_SNIPPET> |
| |
| |
| </SUBSUBSECTION> |
| <SUBSUBSECTION title="Alias long type names to improve readability"> |
| <p>Use local aliases for fully-qualified types if doing so improves |
| readability. The name of a local alias should match the last part |
| of the type.</p> |
| <CODE_SNIPPET> |
| /** |
| * @constructor |
| */ |
| some.long.namespace.MyClass = function() { |
| }; |
| |
| /** |
| * @param {some.long.namespace.MyClass} a |
| */ |
| some.long.namespace.MyClass.staticHelper = function(a) { |
| ... |
| }; |
| |
| myapp.main = function() { |
| var MyClass = some.long.namespace.MyClass; |
| var staticHelper = some.long.namespace.MyClass.staticHelper; |
| staticHelper(new MyClass()); |
| }; |
| </CODE_SNIPPET> |
| <p>Do not create local aliases of namespaces. Namespaces should only |
| be aliased using <a href="#goog-scope">goog.scope</a>.</p> |
| <BAD_CODE_SNIPPET> |
| myapp.main = function() { |
| var namespace = some.long.namespace; |
| namespace.MyClass.staticHelper(new namespace.MyClass()); |
| }; |
| </BAD_CODE_SNIPPET> |
| <p>Avoid accessing properties of an aliased type, unless it is an |
| enum.</p> |
| <CODE_SNIPPET> |
| /** @enum {string} */ |
| some.long.namespace.Fruit = { |
| APPLE: 'a', |
| BANANA: 'b' |
| }; |
| |
| myapp.main = function() { |
| var Fruit = some.long.namespace.Fruit; |
| switch (fruit) { |
| case Fruit.APPLE: |
| ... |
| case Fruit.BANANA: |
| ... |
| } |
| }; |
| </CODE_SNIPPET> |
| <BAD_CODE_SNIPPET> |
| myapp.main = function() { |
| var MyClass = some.long.namespace.MyClass; |
| MyClass.staticHelper(null); |
| }; |
| </BAD_CODE_SNIPPET> |
| <p>Never create aliases in the global scope. Use them only in |
| function blocks.</p> |
| </SUBSUBSECTION> |
| </SUBSECTION> |
| <SUBSECTION title="Filenames"> |
| <p>Filenames should be all lowercase in order to avoid confusion on |
| case-sensitive platforms. Filenames should end in <code>.js</code>, |
| and should contain no punctuation except for <code>-</code> or |
| <code>_</code> (prefer <code>-</code> to <code>_</code>).</p> |
| </SUBSECTION> |
| |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Custom toString() methods"> |
| <SUMMARY> |
| Must always succeed without side effects. |
| </SUMMARY> |
| <BODY> |
| <p>You can control how your objects string-ify themselves by defining a |
| custom <code>toString()</code> method. This is fine, but you need |
| to ensure that your method (1) always succeeds and (2) does not have |
| side-effects. If your method doesn't meet these criteria, it's very |
| easy to run into serious problems. For example, if |
| <code>toString()</code> calls a method that does an |
| <code>assert</code>, <code>assert</code> might try to output the name |
| of the object in which it failed, which of course requires calling |
| <code>toString()</code>.</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Deferred initialization"> |
| <SUMMARY>OK</SUMMARY> |
| <BODY> |
| <p>It isn't always possible to initialize variables at the point of |
| declaration, so deferred initialization is fine.</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Explicit scope"> |
| <SUMMARY>Always</SUMMARY> |
| <BODY> |
| <p>Always use explicit scope - doing so increases portability and |
| clarity. For example, don't rely on <code>window</code> being in the |
| scope chain. You might want to use your function in another |
| application for which <code>window</code> is not the content |
| window.</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Code formatting"> |
| <SUMMARY>Expand for more information.</SUMMARY> |
| <BODY> |
| <p>We follow the <a href="cppguide.xml#Formatting">C++ formatting |
| rules</a> in spirit, with the following additional clarifications.</p> |
| <SUBSECTION title="Curly Braces"> |
| <p>Because of implicit semicolon insertion, always start your curly |
| braces on the same line as whatever they're opening. For |
| example:</p> |
| <CODE_SNIPPET> |
| if (something) { |
| // ... |
| } else { |
| // ... |
| } |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| <SUBSECTION title="Array and Object Initializers"> |
| <p>Single-line array and object initializers are allowed when they |
| fit on a line:</p> |
| <CODE_SNIPPET> |
| var arr = [1, 2, 3]; // No space after [ or before ]. |
| var obj = {a: 1, b: 2, c: 3}; // No space after { or before }. |
| </CODE_SNIPPET> |
| <p>Multiline array initializers and object initializers are indented |
| 2 spaces, with the braces on their own line, just like blocks.</p> |
| <CODE_SNIPPET> |
| // Object initializer. |
| var inset = { |
| top: 10, |
| right: 20, |
| bottom: 15, |
| left: 12 |
| }; |
| |
| // Array initializer. |
| this.rows_ = [ |
| '"Slartibartfast" <fjordmaster@magrathea.com>', |
| '"Zaphod Beeblebrox" <theprez@universe.gov>', |
| '"Ford Prefect" <ford@theguide.com>', |
| '"Arthur Dent" <has.no.tea@gmail.com>', |
| '"Marvin the Paranoid Android" <marv@googlemail.com>', |
| 'the.mice@magrathea.com' |
| ]; |
| |
| // Used in a method call. |
| goog.dom.createDom(goog.dom.TagName.DIV, { |
| id: 'foo', |
| className: 'some-css-class', |
| style: 'display:none' |
| }, 'Hello, world!'); |
| </CODE_SNIPPET> |
| <p>Long identifiers or values present problems for aligned |
| initialization lists, so always prefer non-aligned initialization. |
| For example:</p> |
| <CODE_SNIPPET> |
| CORRECT_Object.prototype = { |
| a: 0, |
| b: 1, |
| lengthyName: 2 |
| }; |
| </CODE_SNIPPET> |
| <p>Not like this:</p> |
| <BAD_CODE_SNIPPET> |
| WRONG_Object.prototype = { |
| a : 0, |
| b : 1, |
| lengthyName: 2 |
| }; |
| </BAD_CODE_SNIPPET> |
| </SUBSECTION> |
| <SUBSECTION title="Function Arguments"> |
| <p>When possible, all function arguments should be listed on the same |
| line. If doing so would exceed the 80-column limit, the arguments |
| must be line-wrapped in a readable way. To save space, you may wrap |
| as close to 80 as possible, or put each argument on its own line to |
| enhance readability. The indentation may be either four spaces, or |
| aligned to the parenthesis. Below are the most common patterns for |
| argument wrapping:</p> |
| <CODE_SNIPPET> |
| // Four-space, wrap at 80. Works with very long function names, survives |
| // renaming without reindenting, low on space. |
| goog.foo.bar.doThingThatIsVeryDifficultToExplain = function( |
| veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, |
| tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) { |
| // ... |
| }; |
| |
| // Four-space, one argument per line. Works with long function names, |
| // survives renaming, and emphasizes each argument. |
| goog.foo.bar.doThingThatIsVeryDifficultToExplain = function( |
| veryDescriptiveArgumentNumberOne, |
| veryDescriptiveArgumentTwo, |
| tableModelEventHandlerProxy, |
| artichokeDescriptorAdapterIterator) { |
| // ... |
| }; |
| |
| // Parenthesis-aligned indentation, wrap at 80. Visually groups arguments, |
| // low on space. |
| function foo(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, |
| tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) { |
| // ... |
| } |
| |
| // Parenthesis-aligned, one argument per line. Emphasizes each |
| // individual argument. |
| function bar(veryDescriptiveArgumentNumberOne, |
| veryDescriptiveArgumentTwo, |
| tableModelEventHandlerProxy, |
| artichokeDescriptorAdapterIterator) { |
| // ... |
| } |
| </CODE_SNIPPET> |
| <p>When the function call is itself indented, you're free to start the |
| 4-space indent relative to the beginning of the original statement |
| or relative to the beginning of the current function call. |
| The following are all acceptable indentation styles.</p> |
| <CODE_SNIPPET> |
| if (veryLongFunctionNameA( |
| veryLongArgumentName) || |
| veryLongFunctionNameB( |
| veryLongArgumentName)) { |
| veryLongFunctionNameC(veryLongFunctionNameD( |
| veryLongFunctioNameE( |
| veryLongFunctionNameF))); |
| } |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| <SUBSECTION title="Passing Anonymous Functions"> |
| <p>When declaring an anonymous function in the list of arguments for |
| a function call, the body of the function is indented two spaces |
| from the left edge of the statement, or two spaces from the left |
| edge of the function keyword. This is to make the body of the |
| anonymous function easier to read (i.e. not be all squished up into |
| the right half of the screen).</p> |
| <CODE_SNIPPET> |
| prefix.something.reallyLongFunctionName('whatever', function(a1, a2) { |
| if (a1.equals(a2)) { |
| someOtherLongFunctionName(a1); |
| } else { |
| andNowForSomethingCompletelyDifferent(a2.parrot); |
| } |
| }); |
| |
| var names = prefix.something.myExcellentMapFunction( |
| verboselyNamedCollectionOfItems, |
| function(item) { |
| return item.name; |
| }); |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| <SUBSECTION title="Aliasing with goog.scope"> |
| <a name="goog-scope"/> |
| <p> |
| <a href="https://docs.google.com/document/pub?id=1ETFAuh2kaXMVL-vafUYhaWlhl6b5D9TOvboVg7Zl68Y"><code>goog.scope</code></a> |
| may be used to shorten references to |
| namespaced symbols in programs using |
| <a href="http://code.google.com/closure/library/">the Closure |
| Library</a>.</p> |
| <p>Only one <code>goog.scope</code> invocation may be added per |
| file. Always place it in the global scope.</p> |
| <p>The opening <code>goog.scope(function() {</code> invocation |
| must be preceded by exactly one blank line and follow any |
| <code>goog.provide</code> statements, <code>goog.require</code> |
| statements, or top-level comments. The invocation must be closed on |
| the last line in the file. Append <code>// goog.scope</code> to the |
| closing statement of the scope. Separate the comment from the |
| semicolon by two spaces.</p> |
| <p>Similar to C++ namespaces, do not indent under goog.scope |
| declarations. Instead, continue from the 0 column.</p> |
| <p>Only alias names that will not be re-assigned to another object |
| (e.g., most constructors, enums, and namespaces). Do not do |
| this (see below for how to alias a constructor):</p> |
| |
| <BAD_CODE_SNIPPET> |
| goog.scope(function() { |
| var Button = goog.ui.Button; |
| |
| Button = function() { ... }; |
| ... |
| </BAD_CODE_SNIPPET> |
| |
| <p>Names must be the same as the last property of the global that they |
| are aliasing.</p> |
| |
| <CODE_SNIPPET> |
| goog.provide('my.module.SomeType'); |
| |
| goog.require('goog.dom'); |
| goog.require('goog.ui.Button'); |
| |
| goog.scope(function() { |
| var Button = goog.ui.Button; |
| var dom = goog.dom; |
| |
| // Alias new types <b>after</b> the constructor declaration. |
| my.module.SomeType = function() { ... }; |
| var SomeType = my.module.SomeType; |
| |
| // Declare methods on the prototype as usual: |
| SomeType.prototype.findButton = function() { |
| // Button as aliased above. |
| this.button = new Button(dom.getElement('my-button')); |
| }; |
| ... |
| }); // goog.scope |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| <SUBSECTION title="Indenting wrapped lines"> |
| <p>Except for <a href="#Array_and_Object_literals">array literals, |
| object literals</a>, and anonymous functions, all wrapped lines |
| should be indented either left-aligned to a sibling expression |
| above, or four spaces (not two spaces) deeper than a parent |
| expression (where "sibling" and "parent" refer to parenthesis |
| nesting level). |
| </p> |
| |
| <CODE_SNIPPET> |
| someWonderfulHtml = '<div class="' + getClassesForWonderfulHtml()'">' + |
| getEvenMoreHtml(someReallyInterestingValues, moreValues, |
| evenMoreParams, 'a duck', true, 72, |
| slightlyMoreMonkeys(0xfff)) + |
| '</div>'; |
| |
| thisIsAVeryLongVariableName = |
| hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine(); |
| |
| thisIsAVeryLongVariableName = siblingOne + siblingTwo + siblingThree + |
| siblingFour + siblingFive + siblingSix + siblingSeven + |
| moreSiblingExpressions + allAtTheSameIndentationLevel; |
| |
| thisIsAVeryLongVariableName = operandOne + operandTwo + operandThree + |
| operandFour + operandFive * ( |
| aNestedChildExpression + shouldBeIndentedMore); |
| |
| someValue = this.foo( |
| shortArg, |
| 'Some really long string arg - this is a pretty common case, actually.', |
| shorty2, |
| this.bar()); |
| |
| if (searchableCollection(allYourStuff).contains(theStuffYouWant) && |
| !ambientNotification.isActive() && (client.isAmbientSupported() || |
| client.alwaysTryAmbientAnyways())) { |
| ambientNotification.activate(); |
| } |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| <SUBSECTION title="Blank lines"> |
| <p>Use newlines to group logically related pieces of code. |
| For example:</p> |
| <CODE_SNIPPET> |
| doSomethingTo(x); |
| doSomethingElseTo(x); |
| andThen(x); |
| |
| nowDoSomethingWith(y); |
| |
| andNowWith(z); |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| <SUBSECTION title="Binary and Ternary Operators"> |
| <p>Always put the operator on the preceding line. Otherwise, |
| line breaks and indentation follow the same rules as in other |
| Google style guides. This operator placement was initially agreed |
| upon out of concerns about automatic semicolon insertion. In fact, |
| semicolon insertion cannot happen before a binary operator, but new |
| code should stick to this style for consistency.</p> |
| <CODE_SNIPPET> |
| var x = a ? b : c; // All on one line if it will fit. |
| |
| // Indentation +4 is OK. |
| var y = a ? |
| longButSimpleOperandB : longButSimpleOperandC; |
| |
| // Indenting to the line position of the first operand is also OK. |
| var z = a ? |
| moreComplicatedB : |
| moreComplicatedC; |
| </CODE_SNIPPET> |
| <p>This includes the dot operator.</p> |
| <CODE_SNIPPET> |
| var x = foo.bar(). |
| doSomething(). |
| doSomethingElse(); |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Parentheses"> |
| <SUMMARY>Only where required</SUMMARY> |
| <BODY> |
| <p>Use sparingly and in general only where required by the syntax |
| and semantics.</p> |
| <p>Never use parentheses for unary operators such as |
| <code>delete</code>, <code>typeof</code> and <code>void</code> or |
| after keywords such as <code>return</code>, <code>throw</code> as |
| well as others (<code>case</code>, <code>in</code> or |
| <code>new</code>).</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Strings"> |
| <SUMMARY>Prefer ' over "</SUMMARY> |
| <BODY> |
| <p>For consistency single-quotes (') are preferred to double-quotes ("). |
| This is helpful when creating strings that include HTML:</p> |
| <CODE_SNIPPET> |
| var msg = 'This is <a href="http://foo">some HTML</a>'; |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Visibility (private and protected fields)"> |
| <SUMMARY>Encouraged, use JSDoc annotations <code>@private</code> and |
| <code>@protected</code></SUMMARY> |
| <BODY> |
| <p>We recommend the use of the JSDoc annotations <code>@private</code> and |
| <code>@protected</code> to indicate visibility levels for classes, |
| functions, and properties.</p> |
| <p>The --jscomp_warning=visibility compiler flag turns on compiler |
| warnings for visibility violations. See |
| <a href="http://code.google.com/p/closure-compiler/wiki/Warnings"> |
| Closure Compiler |
| Warnings</a>. |
| </p> |
| <p><code>@private</code> global variables and functions are only |
| accessible to code in the same file.</p> |
| <p>Constructors marked <code>@private</code> may only be instantiated by |
| code in the same file and by their static and instance members. |
| <code>@private</code> constructors may also be accessed anywhere in the |
| same file for their public static properties and by the |
| <code>instanceof</code> operator.</p> |
| <p>Global variables, functions, and constructors should never be |
| annotated <code>@protected</code>.</p> |
| <CODE_SNIPPET> |
| // File 1. |
| // AA_PrivateClass_ and AA_init_ are accessible because they are global |
| // and in the same file. |
| |
| /** |
| * @private |
| * @constructor |
| */ |
| AA_PrivateClass_ = function() { |
| }; |
| |
| /** @private */ |
| function AA_init_() { |
| return new AA_PrivateClass_(); |
| } |
| |
| AA_init_(); |
| </CODE_SNIPPET> |
| <p><code>@private</code> properties are accessible to all code in the |
| same file, plus all static methods and instance methods of that class |
| that "owns" the property, if the property belongs to a class. They |
| cannot be accessed or overridden from a subclass in a different file.</p> |
| <p><code>@protected</code> properties are accessible to all code in the |
| same file, plus any static methods and instance methods of any subclass |
| of a class that "owns" the property.</p> |
| <p>Note that these semantics differ from those of C++ and Java, in that |
| they grant private and protected access to all code in the same file, |
| not just in the same class or class hierarchy. Also, unlike in C++, |
| private properties cannot be overridden by a subclass. |
| </p> |
| <CODE_SNIPPET> |
| // File 1. |
| |
| /** @constructor */ |
| AA_PublicClass = function() { |
| /** @private */ |
| this.privateProp_ = 2; |
| |
| /** @protected */ |
| this.protectedProp = 4; |
| }; |
| |
| /** @private */ |
| AA_PublicClass.staticPrivateProp_ = 1; |
| |
| /** @protected */ |
| AA_PublicClass.staticProtectedProp = 31; |
| |
| /** @private */ |
| AA_PublicClass.prototype.privateMethod_ = function() {}; |
| |
| /** @protected */ |
| AA_PublicClass.prototype.protectedMethod = function() {}; |
| |
| // File 2. |
| |
| /** |
| * @return {number} The number of ducks we've arranged in a row. |
| */ |
| AA_PublicClass.prototype.method = function() { |
| // Legal accesses of these two properties. |
| return this.privateProp_ + AA_PublicClass.staticPrivateProp_; |
| }; |
| |
| // File 3. |
| |
| /** |
| * @constructor |
| * @extends {AA_PublicClass} |
| */ |
| AA_SubClass = function() { |
| // Legal access of a protected static property. |
| AA_PublicClass.staticProtectedProp = this.method(); |
| }; |
| goog.inherits(AA_SubClass, AA_PublicClass); |
| |
| /** |
| * @return {number} The number of ducks we've arranged in a row. |
| */ |
| AA_SubClass.prototype.method = function() { |
| // Legal access of a protected instance property. |
| return this.protectedProp; |
| }; |
| </CODE_SNIPPET> |
| |
| <p>Notice that in JavaScript, there is no distinction between a type |
| (like <code>AA_PrivateClass_</code>) and the constructor for that |
| type. There is no way to express both that a type is public and its |
| constructor is private (because the constructor could easily be aliased |
| in a way that would defeat the privacy check).</p> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="JavaScript Types"> |
| <SUMMARY>Encouraged and enforced by the compiler.</SUMMARY> |
| <BODY> |
| <a name="JsTypes"/> |
| <p>When documenting a type in JSDoc, be as specific and accurate as |
| possible. The types we support are based on the |
| <a href="http://wiki.ecmascript.org/doku.php?id=spec:spec"> |
| EcmaScript 4 spec</a>.</p> |
| <SUBSECTION title="The JavaScript Type Language"> |
| <p>The ES4 proposal contained a language for specifying JavaScript |
| types. We use this language in JsDoc to express the types of |
| function parameters and return values.</p> |
| |
| <p>As the ES4 proposal has evolved, this language has changed. The |
| compiler still supports old syntaxes for types, but those syntaxes |
| are deprecated.</p> |
| |
| <p/> |
| <table border="1" style="border-collapse:collapse" cellpadding="4"> |
| <thead> |
| <tr> |
| <th>Syntax Name</th> |
| <th>Syntax</th> |
| <th>Description</th> |
| <th>Deprecated Syntaxes</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>Primitive Type</td> |
| <td> |
| There are 5 primitive types in JavaScript: |
| <code>{null}</code>, |
| <code>{undefined}</code>, |
| <code>{boolean}</code>, |
| <code>{number}</code>, and |
| <code>{string}</code>. |
| </td> |
| <td>Simply the name of a type.</td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Instance Type</td> |
| <td> |
| <code>{Object}</code><br/> |
| An instance of Object or null.<p/> |
| <code>{Function}</code><br/> |
| An instance of Function or null.<p/> |
| <code>{EventTarget}</code><br/> |
| An instance of a constructor that implements the EventTarget |
| interface, or null. |
| </td> |
| <td>An instance of a constructor or interface function.<p/> |
| |
| Constructor functions are functions defined with the |
| <code>@constructor</code> JSDoc tag. |
| Interface functions are functions defined with the |
| <code>@interface</code> JSDoc tag.<p/> |
| |
| By default, instance types will accept null. This is the only |
| type syntax that makes the type nullable. Other type syntaxes |
| in this table will not accept null. |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Enum Type</td> |
| <td> |
| <code>{goog.events.EventType}</code><br/> |
| One of the properties of the object literal initializer |
| of <code>goog.events.EventType</code>. |
| </td> |
| <td>An enum must be initialized as an object literal, or as |
| an alias of another enum, annotated with the <code>@enum</code> |
| JSDoc tag. The properties of this literal are the instances |
| of the enum. The syntax of the enum is defined |
| <a href="#enums">below</a>.<p/> |
| |
| Note that this is one of the few things in our type system |
| that were not in the ES4 spec. |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Type Application</td> |
| <td> |
| <code>{Array.<string>}</code><br/>An array of strings.<p/> |
| <code>{Object.<string, number>}</code> |
| <br/>An object in which the keys are strings and the values |
| are numbers. |
| </td> |
| <td>Parameterizes a type, by applying a set of type arguments |
| to that type. The idea is analogous to generics in Java. |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Type Union</td> |
| <td> |
| <code>{(number|boolean)}</code><br/>A number or a boolean. |
| </td> |
| <td>Indicates that a value might have type A OR type B.<p/> |
| |
| The parentheses may be omitted at the top-level |
| expression, but the parentheses should be included in |
| sub-expressions to avoid ambiguity.<br/> |
| <code>{number|boolean}</code><br/> |
| <code>{function(): (number|boolean)}</code> |
| </td> |
| <td> |
| <code>{(number,boolean)}</code>,<br/> |
| <code>{(number||boolean)}</code> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Nullable type</td> |
| <td> |
| <code>{?number}</code><br/> A number or null. |
| </td> |
| <td>Shorthand for the union of the null type with any |
| other type. This is just syntactic sugar. |
| </td> |
| <td> |
| <code>{number?}</code> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Non-nullable type</td> |
| <td> |
| <code>{!Object}</code><br/> An Object, but never the |
| <code>null</code> value. |
| </td> |
| <td>Filters null out of nullable types. Most often used |
| with instance types, which are nullable by default. |
| </td> |
| <td> |
| <code>{Object!}</code> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Record Type</td> |
| <td> |
| <code>{{myNum: number, myObject}}</code> |
| <br/>An anonymous type with the given type members. |
| </td> |
| <td> |
| <p>Indicates that the value has the specified members with the |
| specified types. In this case, <code>myNum</code> with a |
| type <code>number</code> and <code>myObject</code> with any |
| type.</p> |
| <p>Notice that the braces are part of the type syntax. For |
| example, to denote an <code>Array</code> of objects that |
| have a <code>length</code> property, you might write |
| <code>Array.<{length}></code>.</p> |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Function Type</td> |
| <td> |
| <code>{function(string, boolean)}</code><br/> |
| A function that takes two arguments (a string and a boolean), |
| and has an unknown return value.<br/> |
| </td> |
| <td>Specifies a function.</td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Function Return Type</td> |
| <td> |
| <code>{function(): number}</code><br/> |
| A function that takes no arguments and returns a number.<br/> |
| </td> |
| <td>Specifies a function return type.</td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Function <code>this</code> Type</td> |
| <td> |
| <code>{function(this:goog.ui.Menu, string)}</code><br/> |
| A function that takes one argument (a string), and executes |
| in the context of a goog.ui.Menu. |
| </td> |
| <td>Specifies the context type of a function type.</td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Function <code>new</code> Type</td> |
| <td> |
| <code>{function(new:goog.ui.Menu, string)}</code><br/> |
| A constructor that takes one argument (a string), and |
| creates a new instance of goog.ui.Menu when called |
| with the 'new' keyword. |
| </td> |
| <td>Specifies the constructed type of a constructor.</td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Variable arguments</td> |
| <td> |
| <code>{function(string, ...[number]): number}</code><br/> |
| A function that takes one argument (a string), and then a |
| variable number of arguments that must be numbers. |
| </td> |
| <td>Specifies variable arguments to a function.</td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td> |
| <a name="var-args-annotation"/> |
| Variable arguments (in <code>@param</code> annotations) |
| </td> |
| <td> |
| <code>@param {...number} var_args</code><br/> |
| A variable number of arguments to an annotated function. |
| </td> |
| <td> |
| Specifies that the annotated function accepts a variable |
| number of arguments. |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Function <a href="#optional">optional arguments</a></td> |
| <td> |
| <code>{function(?string=, number=)}</code><br/> |
| A function that takes one optional, nullable string and one |
| optional number as arguments. The <code>=</code> syntax is |
| only for <code>function</code> type declarations. |
| </td> |
| <td>Specifies optional arguments to a function.</td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td> |
| <a name="optional-arg-annotation"/> |
| Function <a href="#optional">optional arguments</a> |
| (in <code>@param</code> annotations) |
| </td> |
| <td> |
| <code>@param {number=} opt_argument</code><br/> |
| An optional parameter of type <code>number</code>. |
| </td> |
| <td>Specifies that the annotated function accepts an optional |
| argument.</td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>The ALL type</td> |
| <td><code>{*}</code></td> |
| <td>Indicates that the variable can take on any type.</td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>The UNKNOWN type</td> |
| <td><code>{?}</code></td> |
| <td>Indicates that the variable can take on any type, |
| and the compiler should not type-check any uses of it.</td> |
| <td/> |
| </tr> |
| </tbody> |
| </table> |
| </SUBSECTION> |
| <SUBSECTION title="Types in JavaScript"> |
| <p/> |
| <table border="1" style="border-collapse:collapse" cellpadding="4"> |
| <thead> |
| <tr> |
| <th>Type Example</th> |
| <th>Value Examples</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| |
| <tr> |
| <td>number</td> |
| <td> |
| <CODE_SNIPPET> |
| 1 |
| 1.0 |
| -5 |
| 1e5 |
| Math.PI |
| </CODE_SNIPPET> |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Number</td> |
| <td> |
| <CODE_SNIPPET> |
| new Number(true) |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| <a href="#Wrapper_objects_for_primitive_types"> |
| Number object |
| </a> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>string</td> |
| <td> |
| <CODE_SNIPPET> |
| 'Hello' |
| "World" |
| String(42) |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| String value |
| </td> |
| </tr> |
| |
| <tr> |
| <td>String</td> |
| <td> |
| <CODE_SNIPPET> |
| new String('Hello') |
| new String(42) |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| <a href="#Wrapper_objects_for_primitive_types"> |
| String object |
| </a> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>boolean</td> |
| <td> |
| <CODE_SNIPPET> |
| true |
| false |
| Boolean(0) |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Boolean value |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Boolean</td> |
| <td> |
| <CODE_SNIPPET> |
| new Boolean(true) |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| <a href="#Wrapper_objects_for_primitive_types"> |
| Boolean object |
| </a> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>RegExp</td> |
| <td> |
| <CODE_SNIPPET> |
| new RegExp('hello') |
| /world/g |
| </CODE_SNIPPET></td><td> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Date</td> |
| <td> |
| <CODE_SNIPPET> |
| new Date |
| new Date() |
| </CODE_SNIPPET></td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td> |
| |
| null |
| |
| </td> |
| <td> |
| <CODE_SNIPPET> |
| null |
| </CODE_SNIPPET> |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td> |
| |
| undefined |
| |
| </td> |
| <td> |
| <CODE_SNIPPET> |
| undefined |
| </CODE_SNIPPET> |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>void</td> |
| <td> |
| <CODE_SNIPPET> |
| function f() { |
| return; |
| } |
| </CODE_SNIPPET> |
| </td> |
| <td>No return value</td> |
| </tr> |
| |
| <tr> |
| <td>Array</td> |
| <td> |
| <CODE_SNIPPET> |
| ['foo', 0.3, null] |
| [] |
| </CODE_SNIPPET> |
| </td> |
| <td>Untyped Array</td> |
| </tr> |
| |
| <tr> |
| <td>Array.<number></td> |
| <td> |
| <CODE_SNIPPET> |
| [11, 22, 33] |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| An Array of numbers |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Array.<Array.<string>></td> |
| <td> |
| <CODE_SNIPPET> |
| [['one', 'two', 'three'], ['foo', 'bar']] |
| </CODE_SNIPPET> |
| </td> |
| <td>Array of Arrays of strings</td> |
| </tr> |
| |
| <tr> |
| <td>Object</td> |
| <td> |
| <CODE_SNIPPET> |
| {} |
| {foo: 'abc', bar: 123, baz: null} |
| </CODE_SNIPPET> |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>Object.<string></td> |
| <td> |
| <CODE_SNIPPET> |
| {'foo': 'bar'} |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| An Object in which the values are strings. |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Object.<number, string></td> |
| <td> |
| <CODE_SNIPPET> |
| var obj = {}; |
| obj[1] = 'bar'; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| An Object in which the keys are numbers and the values are |
| strings. <p/>Note that in JavaScript, the keys are always |
| implicitly converted to strings, so |
| <code>obj['1'] == obj[1]</code>. |
| So the key will always be a string in for...in loops. But the |
| compiler will verify the type of the key when indexing into |
| the object. |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Function</td> |
| <td> |
| <CODE_SNIPPET> |
| function(x, y) { |
| return x * y; |
| } |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| <a href="#Wrapper_objects_for_primitive_types"> |
| Function object |
| </a> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>function(number, number): number</td> |
| <td> |
| <CODE_SNIPPET> |
| function(x, y) { |
| return x * y; |
| } |
| </CODE_SNIPPET> |
| </td> |
| <td>function value</td> |
| </tr> |
| |
| <tr> |
| <td><a name="constructor-tag">SomeClass</a></td> |
| <td> |
| <CODE_SNIPPET> |
| /** @constructor */ |
| function SomeClass() {} |
| |
| new SomeClass(); |
| </CODE_SNIPPET> |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>SomeInterface</td> |
| <td> |
| <CODE_SNIPPET> |
| /** @interface */ |
| function SomeInterface() {} |
| |
| SomeInterface.prototype.draw = function() {}; |
| </CODE_SNIPPET> |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>project.MyClass</td> |
| <td> |
| <CODE_SNIPPET> |
| /** @constructor */ |
| project.MyClass = function () {} |
| |
| new project.MyClass() |
| </CODE_SNIPPET> |
| </td> |
| <td/> |
| </tr> |
| |
| <tr> |
| <td>project.MyEnum</td> |
| <td> |
| <CODE_SNIPPET> |
| /** @enum {string} */ |
| project.MyEnum = { |
| /** The color blue. */ |
| BLUE: '#0000dd', |
| /** The color red. */ |
| RED: '#dd0000' |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td><a name="enums">Enumeration</a><p/> |
| JSDoc comments on enum values are optional. |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Element</td> |
| <td> |
| <CODE_SNIPPET> |
| document.createElement('div') |
| </CODE_SNIPPET> |
| </td> |
| <td>Elements in the DOM.</td> |
| </tr> |
| |
| <tr> |
| <td>Node</td> |
| <td> |
| <CODE_SNIPPET> |
| document.body.firstChild |
| </CODE_SNIPPET> |
| </td> |
| <td>Nodes in the DOM.</td> |
| </tr> |
| |
| <tr> |
| <td>HTMLInputElement</td> |
| <td> |
| <CODE_SNIPPET> |
| htmlDocument.getElementsByTagName('input')[0] |
| </CODE_SNIPPET> |
| </td> |
| <td>A specific type of DOM element.</td> |
| </tr> |
| </tbody> |
| </table> |
| </SUBSECTION> |
| |
| <SUBSECTION title="Type Casts"> |
| <p>In cases where type-checking doesn't accurately infer the type of |
| an expression, it is possible to add a type cast comment by adding a |
| type annotation comment and enclosing the expression in |
| parentheses. The parentheses are required.</p> |
| |
| <CODE_SNIPPET> |
| /** @type {number} */ (x) |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="Nullable vs. Optional Parameters and Properties"> |
| <a name="optional"/> |
| <p>Because JavaScript is a loosely-typed language, it is very |
| important to understand the subtle differences between optional, |
| nullable, and undefined function parameters and class |
| properties.</p> |
| |
| <p>Instances of classes and interfaces are nullable by default. |
| For example, the following declaration</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * Some class, initialized with a value. |
| * @param {Object} value Some value. |
| * @constructor |
| */ |
| function MyClass(value) { |
| /** |
| * Some value. |
| * @type {Object} |
| * @private |
| */ |
| this.myValue_ = value; |
| } |
| </CODE_SNIPPET> |
| |
| <p>tells the compiler that the <code>myValue_</code> property holds |
| either an Object or null. If <code>myValue_</code> must never be |
| null, it should be declared like this:</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * Some class, initialized with a non-null value. |
| * @param {!Object} value Some value. |
| * @constructor |
| */ |
| function MyClass(value) { |
| /** |
| * Some value. |
| * @type {!Object} |
| * @private |
| */ |
| this.myValue_ = value; |
| } |
| </CODE_SNIPPET> |
| |
| <p>This way, if the compiler can determine that somewhere in the code |
| <code>MyClass</code> is initialized with a null value, it will issue |
| a warning.</p> |
| |
| |
| |
| <p>Optional parameters to functions may be undefined at runtime, so if |
| they are assigned to class properties, those properties must be |
| declared accordingly:</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * Some class, initialized with an optional value. |
| * @param {Object=} opt_value Some value (optional). |
| * @constructor |
| */ |
| function MyClass(opt_value) { |
| /** |
| * Some value. |
| * @type {Object|undefined} |
| * @private |
| */ |
| this.myValue_ = opt_value; |
| } |
| </CODE_SNIPPET> |
| |
| <p>This tells the compiler that <code>myValue_</code> may hold an |
| Object, null, or remain undefined.</p> |
| |
| <p>Note that the optional parameter <code>opt_value</code> is declared |
| to be of type <code>{Object=}</code>, not |
| <code>{Object|undefined}</code>. This is because optional |
| parameters may, by definition, be undefined. While there is no harm |
| in explicitly declaring an optional parameter as possibly undefined, |
| it is both unnecessary and makes the code harder to read.</p> |
| |
| <p>Finally, note that being nullable and being optional are orthogonal |
| properties. The following four declarations are all different:</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * Takes four arguments, two of which are nullable, and two of which are |
| * optional. |
| * @param {!Object} nonNull Mandatory (must not be undefined), must not be null. |
| * @param {Object} mayBeNull Mandatory (must not be undefined), may be null. |
| * @param {!Object=} opt_nonNull Optional (may be undefined), but if present, |
| * must not be null! |
| * @param {Object=} opt_mayBeNull Optional (may be undefined), may be null. |
| */ |
| function strangeButTrue(nonNull, mayBeNull, opt_nonNull, opt_mayBeNull) { |
| // ... |
| }; |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="Typedefs"> |
| <a name="Typedefs"/> |
| <p>Sometimes types can get complicated. A function that accepts |
| content for an Element might look like:</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * @param {string} tagName |
| * @param {(string|Element|Text|Array.<Element>|Array.<Text>)} contents |
| * @return {!Element} |
| */ |
| goog.createElement = function(tagName, contents) { |
| ... |
| }; |
| </CODE_SNIPPET> |
| |
| <p>You can define commonly used type expressions with a |
| <code>@typedef</code> tag. For example,</p> |
| |
| <CODE_SNIPPET> |
| /** @typedef {(string|Element|Text|Array.<Element>|Array.<Text>)} */ |
| goog.ElementContent; |
| |
| /** |
| * @param {string} tagName |
| * @param {goog.ElementContent} contents |
| * @return {!Element} |
| */ |
| goog.createElement = function(tagName, contents) { |
| ... |
| }; |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="Template types"> |
| <a name="Template_types"/> |
| <p>The compiler has limited support for template types. It can only |
| infer the type of <code>this</code> inside an anonymous function |
| literal from the type of the <code>this</code> argument and whether the |
| <code>this</code> argument is missing.</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * @param {function(this:T, ...)} fn |
| * @param {T} thisObj |
| * @param {...*} var_args |
| * @template T |
| */ |
| goog.bind = function(fn, thisObj, var_args) { |
| ... |
| }; |
| // Possibly generates a missing property warning. |
| goog.bind(function() { this.someProperty; }, new SomeClass()); |
| // Generates an undefined this warning. |
| goog.bind(function() { this.someProperty; }); |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Comments"> |
| <SUMMARY>Use JSDoc</SUMMARY> |
| <BODY> |
| <p> |
| We follow the |
| <a href="cppguide.xml#Comments"> |
| C++ style for comments</a> in spirit. |
| </p> |
| |
| <p>All files, classes, methods and properties should be documented with |
| <a href="http://code.google.com/p/jsdoc-toolkit/">JSDoc</a> |
| comments with the appropriate <a href="#JSDoc_Tag_Reference">tags</a> |
| and <a href="#JsTypes">types</a>. Textual descriptions for properties, |
| methods, method parameters and method return values should be included |
| unless obvious from the property, method, or parameter name. |
| </p> |
| |
| <p>Inline comments should be of the <code>//</code> variety.</p> |
| |
| <p>Complete sentences are recommended but not required. |
| Complete sentences should use appropriate capitalization |
| and punctuation.</p> |
| |
| <SUBSECTION title="Comment Syntax"> |
| <p>The JSDoc syntax is based on |
| <a href="http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html"> |
| JavaDoc</a>. Many tools extract metadata from JSDoc comments to |
| perform code validation and optimizations. These comments must be |
| well-formed.</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * A JSDoc comment should begin with a slash and 2 asterisks. |
| * Inline tags should be enclosed in braces like {@code this}. |
| * @desc Block tags should always start on their own line. |
| */ |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="JSDoc Indentation"> |
| <p>If you have to line break a block tag, you should treat this as |
| breaking a code statement and indent it four spaces.</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * Illustrates line wrapping for long param/return descriptions. |
| * @param {string} foo This is a param with a description too long to fit in |
| * one line. |
| * @return {number} This returns something that has a description too long to |
| * fit in one line. |
| */ |
| project.MyClass.prototype.method = function(foo) { |
| return 5; |
| }; |
| </CODE_SNIPPET> |
| |
| <p>You should not indent the <code>@fileoverview</code> command. You do not have to |
| indent the <code>@desc</code> command.</p> |
| |
| <p>Even though it is not preferred, it is also acceptable to line up |
| the description.</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * This is NOT the preferred indentation method. |
| * @param {string} foo This is a param with a description too long to fit in |
| * one line. |
| * @return {number} This returns something that has a description too long to |
| * fit in one line. |
| */ |
| project.MyClass.prototype.method = function(foo) { |
| return 5; |
| }; |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="HTML in JSDoc"> |
| <p>Like JavaDoc, JSDoc supports many HTML tags, like <code>, |
| <pre>, <tt>, <strong>, <ul>, <ol>, |
| <li>, <a>, and others.</p> |
| |
| <p>This means that plaintext formatting is not respected. So, don't |
| rely on whitespace to format JSDoc:</p> |
| |
| <BAD_CODE_SNIPPET> |
| /** |
| * Computes weight based on three factors: |
| * items sent |
| * items received |
| * last timestamp |
| */ |
| </BAD_CODE_SNIPPET> |
| |
| <p>It'll come out like this:</p> |
| |
| <BAD_CODE_SNIPPET> |
| Computes weight based on three factors: items sent items received last timestamp |
| </BAD_CODE_SNIPPET> |
| |
| <p>Instead, do this:</p> |
| |
| <CODE_SNIPPET> |
| /** |
| * Computes weight based on three factors: |
| * <ul> |
| * <li>items sent |
| * <li>items received |
| * <li>last timestamp |
| * </ul> |
| */ |
| </CODE_SNIPPET> |
| |
| The <a href="http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html"> |
| JavaDoc</a> style guide is a useful resource on how to write |
| well-formed doc comments. |
| </SUBSECTION> |
| |
| <SUBSECTION title="Top/File-Level Comments"> |
| <p> |
| |
| A <a href="copyright.html">copyright notice</a> and author information are optional. |
| File overviews are generally recommended whenever a file consists of |
| more than a single class definition. The top level comment is |
| designed to orient readers unfamiliar with the code to what is in |
| this file. If present, it should provide a description of the |
| file's contents and any dependencies or compatibility information. |
| As an example: |
| </p> |
| |
| <CODE_SNIPPET> |
| /** |
| * @fileoverview Description of file, its uses and information |
| * about its dependencies. |
| */ |
| </CODE_SNIPPET> |
| |
| |
| </SUBSECTION> |
| |
| <SUBSECTION title="Class Comments"> |
| <p>Classes must be documented with a description and a |
| <a href="#constructor-tag">type tag that |
| identifies the constructor</a>. |
| </p> |
| |
| <CODE_SNIPPET> |
| /** |
| * Class making something fun and easy. |
| * @param {string} arg1 An argument that makes this more interesting. |
| * @param {Array.<number>} arg2 List of numbers to be processed. |
| * @constructor |
| * @extends {goog.Disposable} |
| */ |
| project.MyClass = function(arg1, arg2) { |
| // ... |
| }; |
| goog.inherits(project.MyClass, goog.Disposable); |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="Method and Function Comments"> |
| <p>Parameter and return types should be documented. The method |
| description may be omitted if it is obvious from the parameter |
| or return type descriptions. Method descriptions should start |
| with a sentence written in the third person declarative voice.</p> |
| <CODE_SNIPPET> |
| /** |
| * Operates on an instance of MyClass and returns something. |
| * @param {project.MyClass} obj Instance of MyClass which leads to a long |
| * comment that needs to be wrapped to two lines. |
| * @return {boolean} Whether something occurred. |
| */ |
| function PR_someMethod(obj) { |
| // ... |
| } |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="Property Comments"> |
| <CODE_SNIPPET> |
| /** @constructor */ |
| project.MyClass = function() { |
| /** |
| * Maximum number of things per pane. |
| * @type {number} |
| */ |
| this.someProperty = 4; |
| } |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="JSDoc Tag Reference"> |
| <a name="JSDoc_Tag_Reference"/> |
| <p/> |
| <table border="1" style="border-collapse:collapse" cellpadding="4"> |
| <thead> |
| <tr> |
| <th>Tag</th> |
| <th>Template & Examples</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td> |
| <a name="tag-author">@author</a> |
| |
| </td> |
| <td> |
| <code>@author username@google.com (first last)</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @fileoverview Utilities for handling textareas. |
| * @author kuth@google.com (Uthur Pendragon) |
| */ |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Document the author of a file or the owner of a test, |
| generally only used in the <code>@fileoverview</code> comment. |
| |
| </td> |
| </tr> |
| |
| |
| |
| <tr> |
| <td><a name="tag-code">@code</a></td> |
| <td> |
| <code>{@code ...}</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * Moves to the next position in the selection. |
| * Throws {@code goog.iter.StopIteration} when it |
| * passes the end of the range. |
| * @return {Node} The node at the next position. |
| */ |
| goog.dom.RangeIterator.prototype.next = function() { |
| // ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Indicates that a term in a JSDoc description is code so it may |
| be correctly formatted in generated documentation. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-const">@const</a></td> |
| <td> |
| <code>@const</code><br/> |
| <code>@const {type}</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** @const */ var MY_BEER = 'stout'; |
| |
| /** |
| * My namespace's favorite kind of beer. |
| * @const {string} |
| */ |
| mynamespace.MY_BEER = 'stout'; |
| |
| /** @const */ MyClass.MY_BEER = 'stout'; |
| |
| /** |
| * Initializes the request. |
| * @const |
| */ |
| mynamespace.Request.prototype.initialize = function() { |
| // This method cannot be overridden in a subclass. |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| <p>Marks a variable (or property) as read-only and suitable |
| for inlining.</p> |
| |
| <p>A <code>@const</code> variable is an immutable pointer to |
| a value. If a variable or property marked as |
| <code>@const</code> is overwritten, JSCompiler will give |
| warnings.</p> |
| |
| <p>The type declaration of a constant value can be omitted |
| if it can be clearly inferred. An additional comment about |
| the variable is optional.</p> |
| |
| <p>When <code>@const</code> is applied to a method, it |
| implies the method is not only not overwritable, but also |
| that the method is <em>finalized</em> — |
| not overridable in subclasses.</p> |
| |
| <p>For more on <code>@const</code>, see the |
| <a href="#Constants">Constants</a> section.</p> |
| |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-constructor">@constructor</a></td> |
| <td> |
| <code>@constructor</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * A rectangle. |
| * @constructor |
| */ |
| function GM_Rect() { |
| ... |
| } |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used in a class's documentation to indicate the constructor. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-define">@define</a></td> |
| <td> |
| <code>@define {Type} description</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** @define {boolean} */ |
| var TR_FLAGS_ENABLE_DEBUG = true; |
| |
| /** |
| * @define {boolean} Whether we know at compile-time that |
| * the browser is IE. |
| */ |
| goog.userAgent.ASSUME_IE = false; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Indicates a constant that can be overridden by the compiler at |
| compile-time. In the example, the compiler flag |
| <code>--define='goog.userAgent.ASSUME_IE=true'</code> |
| could be specified in the BUILD file to indicate that the |
| constant <code>goog.userAgent.ASSUME_IE</code> should be replaced |
| with <code>true</code>. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-deprecated">@deprecated</a></td> |
| <td> |
| <code>@deprecated Description</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * Determines whether a node is a field. |
| * @return {boolean} True if the contents of |
| * the element are editable, but the element |
| * itself is not. |
| * @deprecated Use isField(). |
| */ |
| BN_EditUtil.isTopEditableField = function(node) { |
| // ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used to tell that a function, method or property should not be |
| used any more. Always provide instructions on what callers |
| should use instead. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-dict">@dict</a></td> |
| <td> |
| <code>@dict Description</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @constructor |
| * @dict |
| */ |
| function Foo(x) { |
| this['x'] = x; |
| } |
| var obj = new Foo(123); |
| var num = obj.x; // warning |
| |
| (/** @dict */ { x: 1 }).x = 123; // warning |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| When a constructor (<code>Foo</code> in the example) is |
| annotated with <code>@dict</code>, you can only use the |
| bracket notation to access the properties of <code>Foo</code> |
| objects. |
| The annotation can also be used directly on object literals. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-enum">@enum</a></td> |
| <td> |
| <code>@enum {Type}</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * Enum for tri-state values. |
| * @enum {number} |
| */ |
| project.TriState = { |
| TRUE: 1, |
| FALSE: -1, |
| MAYBE: 0 |
| }; |
| </CODE_SNIPPET> |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-export">@export</a></td> |
| <td> |
| <code>@export</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** @export */ |
| foo.MyPublicClass.prototype.myPublicMethod = function() { |
| // ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| <p>Given the code on the left, when the compiler is run with |
| the <code>--generate_exports</code> flag, it will generate the |
| code:</p> |
| <CODE_SNIPPET> |
| goog.exportSymbol('foo.MyPublicClass.prototype.myPublicMethod', |
| foo.MyPublicClass.prototype.myPublicMethod); |
| </CODE_SNIPPET> |
| <p>which will export the symbols to uncompiled code. |
| Code that uses the <code>@export</code> annotation must either</p> |
| <ol> |
| <li>include <code>//javascript/closure/base.js</code>, or</li> |
| <li>define both <code>goog.exportSymbol</code> and |
| <code>goog.exportProperty</code> with the same method |
| signature in their own codebase.</li> |
| </ol> |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-expose">@expose</a></td> |
| <td> |
| <code>@expose</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** @expose */ |
| MyClass.prototype.exposedProperty = 3; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| <p> |
| Declares an exposed property. Exposed properties |
| will not be removed, or renamed, or collapsed, |
| or optimized in any way by the compiler. No properties |
| with the same name will be able to be optimized either. |
| </p> |
| |
| <p> |
| <code>@expose</code> should never be used in library code, |
| because it will prevent that property from ever getting |
| removed. |
| </p> |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-extends">@extends</a></td> |
| <td> |
| <code> |
| @extends Type<br/> |
| @extends {Type} |
| </code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * Immutable empty node list. |
| * @constructor |
| * @extends goog.ds.BasicNodeList |
| */ |
| goog.ds.EmptyNodeList = function() { |
| ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used with <code>@constructor</code> to indicate that a class |
| inherits from another class. Curly braces around the type are |
| optional. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-externs">@externs</a></td> |
| <td> |
| <code>@externs</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @fileoverview This is an externs file. |
| * @externs |
| */ |
| |
| var document; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| <p> |
| Declares an |
| |
| externs file. |
| </p> |
| |
| |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-fileoverview">@fileoverview</a></td> |
| <td> |
| <code>@fileoverview Description</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @fileoverview Utilities for doing things that require this very long |
| * but not indented comment. |
| * @author kuth@google.com (Uthur Pendragon) |
| */ |
| </CODE_SNIPPET> |
| </td> |
| <td>Makes the comment block provide file level information.</td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-implements">@implements</a></td> |
| <td> |
| <code> |
| @implements Type<br/> |
| @implements {Type} |
| </code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * A shape. |
| * @interface |
| */ |
| function Shape() {}; |
| Shape.prototype.draw = function() {}; |
| |
| /** |
| * @constructor |
| * @implements {Shape} |
| */ |
| function Square() {}; |
| Square.prototype.draw = function() { |
| ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used with <code>@constructor</code> to indicate that a class |
| implements an interface. Curly braces around the type are |
| optional. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-inheritDoc">@inheritDoc</a></td> |
| <td> |
| <code>@inheritDoc</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** @inheritDoc */ |
| project.SubClass.prototype.toString() { |
| // ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| <p style="font-weight:bold">Deprecated. Use |
| <code>@override</code> instead.</p> |
| |
| Indicates that a method or property of a subclass |
| intentionally hides a method or property of the superclass, |
| and has exactly the same documentation. Notice that |
| <code>@inheritDoc</code> implies <code>@override</code> |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-interface">@interface</a></td> |
| <td> |
| <code>@interface</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * A shape. |
| * @interface |
| */ |
| function Shape() {}; |
| Shape.prototype.draw = function() {}; |
| |
| /** |
| * A polygon. |
| * @interface |
| * @extends {Shape} |
| */ |
| function Polygon() {}; |
| Polygon.prototype.getSides = function() {}; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used to indicate that the function defines an interface. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-lends">@lends</a></td> |
| <td> |
| <code>@lends objectName</code><br/> |
| <code>@lends {objectName}</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| goog.object.extend( |
| Button.prototype, |
| /** @lends {Button.prototype} */ { |
| isButton: function() { return true; } |
| }); |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Indicates that the keys of an object literal should |
| be treated as properties of some other object. This annotation |
| should only appear on object literals.<p/> |
| |
| Notice that the name in braces is not a type name like |
| in other annotations. It's an object name. It names |
| the object on which the properties are "lent". |
| For example, <code>@type {Foo}</code> means "an instance of Foo", |
| but <code>@lends {Foo}</code> means "the constructor Foo".<p/> |
| |
| The <a href="http://code.google.com/p/jsdoc-toolkit/wiki/TagLends"> |
| JSDoc Toolkit docs</a> have more information on this |
| annotation. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-license">@license</a> or |
| <a name="tag-preserve">@preserve</a></td> |
| <td> |
| <code>@license Description</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @preserve Copyright 2009 SomeThirdParty. |
| * Here is the full license text and copyright |
| * notice for this file. Note that the notice can span several |
| * lines and is only terminated by the closing star and slash: |
| */ |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Anything marked by <code>@license</code> or |
| <code>@preserve</code> will be retained by the compiler and |
| output at the top of the compiled code for that file. This |
| annotation allows important notices (such as legal licenses or |
| copyright text) to survive compilation unchanged. Line breaks |
| are preserved. |
| </td> |
| </tr> |
| |
| |
| |
| |
| |
| <tr> |
| <td><a name="tag-noalias">@noalias</a></td> |
| <td> |
| <code>@noalias</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** @noalias */ |
| function Range() {} |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used in an externs file to indicate to the compiler that the |
| variable or function should not be aliased as part of the |
| alias externals pass of the compiler. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-nocompile">@nocompile</a></td> |
| <td> |
| <code>@nocompile</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** @nocompile */ |
| |
| // JavaScript code |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used at the top of a file to tell the compiler to parse this |
| file but not compile it. |
| Code that is not meant for compilation and should be omitted |
| from compilation tests (such as bootstrap code) uses this |
| annotation. |
| Use sparingly. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-nosideeffects">@nosideeffects</a></td> |
| <td> |
| <code>@nosideeffects</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** @nosideeffects */ |
| function noSideEffectsFn1() { |
| // ... |
| } |
| |
| /** @nosideeffects */ |
| var noSideEffectsFn2 = function() { |
| // ... |
| }; |
| |
| /** @nosideeffects */ |
| a.prototype.noSideEffectsFn3 = function() { |
| // ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| This annotation can be used as part of function and |
| constructor declarations to indicate that calls to the |
| declared function have no side-effects. This annotation |
| allows the compiler to remove calls to these functions if the |
| return value is not used. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-override">@override</a></td> |
| <td> |
| <code>@override</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @return {string} Human-readable representation of project.SubClass. |
| * @override |
| */ |
| project.SubClass.prototype.toString = function() { |
| // ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Indicates that a method or property of a subclass |
| intentionally hides a method or property of the superclass. If |
| no other documentation is included, the method or property |
| also inherits documentation from its superclass. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-param">@param</a></td> |
| <td> |
| <code>@param {Type} varname Description</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * Queries a Baz for items. |
| * @param {number} groupNum Subgroup id to query. |
| * @param {string|number|null} term An itemName, |
| * or itemId, or null to search everything. |
| */ |
| goog.Baz.prototype.query = function(groupNum, term) { |
| // ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used with method, function and constructor calls to document |
| the arguments of a function.<p/> |
| |
| <a href="#JsTypes">Type</a> |
| names must be enclosed in curly braces. If the type |
| is omitted, the compiler will not type-check the parameter. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-private">@private</a></td> |
| <td> |
| <code>@private</code><br/> |
| <code>@private {type}</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * Handlers that are listening to this logger. |
| * @private {!Array.<Function>} |
| */ |
| this.handlers_ = []; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used in conjunction with a trailing underscore on the method |
| or property name to indicate that the member is |
| <a href="#Visibility__private_and_protected_fields_">private</a> and final. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-protected">@protected</a></td> |
| <td> |
| <code>@protected</code><br/> |
| <code>@protected {type}</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * Sets the component's root element to the given element. |
| * @param {Element} element Root element for the component. |
| * @protected |
| */ |
| goog.ui.Component.prototype.setElementInternal = function(element) { |
| // ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used to indicate that the member or property is |
| <a href="#Visibility__private_and_protected_fields_">protected</a>. |
| Should be used in conjunction with names with no trailing |
| underscore. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-public">@public</a></td> |
| <td> |
| <code>@public</code><br/> |
| <code>@public {type}</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * Whether to cancel the event in internal capture/bubble processing. |
| * @public {boolean} |
| * @suppress {visiblity} Referencing this outside this package is strongly |
| * discouraged. |
| */ |
| goog.events.Event.prototype.propagationStopped_ = false; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used to indicate that the member or property is public. Variables and |
| properties are public by default, so this annotation is rarely necessary. |
| Should only be used in legacy code that cannot be easily changed to |
| override the visibility of members that were named as private variables. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-return">@return</a></td> |
| <td> |
| <code>@return {Type} Description</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @return {string} The hex ID of the last item. |
| */ |
| goog.Baz.prototype.getLastId = function() { |
| // ... |
| return id; |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used with method and function calls to document the return |
| type. When writing descriptions for boolean parameters, |
| prefer "Whether the component is visible" to "True if the |
| component is visible, false otherwise". If there is no return |
| value, do not use an <code>@return</code> tag.<p/> |
| |
| <a href="#JsTypes">Type</a> |
| names must be enclosed in curly braces. If the type |
| is omitted, the compiler will not type-check the return value. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-see">@see</a></td> |
| <td> |
| <code>@see Link</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * Adds a single item, recklessly. |
| * @see #addSafely |
| * @see goog.Collect |
| * @see goog.RecklessAdder#add |
| ... |
| </CODE_SNIPPET> |
| </td> |
| <td>Reference a lookup to another class function or method.</td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-struct">@struct</a></td> |
| <td> |
| <code>@struct Description</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @constructor |
| * @struct |
| */ |
| function Foo(x) { |
| this.x = x; |
| } |
| var obj = new Foo(123); |
| var num = obj['x']; // warning |
| obj.y = "asdf"; // warning |
| |
| Foo.prototype = /** @struct */ { |
| method1: function() {} |
| }; |
| Foo.prototype.method2 = function() {}; // warning |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| When a constructor (<code>Foo</code> in the example) is |
| annotated with <code>@struct</code>, you can only use the dot |
| notation to access the properties of <code>Foo</code> objects. |
| Also, you cannot add new properties to <code>Foo</code> |
| objects after they have been created. |
| The annotation can also be used directly on object literals. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-supported">@supported</a></td> |
| <td> |
| <code>@supported Description</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @fileoverview Event Manager |
| * Provides an abstracted interface to the |
| * browsers' event systems. |
| * @supported So far tested in IE6 and FF1.5 |
| */ |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Used in a fileoverview to indicate what browsers are supported |
| by the file. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-suppress">@suppress</a></td> |
| <td> |
| <code> |
| @suppress {warning1|warning2} |
| </code> |
| <code> |
| @suppress {warning1,warning2} |
| </code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @suppress {deprecated} |
| */ |
| function f() { |
| deprecatedVersionOfF(); |
| } |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Suppresses warnings from tools. Warning categories are |
| separated by <code>|</code> or <code>,</code>. |
| |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-template">@template</a></td> |
| <td> |
| <code>@template</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * @param {function(this:T, ...)} fn |
| * @param {T} thisObj |
| * @param {...*} var_args |
| * @template T |
| */ |
| goog.bind = function(fn, thisObj, var_args) { |
| ... |
| }; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| This annotation can be used to declare a |
| <a href="#Template_types">template typename</a>. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-this">@this</a></td> |
| <td> |
| <code> |
| @this Type<br/> |
| @this {Type} |
| </code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| pinto.chat.RosterWidget.extern('getRosterElement', |
| /** |
| * Returns the roster widget element. |
| * @this pinto.chat.RosterWidget |
| * @return {Element} |
| */ |
| function() { |
| return this.getWrappedComponent_().getElement(); |
| }); |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| The type of the object in whose context a particular method is |
| called. Required when the <code>this</code> keyword is referenced |
| from a function that is not a prototype method. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-type">@type</a></td> |
| <td> |
| <code> |
| @type Type<br/> |
| @type {Type} |
| </code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** |
| * The message hex ID. |
| * @type {string} |
| */ |
| var hexId = hexId; |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| Identifies the <a href="#JsTypes">type</a> of a variable, |
| property, or expression. Curly braces are not required around |
| most types, but some projects mandate them for all types, for |
| consistency. |
| </td> |
| </tr> |
| |
| <tr> |
| <td><a name="tag-typedef">@typedef</a></td> |
| <td> |
| <code>@typedef</code> |
| <p><i>For example:</i></p> |
| <CODE_SNIPPET> |
| /** @typedef {(string|number)} */ |
| goog.NumberLike; |
| |
| /** @param {goog.NumberLike} x A number or a string. */ |
| goog.readNumber = function(x) { |
| ... |
| } |
| </CODE_SNIPPET> |
| </td> |
| <td> |
| This annotation can be used to declare an alias of a more |
| <a href="#Typedefs">complex type</a>. |
| </td> |
| </tr> |
| |
| |
| |
| </tbody> |
| </table> |
| |
| |
| |
| <p> |
| You may also see other types of JSDoc annotations in third-party |
| code. These annotations appear in the |
| <a href="http://code.google.com/p/jsdoc-toolkit/wiki/TagReference"> |
| JSDoc Toolkit Tag Reference |
| </a> |
| but are currently discouraged in Google code. You should consider |
| them "reserved" names for future use. These include: |
| <ul> |
| <li>@augments</li> |
| <li>@argument</li> |
| <li>@borrows</li> |
| <li>@class</li> |
| <li>@constant</li> |
| <li>@constructs</li> |
| <li>@default</li> |
| <li>@event</li> |
| <li>@example</li> |
| <li>@field</li> |
| <li>@function</li> |
| <li>@ignore</li> |
| <li>@inner</li> |
| <li>@link</li> |
| <li>@memberOf</li> |
| <li>@name</li> |
| <li>@namespace</li> |
| <li>@property</li> |
| <li>@public</li> |
| <li>@requires</li> |
| <li>@returns</li> |
| <li>@since</li> |
| <li>@static</li> |
| <li>@version</li> |
| </ul> |
| </p> |
| </SUBSECTION> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Providing Dependencies With goog.provide"> |
| <SUMMARY> |
| Only provide top-level symbols. |
| </SUMMARY> |
| <BODY> |
| <p> |
| All members defined on a class should be in the same file. So, only |
| top-level classes should be provided in a file that contains multiple |
| members defined on the same class (e.g. enums, inner classes, etc). |
| </p> |
| <p>Do this:</p> |
| <CODE_SNIPPET> |
| goog.provide('namespace.MyClass'); |
| </CODE_SNIPPET> |
| <p>Not this:</p> |
| <BAD_CODE_SNIPPET> |
| goog.provide('namespace.MyClass'); |
| goog.provide('namespace.MyClass.Enum'); |
| goog.provide('namespace.MyClass.InnerClass'); |
| goog.provide('namespace.MyClass.TypeDef'); |
| goog.provide('namespace.MyClass.CONSTANT'); |
| goog.provide('namespace.MyClass.staticMethod'); |
| </BAD_CODE_SNIPPET> |
| <p> |
| Members on namespaces may also be provided: |
| </p> |
| <CODE_SNIPPET> |
| goog.provide('foo.bar'); |
| goog.provide('foo.bar.method'); |
| goog.provide('foo.bar.CONSTANT'); |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Compiling"> |
| <SUMMARY>Required</SUMMARY> |
| <BODY> |
| |
| |
| <p>Use of JS compilers such as the |
| <a href="http://code.google.com/closure/compiler/">Closure Compiler</a> |
| is required for all customer-facing code.</p> |
| |
| |
| |
| |
| </BODY> |
| </STYLEPOINT> |
| |
| <STYLEPOINT title="Tips and Tricks"> |
| <SUMMARY>JavaScript tidbits</SUMMARY> |
| <BODY> |
| <SUBSECTION title="True and False Boolean Expressions"> |
| <p>The following are all false in boolean expressions:</p> |
| <ul> |
| <li><code>null</code></li> |
| <li><code>undefined</code></li> |
| <li><code>''</code> the empty string</li> |
| <li><code>0</code> the number</li> |
| </ul> |
| <p>But be careful, because these are all true:</p> |
| <ul> |
| <li><code>'0'</code> the string</li> |
| <li><code>[]</code> the empty array</li> |
| <li><code>{}</code> the empty object</li> |
| </ul> |
| |
| <p>This means that instead of this:</p> |
| <BAD_CODE_SNIPPET> |
| while (x != null) { |
| </BAD_CODE_SNIPPET> |
| <p>you can write this shorter code (as long as you don't expect x to |
| be 0, or the empty string, or false):</p> |
| <CODE_SNIPPET> |
| while (x) { |
| </CODE_SNIPPET> |
| |
| <p>And if you want to check a string to see if it is null or empty, |
| you could do this:</p> |
| <BAD_CODE_SNIPPET> |
| if (y != null && y != '') { |
| </BAD_CODE_SNIPPET> |
| <p>But this is shorter and nicer:</p> |
| <CODE_SNIPPET> |
| if (y) { |
| </CODE_SNIPPET> |
| |
| <p><strong>Caution:</strong> There are many unintuitive things about |
| boolean expressions. Here are some of them:</p> |
| <ul> |
| <li><code> |
| Boolean('0') == true<br/> |
| '0' != true</code></li> |
| <li><code> |
| 0 != null<br/> |
| 0 == []<br/> |
| 0 == false</code></li> |
| <li><code> |
| Boolean(null) == false<br/> |
| null != true<br/> |
| null != false</code></li> |
| <li><code> |
| Boolean(undefined) == false<br/> |
| undefined != true<br/> |
| undefined != false</code></li> |
| <li><code> |
| Boolean([]) == true<br/> |
| [] != true<br/> |
| [] == false</code></li> |
| <li><code> |
| Boolean({}) == true<br/> |
| {} != true<br/> |
| {} != false</code></li> |
| </ul> |
| </SUBSECTION> |
| |
| <SUBSECTION title="Conditional (Ternary) Operator (?:)"> |
| <p>Instead of this:</p> |
| <CODE_SNIPPET> |
| if (val) { |
| return foo(); |
| } else { |
| return bar(); |
| } |
| </CODE_SNIPPET> |
| <p>you can write this:</p> |
| <CODE_SNIPPET> |
| return val ? foo() : bar(); |
| </CODE_SNIPPET> |
| |
| <p>The ternary conditional is also useful when generating HTML:</p> |
| <CODE_SNIPPET> |
| var html = '<input type="checkbox"' + |
| (isChecked ? ' checked' : '') + |
| (isEnabled ? '' : ' disabled') + |
| ' name="foo">'; |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="&& and ||"> |
| <p>These binary boolean operators are short-circuited, and evaluate |
| to the last evaluated term.</p> |
| |
| <p>"||" has been called the 'default' operator, because instead of |
| writing this:</p> |
| <BAD_CODE_SNIPPET> |
| /** @param {*=} opt_win */ |
| function foo(opt_win) { |
| var win; |
| if (opt_win) { |
| win = opt_win; |
| } else { |
| win = window; |
| } |
| // ... |
| } |
| </BAD_CODE_SNIPPET> |
| <p>you can write this:</p> |
| <CODE_SNIPPET> |
| /** @param {*=} opt_win */ |
| function foo(opt_win) { |
| var win = opt_win || window; |
| // ... |
| } |
| </CODE_SNIPPET> |
| |
| <p>"&&" is also useful for shortening code. For instance, |
| instead of this:</p> |
| <BAD_CODE_SNIPPET> |
| if (node) { |
| if (node.kids) { |
| if (node.kids[index]) { |
| foo(node.kids[index]); |
| } |
| } |
| } |
| </BAD_CODE_SNIPPET> |
| |
| <p>you could do this:</p> |
| <CODE_SNIPPET> |
| if (node && node.kids && node.kids[index]) { |
| foo(node.kids[index]); |
| } |
| </CODE_SNIPPET> |
| |
| <p>or this:</p> |
| <CODE_SNIPPET> |
| var kid = node && node.kids && node.kids[index]; |
| if (kid) { |
| foo(kid); |
| } |
| </CODE_SNIPPET> |
| |
| <p>However, this is going a little too far:</p> |
| <BAD_CODE_SNIPPET> |
| node && node.kids && node.kids[index] && foo(node.kids[index]); |
| </BAD_CODE_SNIPPET> |
| </SUBSECTION> |
| |
| <SUBSECTION title="Iterating over Node Lists"> |
| <p>Node lists are often implemented as node iterators with a filter. |
| This means that getting a property like length is O(n), and |
| iterating over the list by re-checking the length will be |
| O(n^2).</p> |
| <BAD_CODE_SNIPPET> |
| var paragraphs = document.getElementsByTagName('p'); |
| for (var i = 0; i < paragraphs.length; i++) { |
| doSomething(paragraphs[i]); |
| } |
| </BAD_CODE_SNIPPET> |
| |
| <p>It is better to do this instead:</p> |
| <CODE_SNIPPET> |
| var paragraphs = document.getElementsByTagName('p'); |
| for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) { |
| doSomething(paragraph); |
| } |
| </CODE_SNIPPET> |
| |
| <p>This works well for all collections and arrays as long as the array |
| does not contain things that are treated as boolean false.</p> |
| |
| <p>In cases where you are iterating over the childNodes you can also |
| use the firstChild and nextSibling properties.</p> |
| <CODE_SNIPPET> |
| var parentNode = document.getElementById('foo'); |
| for (var child = parentNode.firstChild; child; child = child.nextSibling) { |
| doSomething(child); |
| } |
| </CODE_SNIPPET> |
| </SUBSECTION> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| |
| |
| |
| <PARTING_WORDS> |
| <p> |
| <em>BE CONSISTENT</em>. |
| </p> |
| |
| <p> |
| If you're editing code, take a few minutes to look at the code |
| around you and determine its style. If they use spaces around |
| all their arithmetic operators, you should too. If their |
| comments have little boxes of hash marks around them, make your |
| comments have little boxes of hash marks around them too. |
| </p> |
| |
| <p> |
| The point of having style guidelines is to have a common vocabulary |
| of coding so people can concentrate on what you're saying rather |
| than on how you're saying it. We present global style rules here so |
| people know the vocabulary, but local style is also important. If |
| code you add to a file looks drastically different from the existing |
| code around it, it throws readers out of their rhythm when they go to |
| read it. Avoid this. |
| </p> |
| |
| </PARTING_WORDS> |
| |
| <p align="right"> |
| Revision 2.93 |
| </p> |
| |
| |
| <address> |
| Aaron Whyte<br/> |
| Bob Jervis<br/> |
| Dan Pupius<br/> |
| Erik Arvidsson<br/> |
| Fritz Schneider<br/> |
| Robby Walker<br/> |
| </address> |
| </GUIDE> |