9.4.1 Overview

    • Use of declarations is allowed
    • Use of arguments is allowed
    • Optional parameters without default values are allowed

    9.4.2 Use var

    9.4.2.1 var declarations are NOT block-scoped

    var declarations are scoped to the beginning of the nearest enclosingfunction, script or module, which can cause unexpected behavior, especially withfunction closures that reference var declarations inside of loops. Thefollowing code gives an example:

    9.4.2.2 Declare variables as close as possible to first use

    Even though var declarations are scoped to the beginning of the enclosingfunction, var declarations should be as close as possible to their first use,for readability purposes. However, do not put a var declaration inside a blockif that variable is referenced outside the block. For example:

    1. function sillyFunction() {
    2. for (var x in y) {
    3. // "count" could be declared here, but don't do that.
    4. count++;
    5. }
    6. console.log(count + ' items in y');
    7. }
    9.4.2.3 Use @const for constants variables

    For global declarations where the const keyword would be used, if it wereavailable, annotate the var declaration with @const instead (this is optionalfor local variables).

    9.4.3 Do not use block scoped functions declarations

    Do not do this:

    1. if (x) {
    2. function foo() {}
    3. }

    While most JavaScript VMs implemented before ECMAScript 6 support functiondeclarations within blocks it was not standardized. Implementations wereinconsistent with each other and with the now-standard ECMAScript 6 behavior forblock scoped function declaration. ECMAScript 5 and prior only allow forfunction declarations in the root statement list of a script or function andexplicitly ban them in block scopes in strict mode.

    To get consistent behavior, instead use a var initialized with a functionexpression to define a function within a block:

    9.4.4 Dependency management with goog.provide/goog.require

    9.4.4.1 Summary

    WARNING: goog.provide dependency management is deprecated. All new files,even in projects using goog.provide for older files, should use. The following rules are forpre-existing files only.

    • Place all goog.provides first, goog.requires second. Separate providesfrom requires with an empty line.
    • Sort the entries alphabetically (uppercase first).
    • Don't wrap goog.provide and goog.require statements. Exceed 80 columnsif necessary.
    • Only provide top-level symbols.

    Similar to import statements in other languages, goog.provide andgoog.require statements should be written in a single line, even if theyexceed the 80 column line length limit.

    The lines should be sorted alphabetically, with uppercase letters coming first:

    1. goog.provide('namespace.MyClass');
    2. goog.require('an.extremelyLongNamespace.thatSomeoneThought.wouldBeNice.andNowItIsLonger.Than80Columns');
    3. goog.require('goog.dom');
    4. goog.require('goog.dom.TagName');
    5. goog.require('goog.dom.classes');
    6. goog.require('goog.dominoes');

    All members defined on a class should be in the same file. Only top-levelclasses should be provided in a file that contains multiple members defined onthe same class (e.g. enums, inner classes, etc).

    Do this:

    1. goog.provide('namespace.MyClass');

    Not this:

    Members on namespaces may also be provided:

    1. goog.provide('foo.bar');
    2. goog.provide('foo.bar.CONSTANT');
    3. goog.provide('foo.bar.method');
    9.4.4.2 Aliasing with goog.scope

    WARNING: goog.scope is deprecated. New files should not use goog.scopeeven in projects with existing usage.

    Only one goog.scope invocation may be added per file. Always place it inthe global scope.

    The opening goog.scope(function() { invocation must be preceded by exactly oneblank line and follow any goog.provide statements, goog.require statements,or top-level comments. The invocation must be closed on the last line in thefile. Append // goog.scope to the closing statement of the scope. Separate thecomment from the semicolon by two spaces.

    Similar to C++ namespaces, do not indent under goog.scope declarations.Instead, continue from the 0 column.

    Only make aliases for names that will not be re-assigned to another object(e.g., most constructors, enums, and namespaces). Do not do this (see below forhow to alias a constructor):

    1. goog.scope(function() {
    2. var Button = goog.ui.Button;
    3. ...

    Names must be the same as the last property of the global that they are aliasing.

    9.4.4.3 goog.forwardDeclare

    Prefer to use goog.requireType instead of goog.forwardDeclare to breakcircular dependencies between files in the same library. Unlike goog.require,a goog.requireType statement is allowed to import a namespace before it isdefined.

    goog.forwardDeclare may still be used in legacy code to break circularreferences spanning across library boundaries, but newer code should bestructured to avoid it.