Lỗi javascript cho người mới bắt đầu

Tài liệu này đóng vai trò là định nghĩa đầy đủ về các tiêu chuẩn viết mã của Google dành cho mã nguồn bằng ngôn ngữ lập trình JavaScript. Tệp nguồn JavaScript được mô tả là ở trong Google Style khi và chỉ khi nó tuân thủ các quy tắc ở đây

Show

Giống như các hướng dẫn về phong cách lập trình khác, các vấn đề được đề cập không chỉ bao gồm các vấn đề thẩm mỹ về định dạng mà còn cả các loại quy ước hoặc tiêu chuẩn viết mã khác. Tuy nhiên, tài liệu này tập trung chủ yếu vào các quy tắc cứng rắn và nhanh chóng mà chúng tôi tuân theo trên toàn cầu và tránh đưa ra lời khuyên không thể thực thi rõ ràng (dù là do con người hay công cụ)

1. 1 Ghi chú thuật ngữ

Trong tài liệu này, trừ khi được giải thích khác

  1. Thuật ngữ nhận xét luôn đề cập đến nhận xét triển khai. Chúng tôi không sử dụng cụm từ nhận xét tài liệu, thay vào đó sử dụng thuật ngữ chung “JSDoc” cho cả văn bản mà con người có thể đọc được và chú thích mà máy có thể đọc được trong phạm vi

    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    48

  2. Hướng dẫn Phong cách này sử dụng thuật ngữ RFC 2119 khi sử dụng các cụm từ phải, không được, nên, không nên và có thể. Các thuật ngữ thích và tránh tương ứng với nên và không nên tương ứng. Các câu mệnh lệnh và tuyên bố là quy định và tương ứng với phải

Các ghi chú thuật ngữ khác sẽ thỉnh thoảng xuất hiện trong toàn bộ tài liệu

1. 2 Ghi chú hướng dẫn

Mã ví dụ trong tài liệu này là phi quy chuẩn. Nghĩa là, trong khi các ví dụ ở trong Google Style, chúng có thể không minh họa cách duy nhất để thể hiện mã. Các lựa chọn định dạng tùy chọn được thực hiện trong các ví dụ không được thực thi như các quy tắc

2 Thông tin cơ bản về tệp nguồn

2. 1 Tên tệp

Tên tệp phải là chữ thường và có thể bao gồm dấu gạch dưới (

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
49) hoặc dấu gạch ngang (
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
50), nhưng không có dấu chấm câu bổ sung. Thực hiện theo quy ước mà dự án của bạn sử dụng. Phần mở rộng của tên tệp phải là
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
51

2. 2 Mã hóa tập tin. UTF-8

Các tệp nguồn được mã hóa bằng UTF-8

2. 3 ký tự đặc biệt

2. 3. 1 Ký tự khoảng trắng

Ngoài trình tự kết thúc dòng, ký tự khoảng cách ngang ASCII (0x20) là ký tự khoảng trắng duy nhất xuất hiện ở bất kỳ đâu trong tệp nguồn. Điều này ngụ ý rằng

  1. Tất cả các ký tự khoảng trắng khác trong chuỗi ký tự được thoát và

  2. Các ký tự tab không được sử dụng để thụt lề

2. 3. 2 Trình tự thoát hiểm đặc biệt

Đối với bất kỳ ký tự nào có trình tự thoát đặc biệt (_______0_______52,

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
53,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
54,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
55,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
56,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
57,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
58,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
59,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
60), trình tự đó được sử dụng thay vì trình tự thoát số tương ứng (e. g
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
61,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
62, hoặc
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
63). Thoát bát phân kế thừa không bao giờ được sử dụng

2. 3. 3 ký tự không phải ASCII

Đối với các ký tự không phải ASCII còn lại, ký tự Unicode thực tế (e. g.

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
64) hoặc bộ thoát hex hoặc Unicode tương đương (e. g.
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
65) được sử dụng, chỉ phụ thuộc vào cái nào làm cho mã dễ đọc và dễ hiểu hơn

Mẹo. Trong trường hợp thoát Unicode và đôi khi ngay cả khi các ký tự Unicode thực được sử dụng, một nhận xét giải thích có thể rất hữu ích

/* Best: perfectly clear even without a comment. */
const units = 'μs';

/* Allowed: but unnecessary as μ is a printable character. */
const units = '\u03bcs'; // 'μs'

/* Good: use escapes for non-printable characters with a comment for clarity. */
return '\ufeff' + content;  // Prepend a byte order mark.
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';

Mẹo. Đừng bao giờ làm cho mã của bạn khó đọc hơn chỉ vì sợ rằng một số chương trình có thể không xử lý đúng các ký tự không phải ASCII. If that happens, those programs are broken and they must be fixed

3 Cấu trúc tệp nguồn

Tất cả các tệp nguồn mới phải là tệp

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 (tệp chứa lệnh gọi
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66) hoặc mô-đun ECMAScript (ES) (sử dụng câu lệnh
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
68 và ________0____69). Các tập tin bao gồm những điều sau đây, theo thứ tự

  1. Thông tin giấy phép hoặc bản quyền, nếu có
  2. /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    70 JSDoc, nếu có
  3. Câu lệnh
    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    66, nếu tệp
    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    66
  4. ES
    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    68 câu lệnh, nếu một mô-đun ES
  5. Câu lệnh
    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    74 và
    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    75
  6. Việc triển khai tệp

Chính xác một dòng trống phân tách từng phần hiện có, ngoại trừ việc triển khai tệp, có thể có 1 hoặc 2 dòng trống trước

3. 1 Giấy phép hoặc thông tin bản quyền, nếu có

Nếu thông tin giấy phép hoặc bản quyền thuộc về một tệp, thì nó thuộc về đây

3. 2 /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 70 JSDoc, nếu có

Xem các quy tắc định dạng

3. 3 /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 66 tuyên bố

Tất cả các tệp

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 phải khai báo chính xác một tên
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 trên một dòng. các dòng chứa khai báo
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 không được ngắt dòng và do đó là một ngoại lệ đối với giới hạn 80 cột

Toàn bộ đối số với google. mô-đun là những gì xác định một không gian tên. Đó là tên gói (một mã định danh phản ánh đoạn cấu trúc thư mục chứa mã) cộng với, tùy chọn, lớp/enum/giao diện chính mà nó xác định được nối vào cuối

Thí dụ

goog.module('search.urlHistory.UrlHistoryService');

3. 3. 1 thứ bậc

Không gian tên mô-đun không bao giờ được đặt tên là con trực tiếp của không gian tên mô-đun khác

không được phép

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');

Hệ thống phân cấp thư mục phản ánh hệ thống phân cấp không gian tên, sao cho các thư mục con được lồng sâu hơn là thư mục con của thư mục mẹ cấp cao hơn. Lưu ý rằng điều này ngụ ý rằng chủ sở hữu của các nhóm không gian tên "cha mẹ" nhất thiết phải biết tất cả các không gian tên con, vì chúng tồn tại trong cùng một thư mục

3. 3. 2
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
81

Câu lệnh duy nhất

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 có thể tùy chọn được theo sau bởi lệnh gọi tới
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
83. Tránh
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
84 khi có thể

Thí dụ

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
81 tồn tại để dễ dàng chuyển đổi từ các không gian tên dựa trên phân cấp đối tượng truyền thống nhưng đi kèm với một số hạn chế đặt tên. Vì tên mô-đun con phải được tạo sau không gian tên cha, nên tên này không được là con hoặc cha của bất kỳ
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 nào khác (ví dụ:
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
87 và
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
88 không thể tồn tại an toàn, cũng như
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
87 và
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
90)

3. 3. 3 /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 66 Xuất khẩu

Các lớp, enum, hàm, hằng số và các ký hiệu khác được xuất bằng cách sử dụng đối tượng

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
92. Các biểu tượng đã xuất có thể được xác định trực tiếp trên đối tượng
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
92 hoặc được khai báo cục bộ và được xuất riêng. Các biểu tượng chỉ được xuất nếu chúng được sử dụng bên ngoài mô-đun. Các ký hiệu mô-đun-cục bộ không được xuất khẩu không được khai báo
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94 cũng như tên của chúng không kết thúc bằng dấu gạch dưới. Không có thứ tự theo quy định cho các ký hiệu được xuất và mô-đun-cục bộ

ví dụ

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';

Không chú thích đối tượng

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
92 là
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
96 vì nó đã được trình biên dịch coi là hằng số

/** @const */
exports = {exportedFunction};

3. 4 mô-đun ES

3. 4. 1 Nhập khẩu

Báo cáo nhập khẩu không được ngắt dòng và do đó là một ngoại lệ đối với giới hạn 80 cột

3. 4. 1. 1 Đường dẫn nhập

Các tệp mô-đun ES phải sử dụng câu lệnh

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
68 để nhập các tệp mô-đun ES khác. Đừng
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 mô-đun ES khác

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
3. 4. 1. 1. 1 Phần mở rộng tệp trong đường dẫn nhập

The

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
51 file extension is not optional in import paths and must always be included

import '../directory/file';
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
0

Không nhập cùng một tệp nhiều lần. Điều này có thể gây khó khăn cho việc xác định số lần nhập tổng hợp của một tệp

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
1
3. 4. 1. 3 Đặt tên nhập khẩu
3. 4. 1. 3. 1 Nhập mô-đun đặt tên

Tên nhập mô-đun (

goog.module('search.urlHistory.UrlHistoryService');
00) là tên
goog.module('search.urlHistory.UrlHistoryService');
01 được lấy từ tên tệp đã nhập

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
2
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
33. 4. 1. 3. 2 Naming default imports

Tên nhập mặc định được lấy từ tên tệp đã nhập và tuân theo các quy tắc trong

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
4

Ghi chú. Nói chung, điều này sẽ không xảy ra vì hướng dẫn kiểu này cấm xuất mặc định, xem. Nhập mặc định chỉ được sử dụng để nhập các mô-đun không tuân theo hướng dẫn kiểu này

3. 4. 1. 3. 3 Đặt tên cho hàng nhập đã đặt tên

In general symbols imported via the named import (

goog.module('search.urlHistory.UrlHistoryService');
02) should keep the same name. Tránh nhập bí danh (
goog.module('search.urlHistory.UrlHistoryService');
03). Thích sửa xung đột tên bằng cách sử dụng mô-đun nhập (_______35_______04) hoặc tự đổi tên bản xuất

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
5

Nếu cần đổi tên một mục nhập đã đặt tên thì hãy sử dụng các thành phần của tên tệp hoặc đường dẫn của mô-đun đã nhập trong bí danh kết quả

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
6

3. 4. 2 xuất khẩu

Các biểu tượng chỉ được xuất nếu chúng được sử dụng bên ngoài mô-đun. Các ký hiệu mô-đun-cục bộ không được xuất khẩu không được khai báo

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94 cũng như tên của chúng không kết thúc bằng dấu gạch dưới. Không có thứ tự theo quy định cho các ký hiệu được xuất và mô-đun-cục bộ

3. 4. 2. 1 Named vs default exports

Sử dụng xuất khẩu có tên trong tất cả các mã. Bạn có thể áp dụng từ khóa

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
69 cho khai báo hoặc sử dụng cú pháp
goog.module('search.urlHistory.UrlHistoryService');
07

Do not use default exports. Nhập mô-đun phải đặt tên cho các giá trị này, điều này có thể dẫn đến sự không nhất quán trong việc đặt tên giữa các mô-đun

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
7
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
8
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
9
3. 4. 2. 2 Exporting static container classes and objects

Do not export container classes or objects with static methods or properties for the sake of namespacing

goog.module('search.urlHistory.UrlHistoryService');
0

Instead, export individual constants and functions

goog.module('search.urlHistory.UrlHistoryService');
1
3. 4. 2. 3 Mutability of exports

Exported variables must not be mutated outside of module initialization

There are alternatives if mutation is needed, including exporting a constant reference to an object that has mutable fields or exporting accessor functions for mutable data

goog.module('search.urlHistory.UrlHistoryService');
2
goog.module('search.urlHistory.UrlHistoryService');
3
3. 4. 2. 4 export from

goog.module('search.urlHistory.UrlHistoryService');
08 statements must not be line wrapped and are therefore an exception to the 80-column limit. This applies to both
goog.module('search.urlHistory.UrlHistoryService');
08 flavors

goog.module('search.urlHistory.UrlHistoryService');
4

3. 4. 3 Circular Dependencies in ES modules

Do not create cycles between ES modules, even though the ECMAScript specification allows this. Note that it is possible to create cycles with both the

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
68 and
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
69 statements

goog.module('search.urlHistory.UrlHistoryService');
5
goog.module('search.urlHistory.UrlHistoryService');
6
goog.module('search.urlHistory.UrlHistoryService');
7

3. 4. 4 Interoperating with Closure

3. 4. 4. 1 Referencing goog

To reference the Closure

goog.module('search.urlHistory.UrlHistoryService');
12 namespace, import Closure's
goog.module('search.urlHistory.UrlHistoryService');
13

goog.module('search.urlHistory.UrlHistoryService');
8

goog.module('search.urlHistory.UrlHistoryService');
13 exports only a subset of properties from the global
goog.module('search.urlHistory.UrlHistoryService');
12 that can be used in ES modules

3. 4. 4. 2 goog. require in ES modules

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 in ES modules works as it does in
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 files. You can require any Closure namespace symbol (i. e. , symbols created by
goog.module('search.urlHistory.UrlHistoryService');
18 or
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66) and
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 will return the value

goog.module('search.urlHistory.UrlHistoryService');
9
3. 4. 4. 3 Declaring Closure Module IDs in ES modules

goog.module('search.urlHistory.UrlHistoryService');
21 can be used within ES modules to declare a
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66-like module ID. This means that this module ID can be
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74d,
goog.module('search.urlHistory.UrlHistoryService');
24d,
goog.module('search.urlHistory.UrlHistoryService');
25'd, etc. as if it were a
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 that did not call
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
81. It does not create the module ID as a globally available JavaScript symbol

A

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 (or
goog.module('search.urlHistory.UrlHistoryService');
24) for a module ID from
goog.module('search.urlHistory.UrlHistoryService');
21 will always return the module object (as if it was
goog.module('search.urlHistory.UrlHistoryService');
04'd). As a result, the argument to
goog.module('search.urlHistory.UrlHistoryService');
21 should always end with a
goog.module('search.urlHistory.UrlHistoryService');
33

Note. It is an error to call

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
81 in an ES module, it can only be called from
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 files. There is no direct way to associate a legacy namespace with an ES module

goog.module('search.urlHistory.UrlHistoryService');
21 should only be used to upgrade Closure files to ES modules in place, where named exports are used

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
0

3. 5 goog.module('search.urlHistory.UrlHistoryService'); 37

In a

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 file the
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 statement may optionally be followed by a call to
goog.module('search.urlHistory.UrlHistoryService');
40

In an ES module the

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
68 statements may optionally be followed by a call to
goog.module('search.urlHistory.UrlHistoryService');
40

3. 6 /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74 and /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 75 statements

Imports are done with

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 and
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 statements. The names imported by a
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 statement may be used both in code and in type annotations, while those imported by a
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 may be used in type annotations only

The

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 and
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 statements form a contiguous block with no empty lines. This block follows the
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 declaration separated . The entire argument to
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 or
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 is a namespace defined by a
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 in a separate file.
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 and
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 statements may not appear anywhere else in the file

Each

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 or
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 is assigned to a single constant alias, or else destructured into several constant aliases. These aliases are the only acceptable way to refer to dependencies in type annotations or code. Fully qualified namespaces must not be used anywhere, except as an argument to
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 or
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75

Exception. Các loại, biến và hàm được khai báo trong tệp bên ngoài phải sử dụng tên đủ điều kiện của chúng trong chú thích loại và mã

Aliases must match the final dot-separated component of the imported module's namespace

Ngoại lệ. In certain cases, additional components of the namespace can be used to form a longer alias. The resulting alias must retain the original identifier's casing such that it still correctly identifies its type. Longer aliases may be used to disambiguate otherwise identical aliases, or if it significantly improves readability. In addition, a longer alias must be used to prevent masking native types such as

goog.module('search.urlHistory.UrlHistoryService');
61,
goog.module('search.urlHistory.UrlHistoryService');
62,
goog.module('search.urlHistory.UrlHistoryService');
63,
goog.module('search.urlHistory.UrlHistoryService');
64, and
goog.module('search.urlHistory.UrlHistoryService');
65 (for a more complete list, see Standard Built-in Objects and Web APIs at MDN). When renaming destructured aliases, a space must follow the colon as required in

A file should not contain both a

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 and a
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 statement for the same namespace. If the imported name is used both in code and in type annotations, it should be imported by a single
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 statement

If a module is imported only for its side effects, the call must be a

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 (not a
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75) and assignment may be omitted. A comment is required to explain why this is needed and suppress a compiler warning

Các dòng được sắp xếp theo các quy tắc sau. Tất cả các yêu cầu có tên ở phía bên trái được ưu tiên trước, được sắp xếp theo thứ tự bảng chữ cái của các tên đó. Sau đó, yêu cầu phá hủy, được sắp xếp lại theo tên ở phía bên trái. Cuối cùng, bất kỳ cuộc gọi yêu cầu nào độc lập (thường là những cuộc gọi này dành cho các mô-đun được nhập chỉ vì tác dụng phụ của chúng)

Mẹo. Không cần phải ghi nhớ lệnh này và thực thi thủ công. Bạn có thể dựa vào IDE của mình để báo cáo các yêu cầu không được sắp xếp chính xác

Nếu một bí danh hoặc tên mô-đun dài sẽ khiến một dòng vượt quá giới hạn 80 cột, thì nó không được ngắt dòng. các dòng yêu cầu là một ngoại lệ đối với giới hạn 80 cột

Thí dụ

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
1

nản lòng

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
2

không được phép

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
3

3. 7 Việc triển khai tệp

Việc triển khai thực tế diễn ra sau khi tất cả thông tin phụ thuộc được khai báo (cách nhau ít nhất một dòng trống)

Điều này có thể bao gồm bất kỳ khai báo mô-đun-cục bộ nào (hằng, biến, lớp, hàm, v.v.), cũng như bất kỳ biểu tượng được xuất nào

4 Định dạng

Lưu ý thuật ngữ. cấu trúc giống như khối đề cập đến phần thân của một lớp, hàm, phương thức hoặc khối mã được phân cách bằng dấu ngoặc nhọn. Lưu ý rằng, by và , bất kỳ mảng hoặc đối tượng theo nghĩa đen nào cũng có thể tùy ý được xử lý như thể nó là một cấu trúc giống như khối

Mẹo. Sử dụng

goog.module('search.urlHistory.UrlHistoryService');
71. Cộng đồng JavaScript đã đầu tư nỗ lực để đảm bảo clang-format hoạt động đúng trên các tệp JavaScript.
goog.module('search.urlHistory.UrlHistoryService');
71 có tích hợp với một số trình soạn thảo phổ biến

4. 1 niềng răng

4. 1. 1 Niềng răng được sử dụng cho tất cả các cấu trúc điều khiển

Niềng răng được yêu cầu cho tất cả các cấu trúc điều khiển (i. e.

goog.module('search.urlHistory.UrlHistoryService');
73,
goog.module('search.urlHistory.UrlHistoryService');
74,
goog.module('search.urlHistory.UrlHistoryService');
75,
goog.module('search.urlHistory.UrlHistoryService');
76,
goog.module('search.urlHistory.UrlHistoryService');
77, cũng như bất kỳ câu lệnh nào khác), ngay cả khi phần nội dung chỉ chứa một câu lệnh duy nhất. Câu lệnh đầu tiên của một khối không trống phải bắt đầu trên dòng của chính nó

không được phép

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
4

Ngoại lệ. Một câu lệnh if đơn giản có thể vừa khít hoàn toàn trên một dòng mà không có dòng xuống dòng (và không có dòng nào khác) có thể được giữ trên một dòng không có dấu ngoặc khi nó cải thiện khả năng đọc. Đây là trường hợp duy nhất trong đó cấu trúc điều khiển có thể bỏ dấu ngoặc nhọn và dòng mới

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
5

4. 1. 2 khối rỗng. phong cách K&R

Dấu ngoặc theo kiểu Kernighan và Ritchie (dấu ngoặc của người Ai Cập) cho các khối không trống và các cấu trúc giống như khối

  • Không ngắt dòng trước dấu ngoặc mở
  • Ngắt dòng sau cú đúp mở đầu
  • Ngắt dòng trước dấu ngoặc nhọn
  • Ngắt dòng sau dấu ngoặc nhọn nếu dấu ngoặc nhọn đó kết thúc câu lệnh hoặc phần thân của hàm hoặc câu lệnh lớp hoặc phương thức lớp. Cụ thể, không có ngắt dòng sau dấu ngoặc nhọn nếu nó được theo sau bởi ________ 35 _______74, ________35 ______79, ________35 _______77 hoặc dấu phẩy, dấu chấm phẩy hoặc dấu ngoặc đơn bên phải

Thí dụ

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
6

4. 1. 3 khối trống. có thể ngắn gọn

Một khối trống hoặc cấu trúc giống như khối có thể được đóng lại ngay sau khi nó được mở ra, không có ký tự, dấu cách hoặc ngắt dòng ở giữa (i. e.

goog.module('search.urlHistory.UrlHistoryService');
81), trừ khi nó là một phần của câu lệnh nhiều khối (câu lệnh chứa trực tiếp nhiều khối.
goog.module('search.urlHistory.UrlHistoryService');
73/______35_______74 hoặc
goog.module('search.urlHistory.UrlHistoryService');
84/
goog.module('search.urlHistory.UrlHistoryService');
79/
goog.module('search.urlHistory.UrlHistoryService');
86)

Thí dụ

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
7

không được phép

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
8

4. 2 Khối thụt đầu dòng. +2 dấu cách

Mỗi khi một khối mới hoặc cấu trúc giống như khối được mở, phần thụt lề sẽ tăng thêm hai khoảng trắng. Khi khối kết thúc, thụt lề trở về mức thụt lề trước đó. Mức thụt lề áp dụng cho cả mã và nhận xét trong toàn bộ khối. (Xem ví dụ trong)

4. 2. 1 mảng chữ. giống như khối tùy chọn

Bất kỳ mảng chữ nào cũng có thể được định dạng tùy chọn như thể nó là một “cấu trúc giống như khối. ” Ví dụ: tất cả những điều sau đây đều hợp lệ (không phải là danh sách đầy đủ)

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
9
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
0

Các kết hợp khác được cho phép, đặc biệt khi nhấn mạnh các nhóm ngữ nghĩa giữa các phần tử, nhưng không nên chỉ được sử dụng để giảm kích thước dọc của các mảng lớn hơn

4. 2. 2 đối tượng chữ. giống như khối tùy chọn

Bất kỳ đối tượng theo nghĩa đen nào cũng có thể được định dạng tùy chọn như thể nó là một “cấu trúc giống như khối. ” Các ví dụ tương tự áp dụng như. Ví dụ: tất cả những điều sau đây đều hợp lệ (không phải là danh sách đầy đủ)

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
1
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
2

4. 2. 3 Lớp chữ

Các ký tự lớp (dù là khai báo hay biểu thức) được thụt vào dưới dạng khối. Không thêm dấu chấm phẩy sau các phương thức hoặc sau dấu ngoặc nhọn đóng của một khai báo lớp (các câu lệnh—chẳng hạn như các phép gán—có chứa các biểu thức lớp vẫn được kết thúc bằng dấu chấm phẩy). Sử dụng từ khóa

goog.module('search.urlHistory.UrlHistoryService');
87, nhưng không sử dụng chú thích
goog.module('search.urlHistory.UrlHistoryService');
88 JSDoc trừ khi lớp mở rộng một loại được tạo khuôn mẫu

Thí dụ

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
3
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
4

4. 2. 4 Function expressions

Khi khai báo một hàm ẩn danh trong danh sách các đối số cho một lệnh gọi hàm, phần thân của hàm được thụt lề nhiều hơn hai khoảng trắng so với độ sâu thụt lề trước đó

Thí dụ

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
5

4. 2. 5 Switch statements

As with any other block, the contents of a switch block are indented +2

Sau nhãn chuyển đổi, một dòng mới xuất hiện và mức thụt đầu dòng được tăng lên +2, chính xác như thể một khối đang được mở. An explicit block may be used if required by lexical scoping. Nhãn công tắc sau trở về mức thụt đầu dòng trước đó, như thể một khối đã bị đóng

A blank line is optional between a

goog.module('search.urlHistory.UrlHistoryService');
89 and the following case

Thí dụ

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
6

4. 3 Statements

4. 3. 1 Một câu lệnh trên mỗi dòng

Mỗi câu lệnh được theo sau bởi một dấu ngắt dòng

4. 3. 2 Semicolons are required

Every statement must be terminated with a semicolon. Relying on automatic semicolon insertion is forbidden

4. 4 Giới hạn cột. 80

JavaScript code has a column limit of 80 characters. Ngoại trừ như được lưu ý bên dưới, bất kỳ dòng nào vượt quá giới hạn này đều phải được ngắt dòng, như được giải thích trong

Exceptions

  1. /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    66,
    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    74 and
    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    75 statements (see and )
  2. ES module
    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    68 and
    goog.module('search.urlHistory.UrlHistoryService');
    
    08 statements (see and )
  3. Lines where obeying the column limit is not possible or would hinder discoverability. Examples include
    • A long URL which should be clickable in source
    • A shell command intended to be copied-and-pasted
    • A long string literal which may need to be copied or searched for wholly (e. g. , a long file path)

4. 5 Line-wrapping

Terminology Note. Line wrapping is breaking a chunk of code into multiple lines to obey column limit, where the chunk could otherwise legally fit in a single line

There is no comprehensive, deterministic formula showing exactly how to line-wrap in every situation. Very often there are several valid ways to line-wrap the same piece of code

Note. While the typical reason for line-wrapping is to avoid overflowing the column limit, even code that would in fact fit within the column limit may be line-wrapped at the author's discretion

Tip. Trích xuất một phương thức hoặc biến cục bộ có thể giải quyết vấn đề mà không cần phải ngắt dòng

4. 5. 1 Where to break

The prime directive of line-wrapping is. prefer to break at a higher syntactic level

Preferred

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
7

nản lòng

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
8

In the preceding example, the syntactic levels from highest to lowest are as follows. assignment, division, function call, parameters, number constant

Operators are wrapped as follows

  1. When a line is broken at an operator the break comes after the symbol. (Note that this is not the same practice used in Google style for Java. )
    1. This does not apply to the dot (
      goog.module('search.urlHistory.UrlHistoryService');
      
      95), which is not actually an operator
  2. A method or constructor name stays attached to the open parenthesis (
    goog.module('search.urlHistory.UrlHistoryService');
    
    96) that follows it
  3. A comma (
    goog.module('search.urlHistory.UrlHistoryService');
    
    97) stays attached to the token that precedes it

Note. The primary goal for line wrapping is to have clear code, not necessarily code that fits in the smallest number of lines

4. 5. 2 Indent continuation lines at least +4 spaces

When line-wrapping, each line after the first (each continuation line) is indented at least +4 from the original line, unless it falls under the rules of block indentation

When there are multiple continuation lines, indentation may be varied beyond +4 as appropriate. In general, continuation lines at a deeper syntactic level are indented by larger multiples of 4, and two lines use the same indentation level if and only if they begin with syntactically parallel elements

addresses the discouraged practice of using a variable number of spaces to align certain tokens with previous lines

4. 6 Whitespace

4. 6. 1 Vertical whitespace

A single blank line appears

  1. Between consecutive methods in a class or object literal
    1. Exception. A blank line between two consecutive properties definitions in an object literal (with no other code between them) is optional. Such blank lines are used as needed to create logical groupings of fields
  2. Within method bodies, sparingly to create logical groupings of statements. Blank lines at the start or end of a function body are not allowed
  3. Optionally before the first or after the last method in a class or object literal (neither encouraged nor discouraged)
  4. As required by other sections of this document (e. g. )

Multiple consecutive blank lines are permitted, but never required (nor encouraged)

4. 6. 2 Horizontal whitespace

Use of horizontal whitespace depends on location, and falls into three broad categories. leading (at the start of a line), trailing (at the end of a line), and internal. Leading whitespace (i. e. , indentation) is addressed elsewhere. Trailing whitespace is forbidden

Beyond where required by the language or other style rules, and apart from literals, comments, and JSDoc, a single internal ASCII space also appears in the following places only

  1. Separating any reserved word (such as
    goog.module('search.urlHistory.UrlHistoryService');
    
    73,
    goog.module('search.urlHistory.UrlHistoryService');
    
    75, or
    goog.module('search.urlHistory.UrlHistoryService');
    
    79) except for
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    01 and
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    02, from an open parenthesis (
    goog.module('search.urlHistory.UrlHistoryService');
    
    96) that follows it on that line
  2. Separating any reserved word (such as
    goog.module('search.urlHistory.UrlHistoryService');
    
    74 or
    goog.module('search.urlHistory.UrlHistoryService');
    
    79) from a closing curly brace (
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    06) that precedes it on that line
  3. Before any open curly brace (
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    07), with two exceptions
    1. Before an object literal that is the first argument of a function or the first element in an array literal (e. g.
      goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
      goog.module('foo.bar.baz');
      
      08)
    2. In a template expansion, as it is forbidden by the language (e. g. valid.
      goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
      goog.module('foo.bar.baz');
      
      09, invalid.
      goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
      goog.module('foo.bar.baz');
      
      10)
  4. On both sides of any binary or ternary operator
  5. After a comma (
    goog.module('search.urlHistory.UrlHistoryService');
    
    97) or semicolon (
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    12). Note that spaces are never allowed before these characters
  6. After the colon (
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    13) in an object literal
  7. On both sides of the double slash (
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    14) that begins an end-of-line comment. Here, multiple spaces are allowed, but not required
  8. Sau một ký tự bình luận khối mở và ở cả hai bên của các ký tự đóng (e. g. for short-form type declarations, casts, and parameter name comments.
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    15; or
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    16; or
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    17)

4. 6. 3 Horizontal alignment. discouraged

Terminology Note. Horizontal alignment is the practice of adding a variable number of additional spaces in your code with the goal of making certain tokens appear directly below certain other tokens on previous lines

This practice is permitted, but it is generally discouraged by Google Style. It is not even required to maintain horizontal alignment in places where it was already used

Here is an example without alignment, followed by one with alignment. Both are allowed, but the latter is discouraged

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
9

Tip. Alignment can aid readability, but it creates problems for future maintenance. Consider a future change that needs to touch just one line. This change may leave the formerly-pleasing formatting mangled, and that is allowed. More often it prompts the coder (perhaps you) to adjust whitespace on nearby lines as well, possibly triggering a cascading series of reformattings. Thay đổi một dòng đó hiện có bán kính vụ nổ. This can at worst result in pointless busywork, but at best it still corrupts version history information, slows down reviewers and exacerbates merge conflicts

4. 6. 4 Function arguments

Thích đặt tất cả các đối số hàm trên cùng một dòng với tên hàm. Nếu làm như vậy sẽ vượt quá giới hạn 80 cột, các đối số phải được ngắt dòng theo cách có thể đọc được. Để tiết kiệm dung lượng, bạn có thể ngắt dòng càng gần 80 càng tốt hoặc đặt mỗi đối số trên một dòng riêng để dễ đọc hơn. Thụt đầu dòng phải là bốn khoảng trắng. Căn chỉnh theo dấu ngoặc đơn được cho phép, nhưng không được khuyến khích. Dưới đây là các mẫu phổ biến nhất để gói đối số

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
0

Các dấu ngoặc nhóm tùy chọn chỉ được bỏ qua khi tác giả và người đánh giá đồng ý rằng không có khả năng mã sẽ bị hiểu sai nếu không có chúng, cũng như chúng sẽ không làm cho mã dễ đọc hơn. Không hợp lý khi cho rằng mọi đầu đọc đều ghi nhớ toàn bộ bảng ưu tiên toán tử

Do not use unnecessary parentheses around the entire expression following

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
18,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
19,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
20,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
21,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
22,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
23,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
24,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
25, or
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
26

Dấu ngoặc đơn là bắt buộc đối với kiểu phôi.

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
27

This section addresses implementation comments. JSDoc được xử lý riêng trong

Block comments are indented at the same level as the surrounding code. Chúng có thể theo kiểu

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
28 hoặc
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
14. For multi-line
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
28 comments, subsequent lines must start with * aligned with the
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
31 on the previous line, to make comments obvious with no extra context

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
1

Nhận xét không được đặt trong các hộp được vẽ bằng dấu hoa thị hoặc các ký tự khác

Không sử dụng JSDoc (_______0_______48) để nhận xét triển khai

Nhận xét "Tên tham số" nên được sử dụng bất cứ khi nào giá trị và tên phương thức không truyền đạt đầy đủ ý nghĩa và việc tái cấu trúc phương thức để rõ ràng hơn là không khả thi. Định dạng ưa thích của họ là trước giá trị với =

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
2

For consistency with surrounding code you may put them after the value without =

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
3

5 Tính năng ngôn ngữ

JavaScript bao gồm nhiều tính năng đáng ngờ (và thậm chí nguy hiểm). This section delineates which features may or may not be used, and any additional constraints on their use

5. 1 Khai báo biến cục bộ

5. 1. 1 Sử dụng
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
33 và
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
34

Khai báo tất cả các biến cục bộ bằng

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
33 hoặc
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
34. Sử dụng const theo mặc định, trừ khi một biến cần được gán lại. The
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
37 keyword must not be used

5. 1. 2 Mỗi khai báo một biến

Mỗi khai báo biến cục bộ chỉ khai báo một biến. declarations such as

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
38 are not used

5. 1. 3 Khai báo khi cần thiết, khởi tạo ngay khi có thể

Local variables are not habitually declared at the start of their containing block or block-like construct. Thay vào đó, các biến cục bộ được khai báo gần với điểm chúng được sử dụng lần đầu tiên (với lý do), để giảm thiểu phạm vi của chúng

5. 1. 4 Khai báo các loại theo yêu cầu

Các chú thích loại JSDoc có thể được thêm vào dòng phía trên khai báo hoặc nội tuyến khác trước tên biến nếu không có JSDoc nào khác xuất hiện

Thí dụ

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
4

Mixing inline and JSDoc styles is not allowed. trình biên dịch sẽ chỉ xử lý JsDoc đầu tiên và các chú thích nội tuyến sẽ bị mất

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
5

Mẹo. There are many cases where the compiler can infer a templatized type but not its parameters. This is particularly the case when the initializing literal or constructor call does not include any values of the template parameter type (e. g. , mảng trống, đối tượng,

goog.module('search.urlHistory.UrlHistoryService');
64 hoặc
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
40) hoặc nếu biến được sửa đổi trong một bao đóng. Local variable type annotations are particularly helpful in these cases since otherwise the compiler will infer the template parameter as unknown

5. 2 mảng chữ

5. 2. 1 Sử dụng dấu phẩy sau

Bao gồm dấu phẩy ở cuối bất cứ khi nào có dấu ngắt dòng giữa phần tử cuối cùng và dấu ngoặc đóng

Thí dụ

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
6

5. 2. 2 Không sử dụng phương thức khởi tạo biến đổi
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
41

Hàm tạo dễ bị lỗi nếu các đối số được thêm hoặc xóa. Sử dụng một nghĩa đen thay thế

không được phép

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
7

Điều này hoạt động như mong đợi ngoại trừ trường hợp thứ ba. if

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
42 is a whole number then
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
43 is an array of size
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
42 where all elements are
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
45. If
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
42 is any other number, then an exception will be thrown, and if it is anything else then it will be a single-element array

Thay vào đó, hãy viết

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
8

Cho phép phân bổ rõ ràng một mảng có độ dài nhất định bằng cách sử dụng

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
47 khi thích hợp

5. 2. 3 Thuộc tính phi số

Do not define or use non-numeric properties on an array (other than

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
48). Use a
goog.module('search.urlHistory.UrlHistoryService');
64 (or
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
50) instead

5. 2. 4 Phá hủy

Các ký tự mảng có thể được sử dụng ở phía bên trái của phép gán để thực hiện hủy (chẳng hạn như khi giải nén nhiều giá trị từ một mảng đơn hoặc có thể lặp lại). Phần tử còn lại cuối cùng có thể được bao gồm (không có khoảng cách giữa

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
51 và tên biến). Elements should be omitted if they are unused

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
9

Việc hủy cấu trúc cũng có thể được sử dụng cho các tham số chức năng (lưu ý rằng tên tham số là bắt buộc nhưng có thể bỏ qua). Always specify

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
52 as the default value if a destructured array parameter is optional, and provide default values on the left hand side

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
0

không được phép

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
1

Mẹo. Để (không) đóng gói nhiều giá trị vào một tham số hoặc hàm trả về, hãy ưu tiên hủy đối tượng hơn là hủy mảng khi có thể, vì nó cho phép đặt tên các phần tử riêng lẻ và chỉ định một loại khác nhau cho từng phần tử

5. 2. 5 Toán tử trải rộng

Các ký tự mảng có thể bao gồm toán tử trải rộng (

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
51) để làm phẳng các phần tử ra khỏi một hoặc nhiều lần lặp khác. Toán tử trải rộng nên được sử dụng thay vì các cấu trúc khó xử hơn với
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
54. There is no space after the
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
51

Thí dụ

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
2

5. 3 Object literals

5. 3. 1 Sử dụng dấu phẩy sau

Bao gồm dấu phẩy ở cuối bất cứ khi nào có dấu ngắt dòng giữa thuộc tính cuối cùng và dấu ngoặc nhọn đóng

5. 3. 2 Do not use the
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
50 constructor

Mặc dù

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
50 không gặp vấn đề giống như
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
41, nhưng nó vẫn không được phép vì tính nhất quán. Use an object literal (
goog.module('search.urlHistory.UrlHistoryService');
81 or
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
60) instead

5. 3. 3 Không trộn lẫn các phím được trích dẫn và không được trích dẫn

Object literals may represent either structs (with unquoted keys and/or symbols) or dicts (with quoted and/or computed keys). Do not mix these key types in a single object literal

không được phép

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
3

This also extends to passing the property name to functions, like

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
61. Cụ thể, làm như vậy sẽ phá vỡ mã được biên dịch vì trình biên dịch không thể đổi tên/làm xáo trộn chuỗi ký tự

không được phép

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
4

Điều này được thực hiện tốt nhất như

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
5

5. 3. 4 Computed property names

Tên thuộc tính được tính toán (e. g. ,

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
62) được cho phép và được coi là khóa kiểu chính tả (trích dẫn) (i. e. , must not be mixed with non-quoted keys) unless the computed property is a symbol (e. g. ,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
63). Enum values may also be used for computed keys, but should not be mixed with non-enum keys in the same literal

5. 3. 5 Phương pháp tốc ký

Các phương thức có thể được định nghĩa trên các ký tự đối tượng bằng cách sử dụng tốc ký của phương thức (

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
64) thay cho dấu hai chấm ngay sau đó là một ký tự hàm
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
01 hoặc mũi tên

Thí dụ

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
6

Lưu ý rằng

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
66 trong một phương thức viết tắt hoặc
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
01 đề cập đến chính đối tượng theo nghĩa đen trong khi
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
66 trong một hàm mũi tên đề cập đến phạm vi bên ngoài đối tượng theo nghĩa đen

Thí dụ

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
7

5. 3. 6 thuộc tính tốc ký

Thuộc tính tốc ký được phép trên đối tượng chữ

Thí dụ

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
8

5. 3. 7 Phá hủy

Các mẫu phá hủy đối tượng có thể được sử dụng ở phía bên trái của một nhiệm vụ để thực hiện phá hủy và giải nén nhiều giá trị từ một đối tượng

Các đối tượng bị hủy cấu trúc cũng có thể được sử dụng làm tham số chức năng, nhưng phải được giữ càng đơn giản càng tốt. một cấp duy nhất của các thuộc tính tốc ký không được trích dẫn. Các cấp độ sâu hơn của các thuộc tính được tính toán và lồng nhau có thể không được sử dụng trong quá trình phá hủy tham số. Chỉ định bất kỳ giá trị mặc định nào ở phía bên trái của tham số đã hủy cấu trúc (

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
69, thay vì
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
70) và nếu bản thân đối tượng đã hủy cấu trúc là tùy chọn, thì đối tượng đó phải được đặt mặc định là
goog.module('search.urlHistory.UrlHistoryService');
81. JSDoc cho tham số bị hủy cấu trúc có thể được đặt bất kỳ tên nào (tên này không được sử dụng nhưng được yêu cầu bởi trình biên dịch)

Thí dụ

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
9

không được phép

/** @const */
exports = {exportedFunction};
0

Việc hủy cấu trúc cũng có thể được sử dụng cho các câu lệnh

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 và trong trường hợp này không được bao bọc. toàn bộ câu lệnh chiếm một dòng, bất kể nó dài bao nhiêu (xem phần )

5. 3. 8 bảng liệt kê

Việc liệt kê được xác định bằng cách thêm chú thích

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
73 vào một đối tượng theo nghĩa đen. Các thuộc tính bổ sung có thể không được thêm vào một enum sau khi nó được xác định. Enums phải là hằng số và tất cả các giá trị enum phải không thay đổi sâu sắc

/** @const */
exports = {exportedFunction};
1

5. 4 lớp

5. 4. 1 nhà xây dựng

Constructor là tùy chọn. Các hàm tạo của lớp con phải gọi

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
74 trước khi đặt bất kỳ trường nào hoặc truy cập vào
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
66. Các giao diện nên khai báo các thuộc tính phi phương thức trong hàm tạo

5. 4. 2 trường

Đặt tất cả các trường của một đối tượng cụ thể (i. e. tất cả các thuộc tính khác với phương thức) trong hàm tạo. Chú thích các trường không bao giờ được chỉ định lại với

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
96 (những trường này không cần phải quá bất biến). Annotate non-public fields with the proper visibility annotation (
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
78,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
79), and end all
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94 fields' names with an underscore. Các trường không bao giờ được đặt trên một lớp cụ thể'
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
81

Thí dụ

/** @const */
exports = {exportedFunction};
2

Mẹo. Không bao giờ được thêm hoặc xóa các thuộc tính khỏi một phiên bản sau khi hàm tạo kết thúc, vì nó cản trở đáng kể khả năng tối ưu hóa của máy ảo. Nếu cần, các trường được khởi tạo sau này phải được đặt rõ ràng thành

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
45 trong hàm tạo để ngăn thay đổi hình dạng sau này. Việc thêm
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
83 vào một đối tượng sẽ kiểm tra xem các thuộc tính không được khai báo không được thêm/truy cập. Classes have this added by default

5. 4. 3 Thuộc tính tính toán

Các thuộc tính được tính chỉ có thể được sử dụng trong các lớp khi thuộc tính là một ký hiệu. Các thuộc tính kiểu chính tả (nghĩa là các khóa không phải ký hiệu được trích dẫn hoặc tính toán, như được định nghĩa trong ) không được phép. Một phương thức

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
63 nên được xác định cho bất kỳ lớp nào có thể lặp lại một cách hợp lý. Ngoài điều này,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
85 nên được sử dụng một cách tiết kiệm

Mẹo. hãy cẩn thận khi sử dụng bất kỳ biểu tượng tích hợp nào khác (e. g. ,

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
86) vì chúng không được trình biên dịch điền đầy và do đó sẽ không hoạt động trong các trình duyệt cũ hơn

5. 4. 4 Static methods

Khi nó không ảnh hưởng đến khả năng đọc, hãy ưu tiên các hàm mô-đun cục bộ hơn các phương thức tĩnh riêng tư

Các phương thức tĩnh chỉ nên được gọi trên chính lớp cơ sở. Các phương thức tĩnh không nên được gọi trên các biến chứa một thể hiện động có thể là hàm tạo hoặc hàm tạo của lớp con (và phải được xác định bằng

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
87 nếu điều này được thực hiện) và không được gọi trực tiếp trên lớp con không xác định phương thức tĩnh.

không được phép

/** @const */
exports = {exportedFunction};
3

5. 4. 5 Khai báo lớp kiểu cũ

Mặc dù các lớp ES6 được ưu tiên hơn, nhưng có những trường hợp các lớp ES6 có thể không khả thi. Ví dụ

  1. If there exist or will exist subclasses, including frameworks that create subclasses, that cannot be immediately changed to use ES6 class syntax. If such a class were to use ES6 syntax, all downstream subclasses not using ES6 class syntax would need to be modified

  2. Các khung yêu cầu giá trị

    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    66 đã biết trước khi gọi hàm tạo của siêu lớp, vì các hàm tạo với siêu lớp ES6 không có quyền truy cập vào giá trị của thể hiện
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    66 cho đến khi lệnh gọi tới
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    02 trả về

In all other ways the style guide still applies to this code. Tất cả các tham số mặc định, phần còn lại và hàm mũi tên đều nên được sử dụng khi thích hợp

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
93 cho phép định nghĩa giống như lớp tương tự như cú pháp lớp ES6

/** @const */
exports = {exportedFunction};
4

Alternatively, while

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
93 should be preferred for all new code, more traditional syntax is also allowed

/** @const */
exports = {exportedFunction};
5

Các thuộc tính của mỗi cá thể phải được xác định trong hàm tạo sau lệnh gọi hàm tạo siêu lớp, nếu có một siêu lớp. Các phương thức nên được xác định trên nguyên mẫu của hàm tạo

Defining constructor prototype hierarchies correctly is harder than it first appears. Vì lý do đó, tốt nhất là sử dụng

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
95 từ Thư viện Đóng cửa

5. 4. 6 Không thao tác trực tiếp với
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
81

Từ khóa

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
97 cho phép định nghĩa lớp rõ ràng và dễ đọc hơn so với định nghĩa thuộc tính
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
81. Mã triển khai thông thường không có nghiệp vụ thao tác với các đối tượng này, mặc dù chúng vẫn hữu ích để định nghĩa các lớp như đã định nghĩa trong. Mixins và sửa đổi các nguyên mẫu của các đối tượng dựng sẵn bị cấm rõ ràng

Ngoại lệ. Mã khung (chẳng hạn như Polymer hoặc Angular) có thể cần sử dụng

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
81 và không nên sử dụng các giải pháp thậm chí còn tệ hơn để tránh làm như vậy

5. 4. 7 Getters và Setters

Không sử dụng các thuộc tính getter và setter của JavaScript. Chúng có khả năng gây ngạc nhiên và khó giải thích và có sự hỗ trợ hạn chế trong trình biên dịch. Thay vào đó hãy cung cấp các phương thức thông thường

Ngoại lệ. có những tình huống không thể tránh khỏi việc xác định getter hoặc setter (e. g. data binding frameworks such as Angular and Polymer, or for compatibility with external APIs that cannot be adjusted). Chỉ trong những trường hợp này, getters và setters có thể được sử dụng một cách thận trọng, miễn là chúng được xác định bằng các từ khóa phương pháp tốc ký

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
00 và
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
01 hoặc
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
02 (không phải
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
03, điều này cản trở việc đổi tên thuộc tính). Getters không được thay đổi trạng thái quan sát được

không được phép

/** @const */
exports = {exportedFunction};
6

5. 4. 8 Ghi đè lênString

Phương pháp

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
04 có thể bị ghi đè, nhưng phải luôn thành công và không bao giờ có tác dụng phụ có thể nhìn thấy được

Tip. Beware, in particular, of calling other methods from toString, since exceptional conditions could lead to infinite loops

5. 4. 9 giao diện

Các giao diện có thể được khai báo với

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
05 hoặc
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
06. Interfaces declared with
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
06 can be explicitly (i. e. thông qua
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
08) hoặc được triển khai ngầm bởi một lớp hoặc đối tượng theo nghĩa đen

Tất cả các nội dung phương thức không tĩnh trên giao diện phải là các khối trống. Các trường phải được khai báo là thành viên chưa được khởi tạo trong hàm tạo của lớp

Thí dụ

/** @const */
exports = {exportedFunction};
7

5. 4. 10 lớp trừu tượng

Sử dụng các lớp trừu tượng khi thích hợp. Các lớp và phương thức trừu tượng phải được chú thích bằng

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
09. Không sử dụng
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
10. Xem các lớp và phương thức trừu tượng

5. 5 chức năng

5. 5. 1 Chức năng cấp cao nhất

Các chức năng cấp cao nhất có thể được xác định trực tiếp trên đối tượng

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
92 hoặc nếu không thì được khai báo cục bộ và xuất tùy chọn. Xem để biết thêm về xuất khẩu

ví dụ

/** @const */
exports = {exportedFunction};
8_______56_______9

5. 5. 2 Nested functions and closures

Các hàm có thể chứa các định nghĩa hàm lồng nhau. Nếu việc đặt tên cho hàm là hữu ích, thì nó nên được gán cho một

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
33 cục bộ

5. 5. 3 chức năng mũi tên

Hàm mũi tên cung cấp cú pháp hàm ngắn gọn và đơn giản hóa phạm vi

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
66 cho các hàm lồng nhau. Thích các hàm mũi tên hơn từ khóa
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
01, đặc biệt đối với các hàm lồng nhau (nhưng xem phần )

Thích các chức năng mũi tên hơn các phương pháp tiếp cận phạm vi

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
66 khác, chẳng hạn như
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
16,
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
17 và
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
18. Các hàm mũi tên đặc biệt hữu ích để gọi vào các cuộc gọi lại vì chúng cho phép chỉ định rõ ràng tham số nào sẽ chuyển đến cuộc gọi lại trong khi ràng buộc sẽ chuyển qua tất cả các tham số một cách mù quáng

Phía bên trái của mũi tên chứa 0 hoặc nhiều tham số. Dấu ngoặc đơn xung quanh các tham số là tùy chọn nếu chỉ có một tham số không bị hủy cấu trúc. Khi sử dụng dấu ngoặc đơn, các loại tham số nội tuyến có thể được chỉ định (xem phần )

Mẹo. Việc luôn sử dụng dấu ngoặc đơn ngay cả đối với các hàm mũi tên có một tham số có thể tránh được các trường hợp khi thêm tham số nhưng quên thêm dấu ngoặc đơn, có thể dẫn đến mã có thể phân tích cú pháp và không còn hoạt động như dự kiến

The right-hand side of the arrow contains the body of the function. By default the body is a block statement (zero or more statements surrounded by curly braces). Phần thân cũng có thể là một biểu thức đơn được trả về hoàn toàn nếu một trong hai. the program logic requires returning a value, or the

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
20 operator precedes a single function or method call (using
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
20 ensures
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
45 is returned, prevents leaking values, and communicates intent). Dạng biểu thức đơn được ưu tiên nếu nó cải thiện khả năng đọc (e. g. , cho các biểu thức ngắn hoặc đơn giản)

ví dụ

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
0

không được phép

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
1

5. 5. 4 máy phát điện

Trình tạo cho phép một số trừu tượng hữu ích và có thể được sử dụng khi cần thiết

Khi xác định các hàm tạo, hãy đính kèm

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
31 vào từ khóa
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
01 khi có mặt và tách nó bằng khoảng trắng khỏi tên của hàm. Khi sử dụng lợi nhuận ủy quyền, hãy đính kèm
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
31 vào từ khóa
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
26

Thí dụ

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
2

5. 5. 5 Tham số và kiểu trả về

Các tham số hàm và kiểu trả về thường phải được ghi lại bằng các chú thích JSDoc. Xem để biết thêm thông tin

5. 5. 5. 1 Thông số mặc định

Các tham số tùy chọn được phép sử dụng toán tử bằng trong danh sách tham số. Các tham số tùy chọn phải bao gồm khoảng trắng ở cả hai bên của toán tử bằng, được đặt tên chính xác như các tham số bắt buộc (i. e. , không có tiền tố là

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
26), hãy sử dụng hậu tố
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
27 trong loại JSDoc của chúng, đặt sau các tham số bắt buộc và không sử dụng các trình khởi tạo tạo ra tác dụng phụ có thể quan sát được. Tất cả các tham số tùy chọn cho các chức năng cụ thể phải có giá trị mặc định, ngay cả khi giá trị đó là
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
45. Trái ngược với các hàm cụ thể, các phương thức trừu tượng và giao diện phải bỏ qua các giá trị tham số mặc định

Thí dụ

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
3

Sử dụng các tham số mặc định một cách tiết kiệm. Ưu tiên phá hủy (như trong ) để tạo các API có thể đọc được khi có nhiều hơn một số ít tham số tùy chọn không có thứ tự tự nhiên

Ghi chú. Không giống như các tham số mặc định của Python, bạn có thể sử dụng các trình khởi tạo trả về các đối tượng có thể thay đổi mới (chẳng hạn như

goog.module('search.urlHistory.UrlHistoryService');
81 hoặc
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
52) vì trình khởi tạo được ước tính mỗi khi giá trị mặc định được sử dụng, do đó, một đối tượng sẽ không được chia sẻ giữa các lệnh gọi

Mẹo. Mặc dù các biểu thức tùy ý bao gồm các lệnh gọi hàm có thể được sử dụng làm trình khởi tạo, nhưng chúng nên được giữ càng đơn giản càng tốt. Tránh các trình khởi tạo hiển thị trạng thái có thể thay đổi được chia sẻ, vì điều đó có thể dễ dàng tạo ra sự ghép nối ngoài ý muốn giữa các lệnh gọi hàm

5. 5. 5. 2 Thông số nghỉ ngơi

Sử dụng tham số còn lại thay vì truy cập

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
31. Các tham số còn lại được nhập bằng tiền tố
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
51 trong JSDoc của chúng. Tham số còn lại phải là tham số cuối cùng trong danh sách. Không có khoảng cách giữa
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
51 và tên tham số. Không đặt tên cho tham số còn lại
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
34. Không bao giờ đặt tên biến cục bộ hoặc tham số
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
31, điều này làm mờ tên tích hợp một cách khó hiểu

Thí dụ

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
4

5. 5. 6 thuốc gốc

Khai báo các hàm và phương thức chung khi cần thiết với

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
36 trong JSDoc phía trên định nghĩa hàm hoặc phương thức

5. 5. 7 Toán tử trải rộng

Lời gọi hàm có thể sử dụng toán tử trải rộng (______36_______51). Ưu tiên toán tử trải rộng thành

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
38 khi một mảng hoặc khả năng lặp được giải nén thành nhiều tham số của hàm biến thiên. Không có khoảng trống sau
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
51

Thí dụ

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
5

5. 6 chuỗi ký tự

5. 6. 1 Sử dụng dấu nháy đơn

Chuỗi ký tự thông thường được phân định bằng dấu nháy đơn (

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
40), thay vì dấu nháy kép (
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
41)

Mẹo. nếu một chuỗi chứa một ký tự trích dẫn, hãy cân nhắc sử dụng chuỗi mẫu để tránh phải thoát khỏi trích dẫn

Chuỗi ký tự thông thường không được trải dài trên nhiều dòng

5. 6. 2 Template literals

Sử dụng các ký tự mẫu (được phân tách bằng

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
42) trên cách nối chuỗi phức tạp, đặc biệt nếu có nhiều ký tự chuỗi liên quan. Mẫu chữ có thể kéo dài nhiều dòng

Nếu một mẫu chữ kéo dài nhiều dòng, thì nó không cần phải tuân theo sự thụt lề của khối kèm theo, mặc dù điều đó có thể xảy ra nếu khoảng trắng được thêm vào không thành vấn đề

Thí dụ

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
6

5. 6. 3 Không tiếp tục dòng

Không sử dụng các phần tiếp theo của dòng (nghĩa là kết thúc một dòng bên trong một chuỗi ký tự bằng dấu gạch chéo ngược) bằng ký tự chuỗi thông thường hoặc chuỗi mẫu. Mặc dù ES5 cho phép điều này, nhưng nó có thể dẫn đến các lỗi phức tạp nếu có bất kỳ khoảng trắng ở cuối nào xuất hiện sau dấu gạch chéo và ít rõ ràng hơn đối với người đọc

không được phép

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
7

Thay vào đó, hãy viết

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
8

5. 7 chữ số

Các số có thể được chỉ định ở dạng thập phân, hex, bát phân hoặc nhị phân. Sử dụng chính xác các tiền tố

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
43,
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
44 và
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
45, với các chữ cái viết thường, tương ứng cho hệ thập lục phân, bát phân và nhị phân. Không bao giờ thêm số 0 ở đầu trừ khi ngay sau nó là
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
46,
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
47 hoặc
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
48

5. 8 Cấu trúc điều khiển

5. 8. 1 Đối với các vòng lặp

Với ES6, ngôn ngữ hiện có ba loại vòng lặp

goog.module('search.urlHistory.UrlHistoryService');
75 khác nhau. Tất cả có thể được sử dụng, mặc dù các vòng lặp
goog.module('search.urlHistory.UrlHistoryService');
75-
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
25 nên được ưu tiên hơn khi có thể

Các vòng lặp

goog.module('search.urlHistory.UrlHistoryService');
75-
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
24 chỉ có thể được sử dụng trên các đối tượng kiểu dict (xem phần ) và không được sử dụng để lặp qua một mảng.
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
54 nên được sử dụng trong các vòng lặp
goog.module('search.urlHistory.UrlHistoryService');
75-
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
24 để loại trừ các thuộc tính nguyên mẫu không mong muốn. Ưu tiên ________ 35 _______75-
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
25 và
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
59 hơn ________35 _______75-
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
24 khi có thể

5. 8. 2 ngoại lệ

Ngoại lệ là một phần quan trọng của ngôn ngữ và nên được sử dụng bất cứ khi nào xảy ra trường hợp ngoại lệ. Luôn ném

goog.module('search.urlHistory.UrlHistoryService');
63s hoặc phân lớp của
goog.module('search.urlHistory.UrlHistoryService');
63. không bao giờ ném chuỗi ký tự hoặc các đối tượng khác. Luôn sử dụng
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
64 khi xây dựng một
goog.module('search.urlHistory.UrlHistoryService');
63

Cách xử lý này kéo dài đến các giá trị từ chối của

goog.module('search.urlHistory.UrlHistoryService');
65 vì
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
67 tương đương với
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
68 trong các hàm không đồng bộ

Các ngoại lệ tùy chỉnh cung cấp một cách tuyệt vời để truyền tải thông tin lỗi bổ sung từ các chức năng. Chúng nên được xác định và sử dụng bất cứ khi nào loại

goog.module('search.urlHistory.UrlHistoryService');
63 gốc không đủ

Ưu tiên đưa ra các ngoại lệ hơn các phương pháp xử lý lỗi đặc biệt (chẳng hạn như chuyển loại tham chiếu bộ chứa lỗi hoặc trả về một đối tượng có thuộc tính lỗi)

Rất hiếm khi đúng khi không làm gì để đáp lại một ngoại lệ bị bắt. Khi thực sự thích hợp để không thực hiện bất kỳ hành động nào trong một khối bắt, lý do điều này là hợp lý được giải thích trong một nhận xét

import './sideeffects.js';

import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';

import {name} from './sibling.js';
9

không được phép

import '../directory/file';
0

Tip. Không giống như ở một số ngôn ngữ khác, các mẫu như trên đơn giản là không hoạt động vì điều này sẽ bắt lỗi do

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
70 đưa ra. Sử dụng
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
71 để thay thế

5. 8. 3 Câu lệnh chuyển đổi

Lưu ý thuật ngữ. Bên trong dấu ngoặc nhọn của khối chuyển đổi là một hoặc nhiều nhóm câu lệnh. Mỗi nhóm câu lệnh bao gồm một hoặc nhiều nhãn chuyển đổi (hoặc là

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
72 hoặc là
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
73), theo sau là một hoặc nhiều câu lệnh

5. 8. 3. 1 mùa thu. nhận xét

Trong một khối chuyển đổi, mỗi nhóm câu lệnh hoặc kết thúc đột ngột (với ngoại lệ

goog.module('search.urlHistory.UrlHistoryService');
89,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
21 hoặc
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
22n) hoặc được đánh dấu bằng một nhận xét để chỉ ra rằng việc thực thi sẽ hoặc có thể tiếp tục trong nhóm câu lệnh tiếp theo. Bất kỳ nhận xét nào truyền đạt ý tưởng về sự thất bại là đủ (thường là
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
77). Chú thích đặc biệt này không bắt buộc trong nhóm câu lệnh cuối cùng của khối chuyển đổi

Thí dụ

import '../directory/file';
1
5. 8. 3. 2 Trường hợp
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
78 có mặt

Mỗi câu lệnh chuyển đổi bao gồm một nhóm câu lệnh

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
78, ngay cả khi nó không chứa mã. Nhóm câu lệnh
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
78 phải ở cuối cùng

5. 9 cái này

Only use

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
66 in class constructors and methods, in arrow functions defined within class constructors and methods, or in functions that have an explicit
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
82 declared in the immediately-enclosing function’s JSDoc

Không bao giờ sử dụng

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
66 để chỉ đối tượng chung, bối cảnh của một
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
84, mục tiêu của một sự kiện hoặc các chức năng
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
85ed hoặc
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
86ed không cần thiết

5. 10 kiểm tra bình đẳng

Sử dụng các toán tử nhận dạng (

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
87/
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
88) ngoại trừ các trường hợp được nêu dưới đây

5. 10. 1 Trường hợp ngoại lệ khi ép buộc là mong muốn

Bắt cả hai giá trị

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
89 và
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
45

import '../directory/file';
2

5. 11 tính năng không được phép

5. 11. 1 với

Không sử dụng từ khóa

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
91. Nó làm cho mã của bạn khó hiểu hơn và đã bị cấm ở chế độ nghiêm ngặt kể từ ES5

5. 11. 2 Đánh giá mã động

Không sử dụng

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
84 hoặc hàm tạo
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
93 (ngoại trừ trình tải mã). Các tính năng này có khả năng gây nguy hiểm và đơn giản là không hoạt động trong môi trường CSP

5. 11. 3 Chèn dấu chấm phẩy tự động

Luôn kết thúc câu lệnh bằng dấu chấm phẩy (ngoại trừ khai báo hàm và lớp, như đã lưu ý ở trên)

5. 11. 4 Tính năng phi tiêu chuẩn

Không sử dụng các tính năng không chuẩn. Điều này bao gồm các tính năng cũ đã bị xóa (e. g. ,

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
94), các tính năng mới chưa được chuẩn hóa (e. g. , dự thảo làm việc TC39 hiện tại, các đề xuất ở bất kỳ giai đoạn nào hoặc các tiêu chuẩn web được đề xuất nhưng chưa hoàn chỉnh) hoặc các tính năng độc quyền chỉ được triển khai trong một số trình duyệt. Chỉ sử dụng các tính năng được xác định trong tiêu chuẩn ECMA-262 hoặc WHATWG hiện tại. (Lưu ý rằng các dự án viết dựa trên các API cụ thể, chẳng hạn như tiện ích mở rộng của Chrome hoặc Node. js, rõ ràng có thể sử dụng các API đó). Các "phần mở rộng" ngôn ngữ phi tiêu chuẩn (chẳng hạn như phần mở rộng được cung cấp bởi một số bộ chuyển mã bên ngoài) đều bị cấm

5. 11. 5 đối tượng Wrapper cho các kiểu nguyên thủy

Không bao giờ sử dụng

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
64 trên các trình bao bọc đối tượng nguyên thủy (
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
96,
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
97,
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
98,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
85), cũng như không bao giờ đưa chúng vào chú thích loại

không được phép

import '../directory/file';
3

Các trình bao bọc có thể được gọi là các hàm để ép buộc (được ưu tiên hơn là sử dụng

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
00 hoặc nối chuỗi trống) hoặc tạo ký hiệu

Thí dụ

import '../directory/file';
4

5. 11. 6 Sửa đổi các đối tượng dựng sẵn

Không bao giờ sửa đổi các kiểu dựng sẵn, bằng cách thêm các phương thức vào hàm tạo của chúng hoặc vào nguyên mẫu của chúng. Tránh phụ thuộc vào các thư viện làm điều này. Lưu ý rằng thư viện thời gian chạy của JSCompiler sẽ cung cấp các polyfill tuân thủ tiêu chuẩn nếu có thể;

Không thêm các ký hiệu vào đối tượng toàn cục trừ khi thực sự cần thiết (e. g. được yêu cầu bởi API của bên thứ ba)

5. 11. 7 Bỏ qua
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
01 khi gọi hàm tạo

Không bao giờ gọi hàm tạo trong câu lệnh

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
64 mà không sử dụng dấu ngoặc đơn
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
01

không được phép

import '../directory/file';
5

sử dụng thay thế

import '../directory/file';
6

Bỏ qua dấu ngoặc đơn có thể dẫn đến những sai lầm tinh vi. Hai dòng này không tương đương

import '../directory/file';
7

6 đặt tên

6. 1 Quy tắc chung cho tất cả các định danh

Định danh chỉ sử dụng các chữ cái và chữ số ASCII, và trong một số ít trường hợp được lưu ý bên dưới, dấu gạch dưới và rất hiếm khi (khi được yêu cầu bởi các khung như Angular) ký hiệu đô la

Đặt tên mô tả càng tốt, trong lý do. Đừng lo lắng về việc tiết kiệm không gian theo chiều ngang vì điều quan trọng hơn nhiều là làm cho mã của bạn dễ hiểu ngay lập tức đối với người đọc mới. Không sử dụng các từ viết tắt mơ hồ hoặc không quen thuộc với người đọc bên ngoài dự án của bạn và không viết tắt bằng cách xóa các chữ cái trong một từ

import '../directory/file';
8

không được phép

import '../directory/file';
9

6. 2 Quy tắc theo loại định danh

6. 2. 1 tên gói

Tên gói đều là

goog.module('search.urlHistory.UrlHistoryService');
01. Ví dụ:
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
05, nhưng không phải là
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
06 hoặc
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
07

6. 2. 2 Tên lớp

Tên lớp, giao diện, bản ghi và typedef được viết bằng

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
08. Các lớp chưa được xuất chỉ đơn giản là các lớp cục bộ. chúng không được đánh dấu
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94 và do đó không được đặt tên với dấu gạch dưới

Tên loại thường là danh từ hoặc cụm danh từ. Ví dụ:

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
10,
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
11 hoặc
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
12. Ngoài ra, tên giao diện đôi khi có thể là tính từ hoặc cụm tính từ thay thế (ví dụ:
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
13)

6. 2. 3 Tên phương thức

Tên phương thức được viết bằng

goog.module('search.urlHistory.UrlHistoryService');
01. Tên của phương thức
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94 phải kết thúc bằng dấu gạch dưới

Tên phương thức thường là động từ hoặc cụm động từ. Ví dụ:

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
16 hoặc
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
17. Các phương thức getter và setter cho các thuộc tính không bao giờ được yêu cầu, nhưng nếu chúng được sử dụng thì chúng nên được đặt tên là
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
18 (hoặc tùy chọn là
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
19 hoặc
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
20 đối với booleans) hoặc
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
21 đối với setters

Dấu gạch dưới cũng có thể xuất hiện trong tên phương thức thử nghiệm JsUnit để phân tách các thành phần logic của tên. Một mẫu điển hình là

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
22, ví dụ như
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
23. Không có một cách chính xác nào để đặt tên cho các phương pháp thử nghiệm

6. 2. 4 tên liệt kê

Tên enum được viết bằng

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
08, tương tự như các lớp và thường phải là danh từ số ít. Các mục riêng lẻ trong enum được đặt tên trong
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
25

6. 2. 5 tên không đổi

Tên hằng sử dụng

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
25. tất cả các chữ cái viết hoa, với các từ được phân tách bằng dấu gạch dưới. Không có lý do gì để một hằng số được đặt tên với dấu gạch dưới ở cuối, vì các thuộc tính tĩnh riêng tư có thể được thay thế bằng các cục bộ mô-đun (ngầm riêng tư)

6. 2. 5. 1 Định nghĩa “hằng số”

Mỗi hằng số là một thuộc tính tĩnh

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
96 hoặc một khai báo
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
33 mô-đun-cục bộ, nhưng không phải tất cả các thuộc tính tĩnh
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
96 và
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
33 mô-đun cục bộ đều là hằng số. Trước khi chọn trường hợp không đổi, hãy xem xét liệu trường có thực sự giống như một hằng số bất biến sâu sắc hay không. Ví dụ: nếu bất kỳ trạng thái quan sát được nào của trường hợp đó có thể thay đổi, thì gần như chắc chắn đó không phải là hằng số. Chỉ có ý định không bao giờ thay đổi đối tượng nói chung là không đủ

ví dụ

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
00

Tên hằng thường là danh từ hoặc cụm danh từ

6. 2. 5. 2 Bí danh cục bộ

Các bí danh cục bộ nên được sử dụng bất cứ khi nào chúng cải thiện khả năng đọc so với các tên đủ điều kiện. Thực hiện theo các quy tắc tương tự như

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74s (), giữ nguyên phần cuối của tên bí danh. Bí danh cũng có thể được sử dụng trong các chức năng. Bí danh phải là
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
33

ví dụ

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
01

6. 2. 6 Tên trường không cố định

Tên trường không cố định (tĩnh hoặc cách khác) được viết bằng

goog.module('search.urlHistory.UrlHistoryService');
01, với dấu gạch dưới cho các trường riêng tư

Những tên này thường là danh từ hoặc cụm danh từ. Ví dụ:

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
34 hoặc
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
35

6. 2. 7 tên tham số

Tên tham số được viết bằng

goog.module('search.urlHistory.UrlHistoryService');
01. Lưu ý rằng điều này áp dụng ngay cả khi tham số mong đợi một hàm tạo

Không nên sử dụng tên tham số một ký tự trong các phương thức công khai

Exception. Khi được yêu cầu bởi khung của bên thứ ba, tên tham số có thể bắt đầu bằng

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
37. Ngoại lệ này không áp dụng cho bất kỳ số nhận dạng nào khác (e. g. biến cục bộ hoặc thuộc tính)

6. 2. 8 Tên biến cục bộ

Tên biến cục bộ được viết bằng

goog.module('search.urlHistory.UrlHistoryService');
01, ngoại trừ các hằng số mô-đun-cục bộ (cấp cao nhất), như được mô tả ở trên. Các hằng số trong phạm vi chức năng vẫn được đặt tên trong
goog.module('search.urlHistory.UrlHistoryService');
01. Lưu ý rằng
goog.module('search.urlHistory.UrlHistoryService');
01 được sử dụng ngay cả khi biến chứa hàm tạo

6. 2. 9 Tên tham số mẫu

Tên tham số mẫu phải ngắn gọn, mã định danh một từ hoặc một chữ cái và phải viết hoa toàn bộ, chẳng hạn như

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
41 hoặc
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
42

6. 2. 10 Tên mô-đun cục bộ

Tên mô-đun cục bộ không được xuất hoàn toàn là riêng tư. Chúng không được đánh dấu

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94 và không kết thúc bằng dấu gạch dưới. Điều này áp dụng cho các lớp, hàm, biến, hằng, enum và các mã định danh mô-đun-cục bộ khác

6. 3 Vỏ lạc đà. xác định

Đôi khi, có nhiều cách hợp lý để chuyển đổi một cụm từ tiếng Anh thành trường hợp lạc đà, chẳng hạn như khi có từ viết tắt hoặc cấu trúc bất thường như IPv6 hoặc iOS. Để cải thiện khả năng dự đoán, Google Style chỉ định lược đồ xác định (gần như) sau đây

Bắt đầu với hình thức văn xuôi của tên

  1. Chuyển đổi cụm từ thành ASCII đơn giản và xóa mọi dấu nháy đơn. Ví dụ, thuật toán của Müller có thể trở thành thuật toán của Mueller
  2. Chia kết quả này thành các từ, phân tách trên khoảng trắng và bất kỳ dấu câu nào còn lại (thường là dấu gạch nối)
    1. Khuyến khích. nếu bất kỳ từ nào đã có cách xuất hiện trường hợp lạc đà thông thường trong cách sử dụng phổ biến, hãy chia từ này thành các phần cấu thành của nó (e. g. , AdWords trở thành từ quảng cáo). Lưu ý rằng một từ chẳng hạn như iOS không thực sự ở dạng lạc đà;
  3. Bây giờ viết thường mọi thứ (bao gồm cả từ viết tắt), sau đó chỉ viết hoa ký tự đầu tiên của
    1. … mỗi từ, để tạo ra trường hợp lạc đà trên, hoặc
    2. … mỗi từ ngoại trừ từ đầu tiên, để mang lại trường hợp lạc đà thấp hơn
  4. Cuối cùng, nối tất cả các từ thành một định danh duy nhất

Lưu ý rằng cách viết hoa của các từ gốc gần như hoàn toàn bị bỏ qua

ví dụ

Prose formCorrectIncorrectXML HTTP requestXmlHttpRequestXMLHTTPRequestnew customer IDnewCustomerIdnewCustomerIDinner stopwatchinnerStopwatchinnerStopWatchsupports IPv6 on iOS?supportsIpv6OnIossupportsIPv6OnIOSYouTube importerYouTubeImporterYoutubeImporter*

*Chấp nhận được, nhưng không khuyến khích

Ghi chú. Một số từ được gạch nối một cách mơ hồ trong ngôn ngữ tiếng Anh. ví dụ nonempty và non-empty đều đúng, vì vậy tên phương thức checkNonempty và checkNonEmpty cũng đúng

7 JSDoc

JSDoc được sử dụng trên tất cả các lớp, trường và phương thức

7. 1 Hình thức chung

Định dạng cơ bản của các khối JSDoc như trong ví dụ này

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
02

hoặc trong ví dụ một dòng này

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
03

Nếu nhận xét một dòng tràn thành nhiều dòng, thì nhận xét đó phải sử dụng kiểu nhiều dòng với

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
44 và
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
45 trên các dòng riêng của chúng

Nhiều công cụ trích xuất siêu dữ liệu từ các bình luận JSDoc để thực hiện xác thực và tối ưu hóa mã. Như vậy, những bình luận này phải được hình thành tốt

7. 2 đánh dấu

JSDoc được viết bằng Markdown, mặc dù nó có thể bao gồm HTML khi cần thiết

Lưu ý rằng các công cụ tự động giải nén JSDoc (e. g. JsDossier) thường sẽ bỏ qua định dạng văn bản thuần túy, vì vậy nếu bạn đã làm điều này

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
04

nó sẽ ra như thế này

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
05

Thay vào đó, hãy viết một danh sách Markdown

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
06

Kiểu Google cho phép một tập hợp con các thẻ JSDoc. Xem danh sách đầy đủ. Hầu hết các thẻ phải chiếm dòng riêng của chúng, với thẻ ở đầu dòng

không được phép

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
07

Các thẻ đơn giản không yêu cầu bất kỳ dữ liệu bổ sung nào (chẳng hạn như

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
96,
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
48,
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
49) có thể được kết hợp trên cùng một dòng, cùng với một loại tùy chọn khi thích hợp

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
08

Không có quy tắc cứng nào về thời điểm kết hợp các thẻ hoặc theo thứ tự nào, nhưng phải nhất quán

Để biết thông tin chung về các loại chú thích trong JavaScript, hãy xem Chú thích JavaScript cho Trình biên dịch đóng và Các loại trong Hệ thống loại đóng

7. Gói 4 dòng

Các thẻ khối được ngắt dòng được thụt vào bốn khoảng trắng. Văn bản mô tả được ngắt dòng có thể được xếp thẳng hàng với mô tả trên các dòng trước, nhưng việc căn chỉnh theo chiều ngang này không được khuyến khích

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
09

Không thụt lề khi ngắt dòng mô tả

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
50 hoặc
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
70

Một tệp có thể có tổng quan về tệp cấp cao nhất. Thông báo bản quyền, thông tin tác giả và mặc định là tùy chọn. Tổng quan về tệp thường được khuyến nghị bất cứ khi nào một tệp bao gồm nhiều hơn một định nghĩa lớp. Nhận xét cấp cao nhất được thiết kế để hướng người đọc không quen thuộc với mã đến nội dung trong tệp này. Nếu có, nó có thể cung cấp mô tả về nội dung của tệp và mọi thông tin phụ thuộc hoặc tương thích. Các dòng được bọc không được thụt vào

Thí dụ

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
10

Các lớp, giao diện và bản ghi phải được ghi lại bằng mô tả và mọi tham số mẫu, giao diện được triển khai, khả năng hiển thị hoặc các thẻ thích hợp khác. Mô tả lớp phải cung cấp cho người đọc đủ thông tin để biết cách thức và thời điểm sử dụng lớp, cũng như bất kỳ cân nhắc bổ sung nào cần thiết để sử dụng đúng lớp. Mô tả văn bản có thể được bỏ qua trên hàm tạo. Chú thích

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
52 và
goog.module('search.urlHistory.UrlHistoryService');
88 không được sử dụng với từ khóa
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
97 trừ khi lớp được sử dụng để khai báo một
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
05 hoặc nó mở rộng một lớp chung

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
11

Tất cả các enum và typedef phải được ghi lại bằng các thẻ JSDoc thích hợp (

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
56 hoặc
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
73) ở dòng trước. Công khai enums và typedefs cũng phải có một mô tả. Các mục enum riêng lẻ có thể được ghi lại bằng nhận xét JSDoc trên dòng trước

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
12

Typedefs rất hữu ích để xác định các loại bản ghi ngắn hoặc bí danh cho các liên kết, các hàm phức tạp hoặc các loại chung. Typedefs nên tránh đối với các loại bản ghi có nhiều trường, vì chúng không cho phép ghi lại các trường riêng lẻ, cũng như không sử dụng mẫu hoặc tham chiếu đệ quy. Đối với các loại bản ghi lớn, hãy ưu tiên

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
06

Trong các phương thức và hàm được đặt tên, tham số và kiểu trả về phải được ghi lại, ngoại trừ trường hợp của các

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
59 có cùng chữ ký, trong đó tất cả các kiểu được bỏ qua. Loại
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
66 phải được ghi lại khi cần thiết. Kiểu trả về có thể được bỏ qua nếu hàm không có câu lệnh
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
21 không trống

Các mô tả phương thức, tham số và trả về (nhưng không phải kiểu) có thể bị bỏ qua nếu chúng hiển nhiên từ phần còn lại của JSDoc của phương thức hoặc từ chữ ký của nó

Mô tả phương thức bắt đầu bằng một cụm động từ mô tả chức năng của phương thức. Cụm từ này không phải là một câu mệnh lệnh, mà thay vào đó được viết ở ngôi thứ ba, như thể có một ngụ ý. trước nó

Nếu một phương thức ghi đè một phương thức của lớp bậc trên, nó phải bao gồm một chú thích

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
59. Các phương thức bị ghi đè kế thừa tất cả các chú thích JSDoc từ phương thức siêu hạng (bao gồm cả các chú thích khả năng hiển thị) và chúng nên được bỏ qua trong phương thức bị ghi đè. Tuy nhiên, nếu bất kỳ loại nào được tinh chỉnh trong chú thích loại, thì tất cả chú thích
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
63 và
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
64 phải được chỉ định rõ ràng

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
13

Nếu bạn chỉ cần ghi lại thông số và kiểu trả về của hàm, bạn có thể tùy ý sử dụng JSDocs nội tuyến trong chữ ký của hàm. Các JSDoc nội tuyến này chỉ định các loại trả về và thông số không có thẻ

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
14

Nếu bạn cần mô tả hoặc thẻ, hãy sử dụng một nhận xét JSDoc duy nhất phía trên phương thức. Ví dụ: các phương thức trả về giá trị cần thẻ

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
64

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
15
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
16

Trong các chú thích chức năng ẩn danh thường là tùy chọn. Nếu suy luận loại tự động không đủ hoặc chú thích rõ ràng cải thiện khả năng đọc, thì hãy chú thích thông số và trả về các loại như thế này

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
17

Đối với các biểu thức loại chức năng, xem

Các loại tài sản phải được ghi lại. Mô tả có thể được bỏ qua đối với các thuộc tính riêng tư, nếu tên và loại cung cấp đủ tài liệu để hiểu mã

Các hằng số được xuất công khai được nhận xét giống như các thuộc tính

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
18

7. 10 Loại chú thích

Chú thích loại được tìm thấy trên các thẻ

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
63,
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
64,
goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
82 và
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
69 và tùy chọn trên thẻ
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
96,
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
49 và bất kỳ thẻ hiển thị nào. Các chú thích loại được đính kèm với các thẻ JSDoc phải luôn được đặt trong dấu ngoặc nhọn

7. 10. 1 Nullability

Hệ thống loại định nghĩa các công cụ sửa đổi lần lượt là

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
72 và
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
73 cho non-null và nullable. Các công cụ sửa đổi này phải đứng trước loại

Công cụ sửa đổi tính vô hiệu có các yêu cầu khác nhau đối với các loại khác nhau, được chia thành hai loại chính

  1. Chú thích loại cho nguyên thủy (_______52_______74,
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    75,
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    76,
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    77,
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    45,
    goog.module('my.test.helpers');
    goog.module.declareLegacyNamespace();
    goog.setTestOnly();
    
    89) và chữ (
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    80 và
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    81) luôn không thể vô hiệu theo mặc định. Sử dụng công cụ sửa đổi
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    73 để biến nó thành null, nhưng bỏ qua phần dư thừa
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    72
  2. Các loại tham chiếu (nói chung, mọi thứ trong
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    08, bao gồm cả
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    85) đề cập đến một lớp, enum, bản ghi hoặc typedef được xác định ở nơi khác. Vì các loại này có thể có hoặc không thể vô hiệu hóa, nên không thể chỉ từ cái tên mà biết nó có thể vô hiệu hóa hay không. Luôn sử dụng các công cụ sửa đổi rõ ràng
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    73 và
    const /** !Array */ exportedArray = [1, 2, 3];
    
    const /** !Array */ moduleLocalArray = [4, 5, 6];
    
    /** @return {number} */
    function moduleLocalFunction() {
      return moduleLocalArray.length;
    }
    
    /** @return {number} */
    function exportedFunction() {
      return moduleLocalFunction() * 2;
    }
    
    exports = {exportedArray, exportedFunction};
    
    72 cho các loại này để tránh sự mơ hồ tại các trang web sử dụng

Xấu

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
19

Tốt

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
20

7. 10. 2 loại phôi

Trong trường hợp trình biên dịch không suy luận chính xác loại biểu thức và các hàm xác nhận trong goog. khẳng định không thể khắc phục nó, có thể thắt chặt loại bằng cách thêm nhận xét chú thích loại và đặt biểu thức trong ngoặc đơn. Lưu ý rằng dấu ngoặc đơn là bắt buộc

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
21

7. 10. 3 loại tham số mẫu

Luôn chỉ định tham số mẫu. Bằng cách này, trình biên dịch có thể thực hiện công việc tốt hơn và giúp người đọc dễ dàng hiểu mã làm gì hơn

Xấu

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
22

Tốt

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
23

Các trường hợp không nên sử dụng tham số mẫu

  • goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    50 được sử dụng cho phân cấp kiểu và không phải là cấu trúc giống như bản đồ

7. 10. 4 Biểu thức kiểu hàm

Terminology Note. function type expression refers to a type annotation for function types with the keyword

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
01 in the annotation (see examples below)

Where the function definition is given, do not use a function type expression. Specify parameter and return types with

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
63 and
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
64, or with inline annotations (see ). This includes anonymous functions and functions defined and assigned to a const (where the function jsdoc appears above the whole assignment expression)

Function type expressions are needed, for example, inside

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
56,
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
63 or
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
64. Use it also for variables or properties of function type, if they are not immediately initialized with the function definition

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
24

When using a function type expression, always specify the return type explicitly. Otherwise the default return type is unknown (

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
73), which leads to strange and unexpected behavior, and is rarely what is actually desired

Bad - type error, but no warning given

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
25

Tốt

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
26

7. 10. 5 Whitespace

Within a type annotation, a single space or line break is required after each comma or colon. Additional line breaks may be inserted to improve readability or avoid exceeding the column limit. These breaks should be chosen and indented following the applicable guidelines (e. g. and ). No other whitespace is allowed in type annotations

Tốt

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
27

Xấu

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
28

7. 11 Visibility annotations

Visibility annotations (

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
79,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
78) may be specified in a
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
70 block, or on any exported symbol or property. Do not specify visibility for local variables, whether within a function or at the top level of a module. All
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94 names must end with an underscore

8 Policies

8. 1 Issues unspecified by Google Style. Hãy nhất quán

For any style question that isn't settled definitively by this specification, prefer to do what the other code in the same file is already doing. If that doesn't resolve the question, consider emulating the other files in the same package

8. 2 Compiler warnings

8. 2. 1 Use a standard warning set

As far as possible projects should use

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
01

8. 2. 2 How to handle a warning

Before doing anything, make sure you understand exactly what the warning is telling you. If you're not positive why a warning is appearing, ask for help

Once you understand the warning, attempt the following solutions in order

  1. First, fix it or work around it. Make a strong attempt to actually address the warning, or find another way to accomplish the task that avoids the situation entirely
  2. Otherwise, determine if it's a false alarm. If you are convinced that the warning is invalid and that the code is actually safe and correct, add a comment to convince the reader of this fact and apply the
    /** @const {number} */
    exports.CONSTANT_ONE = 1;
    
    /** @const {string} */
    exports.CONSTANT_TWO = 'Another constant';
    
    02 annotation
  3. Nếu không, hãy để lại nhận xét TODO. This is a last resort. If you do this, do not suppress the warning. The warning should be visible until it can be taken care of properly

8. 2. 3 Suppress a warning at the narrowest reasonable scope

Warnings are suppressed at the narrowest reasonable scope, usually that of a single local variable or very small method. Often a variable or method is extracted for that reason alone

Thí dụ

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
29

Even a large number of suppressions in a class is still better than blinding the entire class to this type of warning

Mark deprecated methods, classes or interfaces with

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
03 annotations. A deprecation comment must include simple, clear directions for people to fix their call sites

8. 4 Code not in Google Style

You will occasionally encounter files in your codebase that are not in proper Google Style. These may have come from an acquisition, or may have been written before Google Style took a position on some issue, or may be in non-Google Style for any other reason

8. 4. 1 Reformatting existing code

When updating the style of existing code, follow these guidelines

  1. It is not required to change all existing code to meet current style guidelines. Reformatting existing code is a trade-off between code churn and consistency. Style rules evolve over time and these kinds of tweaks to maintain compliance would create unnecessary churn. However, if significant changes are being made to a file it is expected that the file will be in Google Style
  2. Be careful not to allow opportunistic style fixes to muddle the focus of a CL. If you find yourself making a lot of style changes that aren’t critical to the central focus of a CL, promote those changes to a separate CL

8. 4. 2 Newly added code. use Google Style

Brand new files use Google Style, regardless of the style choices of other files in the same package

When adding new code to a file that is not in Google Style, reformatting the existing code first is recommended, subject to the advice in

If this reformatting is not done, then new code should be as consistent as possible with existing code in the same file, but must not violate the style guide

8. 5 Local style rules

Teams and projects may adopt additional style rules beyond those in this document, but must accept that cleanup changes may not abide by these additional rules, and must not block such cleanup changes due to violating any additional rules. Beware of excessive rules which serve no purpose. The style guide does not seek to define style in every possible scenario and neither should you

8. 6 Generated code. mostly exempt

Source code generated by the build process is not required to be in Google Style. However, any generated identifiers that will be referenced from hand-written source code must follow the naming requirements. Là một ngoại lệ đặc biệt, các số nhận dạng như vậy được phép chứa dấu gạch dưới, điều này có thể giúp tránh xung đột với các số nhận dạng viết tay

9 Appendices

9. 1 JSDoc tag reference

JSDoc serves multiple purposes in JavaScript. In addition to being used to generate documentation it is also used to control tooling. The best known are the Closure Compiler type annotations

9. 1. 1 Type annotations and other Closure Compiler annotations

Documentation for JSDoc used by the Closure Compiler is described in Annotating JavaScript for the Closure Compiler and Types in the Closure Type System

9. 1. 2 Documentation annotations

In addition to the JSDoc described in Annotating JavaScript for the Closure Compiler the following tags are common and well supported by various documentation generation tools (such as JsDossier) for purely documentation purposes

You may also see other types of JSDoc annotations in third-party code. These annotations appear in the JSDoc Toolkit Tag Reference but are not considered part of valid Google style

9. 1. 2. 1
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
04 or
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
05 - Not recommended

Not recommended

Syntax.

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
06

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
30

Documents the author of a file or the owner of a test, generally only used in the

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
70 comment. The
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
05 tag is used by the unit test dashboard to determine who owns the test results

9. 1. 2. 2
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
09

Syntax.

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
10

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
31

Indicates what bugs the given test function regression tests

Multiple bugs should each have their own

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
09 line, to make searching for regression tests as easy as possible

9. 1. 2. 3
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
12 - Không dùng nữa. Không được dùng

không dùng nữa. Không được dùng. Sử dụng backticks Markdown để thay thế

cú pháp.

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
13

Trong lịch sử,

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
14 được viết là
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
15

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
32

Cho biết rằng một thuật ngữ trong mô tả JSDoc là mã để nó có thể được định dạng chính xác trong tài liệu được tạo

9. 1. 2. 4
const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
50

Syntax.

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
17

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
33
9. 1. 2. 5
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
18

Syntax.

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
19

This tag is used to generate cross-reference links within generated documentation

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
34

Historical note. @link tags have also been used to create external links in generated documentation. For external links, always use Markdown's link syntax instead

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
35
9. 1. 2. 6
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
20

Syntax.

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
21

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
36

Reference a lookup to another class function or method

9. 1. 2. 7
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
22

Syntax.

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
23

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
37

Used in a fileoverview to indicate what browsers are supported by the file

9. 1. 3 Framework specific annotations

Các chú thích sau đây dành riêng cho một khung cụ thể

9. 1. 3. 1
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
24 cho Góc 1
9. 1. 3. 2
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
25 for Polymer

https. //github. com/google/closure-compiler/wiki/Polymer-Pass

9. 1. 4 Notes about standard Closure Compiler annotations

The following tags used to be standard but are now deprecated

9. 1. 4. 1
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
26 - Deprecated. Do not use

Deprecated. Do not use. Use

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
49 and/or
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
87 instead

9. 1. 4. 2
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
29 - Deprecated. Do not use

Deprecated. Do not use. Sử dụng

const /** !Array */ exportedArray = [1, 2, 3];

const /** !Array */ moduleLocalArray = [4, 5, 6];

/** @return {number} */
function moduleLocalFunction() {
  return moduleLocalArray.length;
}

/** @return {number} */
function exportedFunction() {
  return moduleLocalFunction() * 2;
}

exports = {exportedArray, exportedFunction};
59 để thay thế

9. 2 Commonly misunderstood style rules

Here is a collection of lesser-known or commonly misunderstood facts about Google Style for JavaScript. (The following are true statements; this is not a list of myths. )

  • Neither a copyright statement nor
    /** @const {number} */
    exports.CONSTANT_ONE = 1;
    
    /** @const {string} */
    exports.CONSTANT_TWO = 'Another constant';
    
    04 credit is required in a source file. (Neither is explicitly recommended, either. )
  • There is no hard and fast rule governing how to order the members of a class ()
  • Empty blocks can usually be represented concisely as
    goog.module('search.urlHistory.UrlHistoryService');
    
    81, as detailed in ()
  • The prime directive of line-wrapping is. prefer to break at a higher syntactic level ()
  • Non-ASCII characters are allowed in string literals, comments and JSDoc, and in fact are recommended when they make the code easier to read than the equivalent Unicode escape would ()

The following tools exist to support various aspects of Google Style

9. 3. 1 Closure Compiler

This program performs type checking and other checks, optimizations and other transformations (such as ECMAScript 6 to ECMAScript 5 code lowering)

9. 3. 2
goog.module('search.urlHistory.UrlHistoryService');
71

This program reformats JavaScript source code into Google Style, and also follows a number of non-required but frequently readability-enhancing formatting practices. The output produced by

goog.module('search.urlHistory.UrlHistoryService');
71 is compliant with the style guide

goog.module('search.urlHistory.UrlHistoryService');
71 is not required. Authors are allowed to change its output, and reviewers are allowed to ask for such changes; disputes are worked out in the usual way. However, subtrees may choose to opt in to such enforcement locally

9. 3. 3 Closure compiler linter

This program checks for a variety of missteps and anti-patterns

9. 3. 4 Conformance framework

The JS Conformance Framework is a tool that is part of the Closure Compiler that provides developers a simple means to specify a set of additional checks to be run against their code base above the standard checks. Conformance checks can, for example, forbid access to a certain property, or calls to a certain function, or missing type information (unknowns)

These rules are commonly used to enforce critical restrictions (such as defining globals, which could break the codebase) and security patterns (such as using

goog.module('my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();
84 or assigning to
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
37), or more loosely to improve code quality

For additional information see the official documentation for the JS Conformance Framework

9. 4 Exceptions for legacy platforms

9. 4. 1 Overview

This section describes exceptions and additional rules to be followed when modern ECMAScript 6 syntax is not available to the code authors. Exceptions to the recommended style are required when ECMAScript 6 syntax is not possible and are outlined here

  • Use of
    goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
    goog.module('foo.bar.baz');
    
    37 declarations is allowed
  • Use of
    goog.module('my.test.helpers');
    goog.module.declareLegacyNamespace();
    goog.setTestOnly();
    
    31 is allowed
  • Optional parameters without default values are allowed

9. 4. 2 Use
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
37

9. 4. 2. 1
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
37 declarations are NOT block-scoped

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
37 declarations are scoped to the beginning of the nearest enclosing function, script or module, which can cause unexpected behavior, especially with function closures that reference
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
37 declarations inside of loops. The following code gives an example

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
38
9. 4. 2. 2 Declare variables as close as possible to first use

Even though

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
37 declarations are scoped to the beginning of the enclosing function,
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
37 declarations should be as close as possible to their first use, for readability purposes. However, do not put a
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
37 declaration inside a block if that variable is referenced outside the block. For example

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
39
9. 4. 2. 3 Use @const for constants variables

For global declarations where the

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
33 keyword would be used, if it were available, annotate the
goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
37 declaration with @const instead (this is optional for local variables)

9. 4. 3 Do not use block scoped functions declarations

Do not do this

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
40

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

To get consistent behavior, instead use a

goog.module('foo.bar');   // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
37 initialized with a function expression to define a function within a block

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
41

9. 4. 4 Dependency management with
goog.module('search.urlHistory.UrlHistoryService');
18/
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74

9. 4. 4. 1 Summary

WARNING.

goog.module('search.urlHistory.UrlHistoryService');
18 dependency management is deprecated. All new files, even in projects using
goog.module('search.urlHistory.UrlHistoryService');
18 for older files, should use . The following rules are for pre-existing
goog.module('search.urlHistory.UrlHistoryService');
18 files only

  • Place all
    goog.module('search.urlHistory.UrlHistoryService');
    
    18s first,
    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    74s second. Separate provides from requires with an empty line
  • Sort the entries alphabetically (uppercase first)
  • Don't wrap
    goog.module('search.urlHistory.UrlHistoryService');
    
    18 and
    /* Poor: the reader has no idea what character this is. */
    const units = '\u03bcs';
    
    74 statements. Exceed 80 columns if necessary
  • Only provide top-level symbols

goog.module('search.urlHistory.UrlHistoryService');
18 statements should be grouped together and placed first. All
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 statements should follow. The two lists should be separated with an empty line

Similar to import statements in other languages,

goog.module('search.urlHistory.UrlHistoryService');
18 and
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 statements should be written in a single line, even if they exceed the 80 column line length limit

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

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
42

All members defined on a class should be in the same file. 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)

Làm cái này

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
43

Không phải cái này

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
44

Thành viên trên không gian tên cũng có thể được cung cấp

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
45
9. 4. 4. 2 Aliasing with
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
64

WARNING.

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
64 is deprecated. New files should not use
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
64 even in projects with existing
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
64 usage

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
64 may be used to shorten references to namespaced symbols in code using
goog.module('search.urlHistory.UrlHistoryService');
18/
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 dependency management

Only one

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
64 invocation may be added per file. Always place it in the global scope

The opening

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
72 invocation must be preceded by exactly one blank line and follow any
goog.module('search.urlHistory.UrlHistoryService');
18 statements,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 statements, or top-level comments. The invocation must be closed on the last line in the file. Append
/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
75 to the closing statement of the scope. Separate the comment from the semicolon by two spaces

Similar to C++ namespaces, do not indent under

/** @const {number} */
exports.CONSTANT_ONE = 1;

/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
64 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 for how to alias a constructor)

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
46

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

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
47
9. 4. 4. 3
goog.module('search.urlHistory.UrlHistoryService');
25

Prefer to use

/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 instead of
goog.module('search.urlHistory.UrlHistoryService');
25 to break circular dependencies between files in the same library. Unlike
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74, a
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 statement is allowed to import a namespace before it is defined

goog.module('search.urlHistory.UrlHistoryService');
25 may still be used in legacy code to break circular references spanning across library boundaries, but newer code should be structured to avoid it

goog.module('search.urlHistory.UrlHistoryService');
25 statements must follow the same style rules as
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 and
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75. The entire block of
goog.module('search.urlHistory.UrlHistoryService');
25,
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 and
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 statements is sorted alphabetically