diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e446061 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,18 @@ +on: + push: + branches: + - master + +name: Release + +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - uses: GoogleCloudPlatform/release-please-action@v3 + id: release + with: + token: ${{ secrets.RELEASE_TOKEN }} + release-type: node + package-name: posture + changelog-types: '[{"type": "types", "section":"Types", "hidden": false},{"type": "revert", "section":"Reverts", "hidden": false},{"type": "feat", "section": "Features", "hidden": false},{"type": "fix", "section": "Bug Fixes", "hidden": false},{"type": "improvement", "section": "Feature Improvements", "hidden": false},{"type": "docs", "section":"Docs", "hidden": false},{"type": "style", "section":"Styling", "hidden": false},{"type": "refactor", "section":"Code Refactoring", "hidden": false},{"type": "perf", "section":"Performance Improvements", "hidden": false},{"type": "test", "section":"Tests", "hidden": false},{"type": "build", "section":"Build System", "hidden": false},{"type": "ci", "section":"CI", "hidden":false}]' diff --git a/README.md b/README.md index 2089cce..5e094b5 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,12 @@
- - + + - - + +
+ Please note: there's a newer version of this guide that includes + ECMAScript 6th Edition features. It lives here. + You should probably be using that for new code. + + Revision 2.93 +
+ + + Aaron Whyte+ Hooray! Now you know you can expand points to get more + details. Alternatively, there's a "toggle all" at the + top of this document. +
+ ++ JavaScript is the main client-side scripting language used + + by many of Google's open-source + projects. + This style guide is a list of dos and don'ts for + JavaScript programs. +
+ + + + + +var
: Always
+ var
,
+ 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
+ var
.
+ NAMES_LIKE_THIS
for constant values.@const
to indicate a constant (non-overwritable)
+ pointer (a variable or property).const
keyword
+ as it's not supported in Internet Explorer.If a value is intended to be constant
+ and immutable, it should be given a name
+ in CONSTANT_VALUE_CASE
.
+ ALL_CAPS
additionally implies @const
+ (that the value is not overwritable).
+
Primitive types (number
, string
,
+ boolean
) are constant values.
Objects
'
+ 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.
The @const
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
+
+ const
keyword (which we do not use due to the
+ lack of support in Internet Explorer).
A @const
annotation on a method additionally
+ implies that the method cannot not be overridden in subclasses.
+
A @const
annotation on a constructor implies the
+ class cannot be subclassed (akin to final
in Java).
+
Note that @const
does not necessarily imply
+ CONSTANT_VALUES_CASE
.
+
+ However, CONSTANT_VALUES_CASE
+ does imply @const
.
+
The number of seconds in a minute never changes. It is a
+ constant value. ALL_CAPS
+ also implies @const
, so the constant cannot be
+ overwritten.
+
The open source compiler will allow the symbol to be
+ overwritten because the constant is
+ not marked as @const
.
In this case, the pointer can never be overwritten, but
+ value is highly mutable and not constant (and thus in
+ camelCase
, not ALL_CAPS
).
Relying on implicit insertion can cause subtle, hard to debug + problems. Don't do it. You're better than that.
+There are a couple places where missing semicolons are particularly + dangerous:
+x[ffVersion, ieVersion][isIE]()
.die
is always called since the array minus 1 is
+ NaN
which is never equal to anything (not even if
+ resultOfOperation()
returns NaN
) and
+ THINGS_TO_EAT
gets assigned the result of
+ die()
.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.
+This has really surprised people, so make sure your assignments end + with semicolons.
+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:
+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.
+ +Do not do this:
+While most script engines support Function Declarations within blocks + it is not part of ECMAScript (see + ECMA-262, + 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:
+You basically can't avoid exceptions if you're doing something + non-trivial (using an application development framework, etc.). + Go for it.
+ +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.
+ +For maximum portability and compatibility, always prefer standards
+ features over non-standards features (e.g.,
+ string.charAt(3)
over string[3]
and element
+ access with DOM functions instead of using an application-specific
+ shorthand).
There's no reason to use wrapper objects for primitive types, plus + they're dangerous:
+Don't do it!
+However type casting is fine.
+This is very useful for casting things to
+ number
, string
and boolean
.
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!
+ +For that reason, it is best to use goog.inherits()
from
+
+ the Closure Library
+
+ or a similar library function.
+
/** @constructor */
+ function SomeConstructor() {
+ this.someProperty = 1;
+ }
+ Foo.prototype.someMethod = function() { ... };
While there are several ways to attach methods and properties to an + object created via "new", the preferred style for methods + is:
+The preferred style for other properties is to initialize the field + in the constructor:
+Current JavaScript engines optimize based on the "shape" + of an object, + adding a property to an object (including overriding + a value set on the prototype) changes the shape and can degrade + performance.
+this.foo = null
.Instead of:
+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
+ if (key in obj)
.
The ability to create closures is perhaps the most useful and often + overlooked feature of JS. Here is + + a good description of how closures work.
+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:
+the function closure keeps a reference to element
,
+ a
, and b
even if it never uses
+ element
. Since element
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:
eval()
makes for confusing semantics and is dangerous
+ to use if the string being eval()
'd contains user input.
+ There's usually a better, clearer, and safer way to write your code,
+ so its use is generally not permitted.
For RPC you can always use JSON and read the result using
+ JSON.parse()
instead of eval()
.
Let's assume we have a server that returns something like this:
+ +If the feed was modified to include malicious JavaScript code, then
+ if we use eval
then that code will be executed.
With JSON.parse
, invalid JSON (including all executable
+ JavaScript) will cause an exception to be thrown.
Using with
clouds the semantics of your program.
+ Because the object of the with
can have properties that
+ collide with local variables, it can drastically change the meaning
+ of your program. For example, what does this do?
Answer: anything. The local variable x
could be
+ clobbered by a property of foo
and perhaps it even has
+ a setter, in which case assigning 3
could cause lots of
+ other code to execute. Don't use with
.
The semantics of this
can be tricky. At times it refers
+ to the global object (in most places), the scope of the caller (in
+ eval
), 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
+ call()
ed or apply()
ed).
Because this is so easy to get wrong, limit its use to those places + where it is required:
+for-in
loops are often incorrectly used to loop over
+ the elements in an Array
. This is however very error
+ prone because it does not loop from 0
to
+ length - 1
but over all the present keys in the object
+ and its prototype chain. Here are a few cases where it fails:
Always use normal for loops when using arrays.
+Array
as a map/hash/associative array
+ Associative Array
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 Object
instead of Array
in
+ these cases because the features that you want are actually features
+ of Object
and not of Array
.
+ Array
just happens to extend Object
(like
+ any other object in JS and therefore you might as well have used
+ Date
, RegExp
or String
).
Do not do this:
+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.
+Use string concatenation instead:
+Use Array
and Object
literals instead of
+ Array
and Object
constructors.
Array constructors are error-prone due to their arguments.
+Because of this, if someone changes the code to pass 1 argument + instead of 2 arguments, the array might not have the expected + length.
+To avoid these kinds of weird cases, always use the more readable + array literal.
+Object constructors don't have the same problems, but for readability + and consistency object literals should be used.
+Should be written as:
+Modifying builtins like Object.prototype
and
+ Array.prototype
are strictly forbidden. Modifying other
+ builtins like Function.prototype
is less dangerous but
+ still leads to hard to debug issues in production and should be
+ avoided.
Don't do this:
+Conditional Comments hinder automated tools as they can vary the + JavaScript syntax tree at runtime.
+ +In general, use
+ functionNamesLikeThis
,
+ variableNamesLikeThis
,
+ ClassNamesLikeThis
,
+ EnumNamesLikeThis
,
+ methodNamesLikeThis
,
+ CONSTANT_VALUES_LIKE_THIS
,
+ foo.namespaceNamesLikeThis.bar
, and
+ filenameslikethis.js
.
+
For more information on private and protected, + read the section on + + visibility. +
+ + + + +Optional function arguments start with opt_
.
Functions that take a variable number of arguments should have the
+ last argument named var_args
. You may not refer to
+ var_args
in the code; use the arguments
+ array.
Optional and variable arguments can also be specified in
+ @param
annotations. Although either convention is
+ acceptable to the compiler, using both together is preferred.
EcmaScript 5 getters and setters for properties are discouraged. + However, if they are used, then getters must not change observable + state.
+Getters and setters methods for properties are not required.
+ However, if they are used, then getters must be named
+ getFoo()
and setters must be named
+ setFoo(value)
. (For boolean getters,
+ isFoo()
is also acceptable, and often sounds more
+ natural.)
JavaScript has no inherent packaging or namespacing support.
+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.
+ALWAYS 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 sloth.*
.
Many JavaScript libraries, including + + the Closure Library + + and + + Dojo toolkit + + give you high-level functions for declaring your namespaces. + Be consistent about how you declare your namespaces.
+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 sloth.hats
.
"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 foo.hats.*
, your
+ internal code should not define all its symbols in
+ foo.hats.*
, because it will break if the other
+ team defines new symbols.
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.
+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.
+Do not create local aliases of namespaces. Namespaces should only + be aliased using goog.scope.
+Avoid accessing properties of an aliased type, unless it is an + enum.
+Never create aliases in the global scope. Use them only in + function blocks.
+Filenames should be all lowercase in order to avoid confusion on
+ case-sensitive platforms. Filenames should end in .js
,
+ and should contain no punctuation except for -
or
+ _
(prefer -
to _
).
You can control how your objects string-ify themselves by defining a
+ custom toString()
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
+ toString()
calls a method that does an
+ assert
, assert
might try to output the name
+ of the object in which it failed, which of course requires calling
+ toString()
.
It isn't always possible to initialize variables at the point of + declaration, so deferred initialization is fine.
+ +Always use explicit scope - doing so increases portability and
+ clarity. For example, don't rely on window
being in the
+ scope chain. You might want to use your function in another
+ application for which window
is not the content
+ window.
We follow the C++ formatting + rules in spirit, with the following additional clarifications.
+Because of implicit semicolon insertion, always start your curly + braces on the same line as whatever they're opening. For + example:
+Single-line array and object initializers are allowed when they + fit on a line:
+Multiline array initializers and object initializers are indented + 2 spaces, with the braces on their own line, just like blocks.
+Long identifiers or values present problems for aligned + initialization lists, so always prefer non-aligned initialization. + For example:
+Not like this:
+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:
+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.
+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).
+
+ goog.scope
+ may be used to shorten references to
+ namespaced symbols in programs using
+ the Closure
+ Library.
Only one goog.scope
invocation may be added per
+ file. Always place it in the global scope.
The opening goog.scope(function() {
invocation
+ must be preceded by exactly one blank line and follow any
+ goog.provide
statements, goog.require
+ statements, or top-level comments. The invocation must be closed on
+ the last line in the file. Append // goog.scope
to the
+ closing statement of the scope. Separate the comment from the
+ semicolon by two spaces.
Similar to C++ namespaces, do not indent under goog.scope + declarations. Instead, continue from the 0 column.
+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):
+ +Names must be the same as the last property of the global that they + are aliasing.
+ +Except for array literals, + object literals, 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). +
+ +Use newlines to group logically related pieces of code. + For example:
+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.
+This includes the dot operator.
+Use sparingly and in general only where required by the syntax + and semantics.
+Never use parentheses for unary operators such as
+ delete
, typeof
and void
or
+ after keywords such as return
, throw
as
+ well as others (case
, in
or
+ new
).
For consistency single-quotes (') are preferred to double-quotes ("). + This is helpful when creating strings that include HTML:
+@private
and
+ @protected
We recommend the use of the JSDoc annotations @private
and
+ @protected
to indicate visibility levels for classes,
+ functions, and properties.
The --jscomp_warning=visibility compiler flag turns on compiler + warnings for visibility violations. See + + Closure Compiler + Warnings. +
+@private
global variables and functions are only
+ accessible to code in the same file.
Constructors marked @private
may only be instantiated by
+ code in the same file and by their static and instance members.
+ @private
constructors may also be accessed anywhere in the
+ same file for their public static properties and by the
+ instanceof
operator.
Global variables, functions, and constructors should never be
+ annotated @protected
.
@private
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.
@protected
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.
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. +
+Notice that in JavaScript, there is no distinction between a type
+ (like AA_PrivateClass_
) 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).
When documenting a type in JSDoc, be as specific and accurate as + possible. The types we support are based on the + + EcmaScript 4 spec.
+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.
+ +As the ES4 proposal has evolved, this language has changed. The + compiler still supports old syntaxes for types, but those syntaxes + are deprecated.
+ + +Syntax Name | +Syntax | +Description | +Deprecated Syntaxes | +
---|---|---|---|
Primitive Type | +
+ There are 5 primitive types in JavaScript:
+ {null} ,
+ {undefined} ,
+ {boolean} ,
+ {number} , and
+ {string} .
+ |
+ Simply the name of a type. | ++ |
Instance Type | +
+ {Object} + An instance of Object or null. + {Function} + An instance of Function or null. + {EventTarget} + An instance of a constructor that implements the EventTarget + interface, or null. + |
+ An instance of a constructor or interface function.
+
+ Constructor functions are functions defined with the
+ @constructor JSDoc tag.
+ Interface functions are functions defined with the
+ @interface JSDoc tag.
+
+ 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.
+ |
+ + |
Enum Type | +
+ {goog.events.EventType} + One of the properties of the object literal initializer + of goog.events.EventType .
+ |
+ An enum must be initialized as an object literal, or as
+ an alias of another enum, annotated with the @enum
+ JSDoc tag. The properties of this literal are the instances
+ of the enum. The syntax of the enum is defined
+ below.
+
+ Note that this is one of the few things in our type system
+ that were not in the ES4 spec.
+ |
+ + |
Type Application | +
+ {Array.<string>} An array of strings. + {Object.<string, number>}
+ An object in which the keys are strings and the values + are numbers. + |
+ Parameterizes a type, by applying a set of type arguments + to that type. The idea is analogous to generics in Java. + | ++ |
Type Union | +
+ {(number|boolean)} A number or a boolean. + |
+ Indicates that a value might have type A OR type B.
+
+ The parentheses may be omitted at the top-level
+ expression, but the parentheses should be included in
+ sub-expressions to avoid ambiguity. + {number|boolean} + {function(): (number|boolean)}
+ |
+
+ {(number,boolean)} ,+ {(number||boolean)}
+ |
+
Nullable type | +
+ {?number} A number or null. + |
+ Shorthand for the union of the null type with any + other type. This is just syntactic sugar. + | +
+ {number?}
+ |
+
Non-nullable type | +
+ {!Object} An Object, but never the + null value.
+ |
+ Filters null out of nullable types. Most often used + with instance types, which are nullable by default. + | +
+ {Object!}
+ |
+
Record Type | +
+ {{myNum: number, myObject}}
+ An anonymous type with the given type members. + |
+
+ Indicates that the value has the specified members with the
+ specified types. In this case, Notice that the braces are part of the type syntax. For
+ example, to denote an |
+ + |
Function Type | +
+ {function(string, boolean)} + A function that takes two arguments (a string and a boolean), + and has an unknown return value. + |
+ Specifies a function. | ++ |
Function Return Type | +
+ {function(): number} + A function that takes no arguments and returns a number. + |
+ Specifies a function return type. | ++ |
Function this Type |
+
+ {function(this:goog.ui.Menu, string)} + A function that takes one argument (a string), and executes + in the context of a goog.ui.Menu. + |
+ Specifies the context type of a function type. | ++ |
Function new Type |
+
+ {function(new:goog.ui.Menu, string)} + A constructor that takes one argument (a string), and + creates a new instance of goog.ui.Menu when called + with the 'new' keyword. + |
+ Specifies the constructed type of a constructor. | ++ |
Variable arguments | +
+ {function(string, ...[number]): number} + A function that takes one argument (a string), and then a + variable number of arguments that must be numbers. + |
+ Specifies variable arguments to a function. | ++ |
+
+ Variable arguments (in @param annotations)
+ |
+
+ @param {...number} var_args + A variable number of arguments to an annotated function. + |
+ + Specifies that the annotated function accepts a variable + number of arguments. + | ++ |
Function optional arguments | +
+ {function(?string=, number=)} + A function that takes one optional, nullable string and one + optional number as arguments. The = syntax is
+ only for function type declarations.
+ |
+ Specifies optional arguments to a function. | ++ |
+
+ Function optional arguments
+ (in @param annotations)
+ |
+
+ @param {number=} opt_argument + An optional parameter of type number .
+ |
+ Specifies that the annotated function accepts an optional + argument. | ++ |
The ALL type | +{*} |
+ Indicates that the variable can take on any type. | ++ |
The UNKNOWN type | +{?} |
+ Indicates that the variable can take on any type, + and the compiler should not type-check any uses of it. | ++ |
Type Example | +Value Examples | +Description | +
---|---|---|
number | +
+ |
+ + |
Number | +
+ |
+ + + Number object + + | +
string | +
+ |
+ + String value + | +
String | +
+ |
+ + + String object + + | +
boolean | +
+ |
+ + Boolean value + | +
Boolean | +
+ |
+ + + Boolean object + + | +
RegExp | +
+ | + | +
Date | +
+ |
+ + |
+ + null + + | +
+ |
+ + |
+ + undefined + + | +
+ |
+ + |
void | +
+ |
+ No return value | +
Array | +
+ |
+ Untyped Array | +
Array.<number> | +
+ |
+ + An Array of numbers + | +
Array.<Array.<string>> | +
+ |
+ Array of Arrays of strings | +
Object | +
+ |
+ + |
Object.<string> | +
+ |
+ + An Object in which the values are strings. + | +
Object.<number, string> | +
+ |
+
+ An Object in which the keys are numbers and the values are
+ strings. Note that in JavaScript, the keys are always
+ implicitly converted to strings, so
+ obj['1'] == obj[1] .
+ 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.
+ |
+
Function | +
+ |
+ + + Function object + + | +
function(number, number): number | +
+ |
+ function value | +
SomeClass | +
+ |
+ + |
SomeInterface | +
+ |
+ + |
project.MyClass | +
+ |
+ + |
project.MyEnum | +
+ |
+ Enumeration + JSDoc comments on enum values are optional. + | +
Element | +
+ |
+ Elements in the DOM. | +
Node | +
+ |
+ Nodes in the DOM. | +
HTMLInputElement | +
+ |
+ A specific type of DOM element. | +
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.
+ +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.
+ +Instances of classes and interfaces are nullable by default. + For example, the following declaration
+ +tells the compiler that the myValue_
property holds
+ either an Object or null. If myValue_
must never be
+ null, it should be declared like this:
This way, if the compiler can determine that somewhere in the code
+ MyClass
is initialized with a null value, it will issue
+ a warning.
Optional parameters to functions may be undefined at runtime, so if + they are assigned to class properties, those properties must be + declared accordingly:
+ +This tells the compiler that myValue_
may hold an
+ Object, null, or remain undefined.
Note that the optional parameter opt_value
is declared
+ to be of type {Object=}
, not
+ {Object|undefined}
. 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.
Finally, note that being nullable and being optional are orthogonal + properties. The following four declarations are all different:
+ +Sometimes types can get complicated. A function that accepts + content for an Element might look like:
+ +You can define commonly used type expressions with a
+ @typedef
tag. For example,
The compiler has limited support for template types. It can only
+ infer the type of this
inside an anonymous function
+ literal from the type of the this
argument and whether the
+ this
argument is missing.
+ We follow the + + C++ style for comments in spirit. +
+ +All files, classes, methods and properties should be documented with + JSDoc + comments with the appropriate tags + and types. Textual descriptions for properties, + methods, method parameters and method return values should be included + unless obvious from the property, method, or parameter name. +
+ +Inline comments should be of the //
variety.
Complete sentences are recommended but not required. + Complete sentences should use appropriate capitalization + and punctuation.
+ +The JSDoc syntax is based on + + JavaDoc. Many tools extract metadata from JSDoc comments to + perform code validation and optimizations. These comments must be + well-formed.
+ +If you have to line break a block tag, you should treat this as + breaking a code statement and indent it four spaces.
+ +You should not indent the @fileoverview
command. You do not have to
+ indent the @desc
command.
Even though it is not preferred, it is also acceptable to line up + the description.
+ +Like JavaDoc, JSDoc supports many HTML tags, like <code>, + <pre>, <tt>, <strong>, <ul>, <ol>, + <li>, <a>, and others.
+ +This means that plaintext formatting is not respected. So, don't + rely on whitespace to format JSDoc:
+ +It'll come out like this:
+ +Instead, do this:
+ ++ + A copyright notice 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: +
+ +Classes must be documented with a description and a + type tag that + identifies the constructor. +
+ +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.
+Tag | +Template & Examples | +Description | +
---|---|---|
+ @author + + | +
+ @author username@google.com (first last)
+ For example: + |
+
+ Document the author of a file or the owner of a test,
+ generally only used in the @fileoverview comment.
+
+ |
+
@code | +
+ {@code ...}
+ For example: + |
+ + Indicates that a term in a JSDoc description is code so it may + be correctly formatted in generated documentation. + | +
@const | +
+ @const + @const {type}
+ For example: + |
+
+ Marks a variable (or property) as read-only and suitable + for inlining. + +A The type declaration of a constant value can be omitted + if it can be clearly inferred. An additional comment about + the variable is optional. + +When For more on |
+
@constructor | +
+ @constructor
+ For example: + |
+ + Used in a class's documentation to indicate the constructor. + | +
@define | +
+ @define {Type} description
+ For example: + |
+
+ Indicates a constant that can be overridden by the compiler at
+ compile-time. In the example, the compiler flag
+ --define='goog.userAgent.ASSUME_IE=true'
+ could be specified in the BUILD file to indicate that the
+ constant goog.userAgent.ASSUME_IE should be replaced
+ with true .
+ |
+
@deprecated | +
+ @deprecated Description
+ For example: + |
+ + Used to tell that a function, method or property should not be + used any more. Always provide instructions on what callers + should use instead. + | +
@dict | +
+ @dict Description
+ For example: + |
+
+ When a constructor (Foo in the example) is
+ annotated with @dict , you can only use the
+ bracket notation to access the properties of Foo
+ objects.
+ The annotation can also be used directly on object literals.
+ |
+
@enum | +
+ @enum {Type}
+ For example: + |
+ |
@export | +
+ @export
+ For example: + |
+
+ Given the code on the left, when the compiler is run with
+ the which will export the symbols to uncompiled code.
+ Code that uses the
|
+
@expose | +
+ @expose
+ For example: + |
+
+ + 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. + + +
+ |
+
@extends | +
+
+ @extends Type
+ For example: + |
+
+ Used with @constructor to indicate that a class
+ inherits from another class. Curly braces around the type are
+ optional.
+ |
+
@externs | +
+ @externs
+ For example: + |
+
+ + Declares an + + externs file. + + + + |
+
@fileoverview | +
+ @fileoverview Description
+ For example: + |
+ Makes the comment block provide file level information. | +
@implements | +
+
+ @implements Type
+ For example: + |
+
+ Used with @constructor to indicate that a class
+ implements an interface. Curly braces around the type are
+ optional.
+ |
+
@inheritDoc | +
+ @inheritDoc
+ For example: + |
+
+ Deprecated. Use
+ @inheritDoc implies @override
+ |
+
@interface | +
+ @interface
+ For example: + |
+ + Used to indicate that the function defines an interface. + | +
@lends | +
+ @lends objectName + @lends {objectName}
+ For example: + |
+
+ 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.
+
+ 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, @type {Foo} means "an instance of Foo",
+ but @lends {Foo} means "the constructor Foo".
+
+ The
+ JSDoc Toolkit docs have more information on this
+ annotation.
+ |
+
@license or + @preserve | +
+ @license Description
+ For example: + |
+
+ Anything marked by @license or
+ @preserve 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.
+ |
+
@noalias | +
+ @noalias
+ For example: + |
+ + 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. + | +
@nocompile | +
+ @nocompile
+ For example: + |
+ + 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. + | +
@nosideeffects | +
+ @nosideeffects
+ For example: + |
+ + 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. + | +
@override | +
+ @override
+ For example: + |
+ + 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. + | +
@param | +
+ @param {Type} varname Description
+ For example: + |
+ + Used with method, function and constructor calls to document + the arguments of a function. + + Type + names must be enclosed in curly braces. If the type + is omitted, the compiler will not type-check the parameter. + | +
@private | +
+ @private + @private {type}
+ For example: + |
+ + Used in conjunction with a trailing underscore on the method + or property name to indicate that the member is + private and final. + | +
@protected | +
+ @protected + @protected {type}
+ For example: + |
+ + Used to indicate that the member or property is + protected. + Should be used in conjunction with names with no trailing + underscore. + | +
@public | +
+ @public + @public {type}
+ For example: + |
+ + 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. + | +
@return | +
+ @return {Type} Description
+ For example: + |
+
+ 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 @return tag.
+
+ Type
+ names must be enclosed in curly braces. If the type
+ is omitted, the compiler will not type-check the return value.
+ |
+
@see | +
+ @see Link
+ For example: + |
+ Reference a lookup to another class function or method. | +
@struct | +
+ @struct Description
+ For example: + |
+
+ When a constructor (Foo in the example) is
+ annotated with @struct , you can only use the dot
+ notation to access the properties of Foo objects.
+ Also, you cannot add new properties to Foo
+ objects after they have been created.
+ The annotation can also be used directly on object literals.
+ |
+
@supported | +
+ @supported Description
+ For example: + |
+ + Used in a fileoverview to indicate what browsers are supported + by the file. + | +
@suppress | +
+
+ @suppress {warning1|warning2}
+
+
+ @suppress {warning1,warning2}
+
+ For example: + |
+
+ Suppresses warnings from tools. Warning categories are
+ separated by | or , .
+
+ |
+
@template | +
+ @template
+ For example: + |
+ + This annotation can be used to declare a + template typename. + | +
@this | +
+
+ @this Type
+ For example: + |
+
+ The type of the object in whose context a particular method is
+ called. Required when the this keyword is referenced
+ from a function that is not a prototype method.
+ |
+
@type | +
+
+ @type Type
+ For example: + |
+ + Identifies the type of a variable, + property, or expression. Curly braces are not required around + most types, but some projects mandate them for all types, for + consistency. + | +
@typedef | +
+ @typedef
+ For example: + |
+ + This annotation can be used to declare an alias of a more + complex type. + | +
+ You may also see other types of JSDoc annotations in third-party + code. These annotations appear in the + + JSDoc Toolkit Tag Reference + + but are currently discouraged in Google code. You should consider + them "reserved" names for future use. These include: +
+ 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). +
+Do this:
+Not this:
++ Members on namespaces may also be provided: +
+Use of JS compilers such as the + Closure Compiler + is required for all customer-facing code.
+ + + + + +The following are all false in boolean expressions:
+null
undefined
''
the empty string0
the numberBut be careful, because these are all true:
+'0'
the string[]
the empty array{}
the empty objectThis means that instead of this:
+you can write this shorter code (as long as you don't expect x to + be 0, or the empty string, or false):
+And if you want to check a string to see if it is null or empty, + you could do this:
+But this is shorter and nicer:
+Caution: There are many unintuitive things about + boolean expressions. Here are some of them:
+
+ Boolean('0') == true
+ '0' != true
+ 0 != null
+ 0 == []
+ 0 == false
+ Boolean(null) == false
+ null != true
+ null != false
+ Boolean(undefined) == false
+ undefined != true
+ undefined != false
+ Boolean([]) == true
+ [] != true
+ [] == false
+ Boolean({}) == true
+ {} != true
+ {} != false
Instead of this:
+you can write this:
+The ternary conditional is also useful when generating HTML:
+These binary boolean operators are short-circuited, and evaluate + to the last evaluated term.
+ +"||" has been called the 'default' operator, because instead of + writing this:
+you can write this:
+"&&" is also useful for shortening code. For instance, + instead of this:
+you could do this:
+or this:
+However, this is going a little too far:
+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).
+It is better to do this instead:
+This works well for all collections and arrays as long as the array + does not contain things that are treated as boolean false.
+ +In cases where you are iterating over the childNodes you can also + use the firstChild and nextSibling properties.
++ BE CONSISTENT. +
+ ++ 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. +
+ ++ 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. +
+ ++ Revision 2.93 +
+ + + + Aaron Whyte