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
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ỉ là các vấn đề thẩm mỹ về định dạng mà còn các loại quy ước hoặc tiêu chuẩn mã hóa 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
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
48/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs';
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';
512. 2 Mã hóa tập tin. UTF-8
Source files are encoded in UTF-8
2. 3 Special characters
2. 3. 1 Whitespace characters
Aside from the line terminator sequence, the ASCII horizontal space character [0x20] is the only whitespace character that appears anywhere in a source file. This implies that
All other whitespace characters in string literals are escaped, and
Tab characters are not used for indentation
2. 3. 2 Special escape sequences
For any character that has a special escape sequence [
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
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], that sequence is used rather than the corresponding numeric escape [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, or /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
63]. Legacy octal escapes are never used2. 3. 3 Non-ASCII characters
For the remaining non-ASCII characters, either the actual Unicode character [e. g.
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
64] or the equivalent hex or Unicode escape [e. g. /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
65] is used, depending only on which makes the code easier to read and understandMẹo. In the Unicode escape case, and occasionally even when actual Unicode characters are used, an explanatory comment can be very helpful
/* 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';
Tip. Never make your code less readable simply out of fear that some programs might not handle non-ASCII characters properly. 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ự- Thông tin giấy phép hoặc bản quyền, nếu có
70 JSDoc, nếu có/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs';
- Câu lệnh
66, nếu tệp/* 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';
- ES
68 câu lệnh, nếu một mô-đun ES/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs';
- Câu lệnh
74 và/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs';
75/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs';
- 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ừ phần triển khai của 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ó
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
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ố
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
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ộtToà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
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
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, 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
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
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ậpCá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ácimport './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ậpPhần mở rộng tệp
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
51 không phải là tùy chọn trong đường dẫn nhập và phải luôn được đưa vàoimport '../directory/file';
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
0Khô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';
13. 4. 1. 3 Đặt tên nhập khẩu3. 4. 1. 3. 1 Nhập mô-đun đặt tênTê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 Đặt tên nhập khẩu mặc địnhTê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';
4Ghi 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ênNói chung, các ký hiệu được nhập thông qua quá trình nhập có tên [
goog.module['search.urlHistory.UrlHistoryService'];
02] nên giữ nguyên tên. 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';
5Nế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 hoặc đường dẫn tệp 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';
63. 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 Xuất khẩu được đặt tên và mặc địnhSử 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'];
07Không sử dụng xuất khẩu mặc định. 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';
93. 4. 2. 2 Xuất các lớp và đối tượng vùng chứa tĩnhKhông xuất các lớp hoặc đối tượng vùng chứa bằng các phương thức hoặc thuộc tính tĩnh vì mục đích tạo không gian tên
goog.module['search.urlHistory.UrlHistoryService'];
0Thay vào đó, hãy xuất các hằng số và hàm riêng lẻ
goog.module['search.urlHistory.UrlHistoryService'];
13. 4. 2. 3 Tính biến động của hàng xuất khẩuCác biến đã xuất không được thay đổi bên ngoài quá trình khởi tạo mô-đun
Có các lựa chọn thay thế nếu cần thay đổi, bao gồm xuất một tham chiếu không đổi đến một đối tượng có các trường có thể thay đổi hoặc xuất các hàm truy cập cho dữ liệu có thể thay đổi
goog.module['search.urlHistory.UrlHistoryService'];
2goog.module['search.urlHistory.UrlHistoryService'];
33. 4. 2. 4 xuất khẩu từCác câu lệnh
goog.module['search.urlHistory.UrlHistoryService'];
08 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. Điều này áp dụng cho cả hương vị goog.module['search.urlHistory.UrlHistoryService'];
08goog.module['search.urlHistory.UrlHistoryService'];
43. 4. 3 vòng phụ thuộc trong các mô-đun ES
Không tạo chu kỳ giữa các mô-đun ES, mặc dù đặc tả ECMAScript cho phép điều này. Lưu ý rằng có thể tạo chu trình bằng cả câu lệnh
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
68 và /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
69goog.module['search.urlHistory.UrlHistoryService'];
5goog.module['search.urlHistory.UrlHistoryService'];
6goog.module['search.urlHistory.UrlHistoryService'];
73. 4. 4 Tương tác với Đóng cửa
3. 4. 4. 1 Tham khảo googleĐể tham chiếu không gian tên Closure
goog.module['search.urlHistory.UrlHistoryService'];
12, nhập Closure's goog.module['search.urlHistory.UrlHistoryService'];
13goog.module['search.urlHistory.UrlHistoryService'];
8goog.module['search.urlHistory.UrlHistoryService'];
13 chỉ xuất một tập hợp con các thuộc tính từ goog.module['search.urlHistory.UrlHistoryService'];
12 toàn cầu có thể được sử dụng trong các mô-đun ES3. 4. 4. 2 tốt. yêu cầu trong các mô-đun ESCác mô-đun
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 trong ES hoạt động giống như trong các tệp /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66. Bạn có thể yêu cầu bất kỳ ký hiệu không gian tên Closure nào [i. e. , các ký hiệu được tạo bởi goog.module['search.urlHistory.UrlHistoryService'];
18 hoặc /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66] và /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 sẽ trả về giá trịgoog.module['search.urlHistory.UrlHistoryService'];
93. 4. 4. 3 Khai báo ID mô-đun đóng trong mô-đun ESCó thể sử dụng
goog.module['search.urlHistory.UrlHistoryService'];
21 trong các mô-đun ES để khai báo ID mô-đun giống như /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66. Điều này có nghĩa là ID mô-đun này có thể là /* 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, v.v. như thể đó là một /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 không gọi cho /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
81. Nó không tạo ID mô-đun dưới dạng biểu tượng JavaScript có sẵn trên toàn cầuMột
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 [hoặc goog.module['search.urlHistory.UrlHistoryService'];
24] cho ID mô-đun từ goog.module['search.urlHistory.UrlHistoryService'];
21 sẽ luôn trả về đối tượng mô-đun [như thể nó là goog.module['search.urlHistory.UrlHistoryService'];
04'd]. Kết quả là, đối số của goog.module['search.urlHistory.UrlHistoryService'];
21 phải luôn kết thúc bằng ____35_______33Ghi chú. Có lỗi khi gọi
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
81 trong mô-đun ES, nó chỉ có thể được gọi từ tệp /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66. Không có cách nào trực tiếp để liên kết một không gian tên kế thừa với một mô-đun ESChỉ nên sử dụng
goog.module['search.urlHistory.UrlHistoryService'];
21 để nâng cấp tệp Đóng lên mô-đun ES tại chỗ, nơi sử dụng xuất khẩu có têngoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
03. 5 goog.module['search.urlHistory.UrlHistoryService'];
37
goog.module['search.urlHistory.UrlHistoryService'];
Trong tệp
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66, câu lệnh /* 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 goog.module['search.urlHistory.UrlHistoryService'];
40Trong một mô-đun ES, các câu lệnh
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
68 có thể tùy chọn được theo sau bởi một cuộc gọi tới goog.module['search.urlHistory.UrlHistoryService'];
403. 6 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
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
Nhập khẩu được thực hiện với 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. Các tên được nhập bởi câu lệnh /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 có thể được sử dụng cả trong mã và chú thích loại, trong khi những tên được nhập bởi một /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 chỉ có thể được sử dụng trong chú thích loạiCác 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 tạo thành một khối liền kề không có dòng trống. Khối này theo tuyên bố /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 được tách ra. Toàn bộ đối số của /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 hoặc /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 là một không gian tên được xác định bởi một /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
66 trong một tệp riêng biệt. Các 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 không được xuất hiện ở bất kỳ nơi nào khác trong tệpMỗi
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 hoặc /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 được gán cho một bí danh cố định duy nhất hoặc nếu không sẽ bị hủy cấu trúc thành một số bí danh cố định. Các bí danh này là cách duy nhất được chấp nhận để chỉ các phụ thuộc trong chú thích loại hoặc mã. Không được sử dụng các không gian tên đủ điều kiện ở bất kỳ đâu, ngoại trừ làm đối số cho /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 hoặc /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75Ngoại lệ. 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ã
Bí danh phải khớp với thành phần cuối cùng được phân tách bằng dấu chấm trong không gian tên của mô-đun đã nhập
Ngoại lệ. Trong một số trường hợp nhất định, các thành phần bổ sung của không gian tên có thể được sử dụng để tạo bí danh dài hơn. Bí danh kết quả phải giữ lại cách viết hoa của mã định danh ban đầu để nó vẫn xác định chính xác loại của nó. Các bí danh dài hơn có thể được sử dụng để phân biệt các bí danh giống hệt nhau hoặc nếu nó cải thiện đáng kể khả năng đọc. Ngoài ra, một bí danh dài hơn phải được sử dụng để ngăn che giấu các loại bản địa, chẳng hạn như
goog.module['search.urlHistory.UrlHistoryService'];
61, goog.module['search.urlHistory.UrlHistoryService'];
62, goog.module['search.urlHistory.UrlHistoryService'];
63, goog.module['search.urlHistory.UrlHistoryService'];
64 và goog.module['search.urlHistory.UrlHistoryService'];
65 [để biết danh sách đầy đủ hơn, hãy xem API web và đối tượng tích hợp sẵn tiêu chuẩn tại MDN]. Khi đổi tên các bí danh bị hủy cấu trúc, một khoảng trắng phải theo sau dấu hai chấm theo yêu cầu trongMột tệp không được chứa cả câu lệnh
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74 và câu lệnh /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
75 cho cùng một không gian tên. Nếu tên đã nhập được sử dụng cả trong chú thích mã và loại, thì tên đó phải được nhập bằng một câu lệnh /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74Nếu một mô-đun được nhập chỉ vì tác dụng phụ của nó, lệnh gọi phải là __________74 [không phải __________75] và phép gán có thể bị bỏ qua. Cần có một bình luận để giải thích lý do tại sao điều này là cần thiết và loại bỏ cảnh báo của trình biên dịch
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 đều đượ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, một lần nữa được sắp xếp 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'];
1nản lòng
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
2không được phép
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
33. 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ến4. 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'];
4Ngoạ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'];
54. 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'];
64. 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'];
7không được phép
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
84. 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'];
9goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
0Cá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[];
1goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
24. 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ẫuThí dụ
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
3goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
44. 2. 4 Biểu thức hàm
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[];
54. 2. 5 Câu lệnh chuyển đổi
Như với bất kỳ khối nào khác, nội dung của khối chuyển đổi được thụt vào +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ở. Một khối rõ ràng có thể được sử dụng nếu được yêu cầu bởi phạm vi từ vựng. 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
Một dòng trống là tùy chọn giữa một
goog.module['search.urlHistory.UrlHistoryService'];
89 và trường hợp sauThí dụ
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
64. 3 Tuyên bố
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 dấu chấm phẩy là bắt buộc
Mọi câu lệnh phải được kết thúc bằng dấu chấm phẩy. Dựa vào chèn dấu chấm phẩy tự động bị cấm
4. 4 Giới hạn cột. 80
Mã JavaScript có giới hạn cột là 80 ký tự. 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
ngoại lệ
- Câu lệnh
66,/* 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 [xem và ]/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs';
- Câu lệnh mô-đun ES
68 và/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs';
08 [xem và ]goog.module['search.urlHistory.UrlHistoryService'];
- Các dòng không thể tuân theo giới hạn cột hoặc sẽ cản trở khả năng khám phá. Những ví dụ bao gồm
- Một URL dài có thể nhấp được trong nguồn
- Một lệnh trình bao dự định được sao chép và dán
- Một chuỗi ký tự dài có thể cần được sao chép hoặc tìm kiếm toàn bộ [e. g. , một đường dẫn tệp dài]
4. 5 Đóng gói dòng
Lưu ý thuật ngữ. Ngắt dòng đang chia một đoạn mã thành nhiều dòng để tuân theo giới hạn của cột, trong đó đoạn mã đó có thể nằm gọn trong một dòng một cách hợp pháp
Không có công thức toàn diện, xác định nào chỉ ra chính xác cách ngắt dòng trong mọi tình huống. Rất thường có một số cách hợp lệ để ngắt dòng cùng một đoạn mã
Ghi chú. Mặc dù lý do điển hình của việc ngắt dòng là để tránh vượt quá giới hạn cột, nhưng ngay cả mã thực tế phù hợp với giới hạn cột cũng có thể được ngắt dòng theo quyết định của tác giả
Mẹo. 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 Nơi để phá vỡ
Chỉ thị chính của line-wrapping là. thích phá vỡ ở cấp độ cú pháp cao hơn
ưa thích
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
7nản lòng
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
8Trong ví dụ trước, các mức cú pháp từ cao nhất đến thấp nhất như sau. gán, chia, gọi hàm, tham số, hằng số
Toán tử được gói như sau
- Khi một dòng bị ngắt tại một toán tử, dấu ngắt xuất hiện sau ký hiệu. [Lưu ý rằng đây không phải là cách làm tương tự được sử dụng theo phong cách Google dành cho Java. ]
- Điều này không áp dụng cho dấu chấm [
95], thực ra không phải là toán tửgoog.module['search.urlHistory.UrlHistoryService'];
- Điều này không áp dụng cho dấu chấm [
- Tên phương thức hoặc hàm tạo được gắn vào dấu ngoặc đơn mở [
96] theo sau nógoog.module['search.urlHistory.UrlHistoryService'];
- Dấu phẩy [
97] được gắn vào mã thông báo đứng trước nógoog.module['search.urlHistory.UrlHistoryService'];
Ghi chú. Mục tiêu chính của việc ngắt dòng là có mã rõ ràng, không nhất thiết là mã phù hợp với số lượng dòng nhỏ nhất
4. 5. 2 dòng tiếp tục thụt lề ít nhất +4 dấu cách
Khi ngắt dòng, mỗi dòng sau dòng đầu tiên [mỗi dòng tiếp theo] được thụt vào ít nhất +4 so với dòng ban đầu, trừ khi nó tuân theo quy tắc thụt lề khối
Khi có nhiều dòng tiếp tục, thụt đầu dòng có thể thay đổi ngoài +4 khi thích hợp. Nói chung, các dòng tiếp tục ở cấp độ cú pháp sâu hơn được thụt vào bởi các bội số lớn hơn của 4 và hai dòng sử dụng cùng một mức độ thụt đầu dòng khi và chỉ khi chúng bắt đầu bằng các yếu tố song song về mặt cú pháp
giải quyết thực tiễn không khuyến khích sử dụng một số khoảng trắng khác nhau để căn chỉnh các mã thông báo nhất định với các dòng trước đó
4. 6 Khoảng trắng
4. 6. 1 Khoảng trắng dọc
Một dòng trống duy nhất xuất hiện
- Giữa các phương thức liên tiếp trong một lớp hoặc đối tượng theo nghĩa đen
- Ngoại lệ. Một dòng trống giữa hai định nghĩa thuộc tính liên tiếp trong một đối tượng bằng chữ [không có mã nào khác giữa chúng] là tùy chọn. Các dòng trống như vậy được sử dụng khi cần thiết để tạo các nhóm trường hợp lý
- Trong nội dung phương thức, tiết kiệm để tạo các nhóm câu lệnh logic. Các dòng trống ở đầu hoặc cuối thân hàm không được phép
- Tùy chọn trước phương thức đầu tiên hoặc sau phương thức cuối cùng trong một lớp hoặc đối tượng theo nghĩa đen [không được khuyến khích cũng không được khuyến khích]
- Theo yêu cầu của các phần khác của tài liệu này [e. g. ]
Nhiều dòng trống liên tiếp được cho phép, nhưng không bao giờ bắt buộc [cũng không được khuyến khích]
4. 6. 2 Khoảng trắng ngang
Việc sử dụng khoảng trắng ngang phụ thuộc vào vị trí và thuộc ba loại chính. đầu [ở đầu dòng], theo sau [ở cuối dòng] và nội bộ. Khoảng trắng hàng đầu [i. e. , thụt đầu dòng] được giải quyết ở nơi khác. Khoảng trắng ở cuối bị cấm
Ngoài những nơi được yêu cầu bởi ngôn ngữ hoặc các quy tắc kiểu khác và ngoài chữ, nhận xét và JSDoc, một không gian ASCII bên trong cũng chỉ xuất hiện ở những vị trí sau
- Tách bất kỳ từ dành riêng nào [chẳng hạn như
73,goog.module['search.urlHistory.UrlHistoryService'];
75 hoặcgoog.module['search.urlHistory.UrlHistoryService'];
79] ngoại trừgoog.module['search.urlHistory.UrlHistoryService'];
01 vàgoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
02, khỏi dấu ngoặc đơn mở [_______35_______96] theo sau nó trên dòng đógoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
- Tách bất kỳ từ dành riêng nào [chẳng hạn như
74 hoặcgoog.module['search.urlHistory.UrlHistoryService'];
79] khỏi dấu ngoặc nhọn đóng [goog.module['search.urlHistory.UrlHistoryService'];
06] đứng trước từ đó trên dòng đógoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
- Trước bất kỳ dấu ngoặc nhọn mở nào [______36_______07], với hai ngoại lệ
- Trước một ký tự đối tượng là đối số đầu tiên của một hàm hoặc phần tử đầu tiên trong một ký tự mảng [e. g.
08]goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
- Trong bản mở rộng mẫu, vì nó bị cấm bởi ngôn ngữ [e. g. có giá trị.
09, không hợp lệ.goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
10]goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
- Trước một ký tự đối tượng là đối số đầu tiên của một hàm hoặc phần tử đầu tiên trong một ký tự mảng [e. g.
- Trên cả hai mặt của bất kỳ toán tử nhị phân hoặc bậc ba nào
- Sau dấu phẩy [
97] hoặc dấu chấm phẩy [goog.module['search.urlHistory.UrlHistoryService'];
12]. Lưu ý rằng khoảng cách không bao giờ được phép trước các ký tự nàygoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
- Sau dấu hai chấm [
13] trong một đối tượng theo nghĩa đengoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
- Ở cả hai bên của dấu gạch chéo kép [
14] bắt đầu nhận xét cuối dòng. Ở đây, nhiều khoảng trắng được cho phép, nhưng không bắt buộcgoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
- 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. cho các khai báo kiểu dạng ngắn, ép kiểu và nhận xét tên tham số.
15;goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
4. 6. 3 Căn ngang. chán nản
Lưu ý thuật ngữ. Căn chỉnh theo chiều ngang là cách thêm một số khoảng trắng bổ sung có thể thay đổi vào mã của bạn với mục tiêu làm cho một số mã thông báo nhất định xuất hiện ngay bên dưới một số mã thông báo khác trên các dòng trước đó
Phương pháp này được cho phép, nhưng nó thường không được Google Style khuyến khích. Thậm chí không bắt buộc phải duy trì căn chỉnh ngang ở những nơi nó đã được sử dụng
Đây là một ví dụ không có căn chỉnh, theo sau là một ví dụ có căn chỉnh. Cả hai đều được phép, nhưng cái sau không được khuyến khích
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
9Mẹo. Căn chỉnh có thể hỗ trợ khả năng đọc, nhưng nó tạo ra các vấn đề cho việc bảo trì trong tương lai. Xem xét một thay đổi trong tương lai chỉ cần chạm vào một dòng. Thay đổi này có thể khiến định dạng hài lòng trước đây bị xáo trộn và điều đó được cho phép. Thông thường, nó cũng nhắc người viết mã [có thể là bạn] điều chỉnh khoảng trắng trên các dòng gần đó, có thể kích hoạt một loạt định dạng lại xếp tầng. Thay đổi một dòng đó hiện có bán kính vụ nổ. Điều này tệ nhất có thể dẫn đến công việc bận rộn vô nghĩa, nhưng tốt nhất thì nó vẫn làm hỏng thông tin lịch sử phiên bản, làm chậm người đánh giá và làm trầm trọng thêm xung đột hợp nhất
4. 6. 4 Đối số chức năng
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};
04. 7 Nhóm dấu ngoặc đơn. khuyến khích
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ử
Không sử dụng dấu ngoặc đơn không cần thiết xung quanh toàn bộ biểu thức sau
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, hoặc goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
26Dấu ngoặc đơn là bắt buộc đối với loại phôi.
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
27Phần này giải quyết các ý kiến thực hiện. JSDoc được xử lý riêng trong
Nhận xét khối được thụt lề ở cùng mức với mã xung quanh. 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. Đối với nhận xét nhiều dòng goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
28, các dòng tiếp theo phải bắt đầu bằng * được căn chỉnh với goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
31 trên dòng trước đó, để làm cho nhận xét rõ ràng mà không có ngữ cảnh bổ sungconst /** !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};
1Nhậ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Để thống nhất với mã xung quanh, bạn có thể đặt chúng sau giá trị mà không 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 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]. Phần này mô tả những tính năng nào có thể được sử dụng hoặc không được sử dụng và mọi ràng buộc bổ sung đối với việc sử dụng chúng
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
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
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. Không được sử dụng từ khóa goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
375. 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. khai báo chẳng hạn như
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
38 không được sử dụng5. 1. 3 Khai báo khi cần thiết, khởi tạo ngay khi có thể
Các biến cục bộ không được khai báo theo thói quen khi bắt đầu khối chứa hoặc cấu trúc giống như khối của chúng. 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 nhu 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};
4Không được phép trộn các kiểu nội tuyến và JSDoc. 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};
5Mẹo. Có nhiều trường hợp trình biên dịch có thể suy ra một kiểu đã được tạo khuôn mẫu nhưng không thể suy ra các tham số của nó. Đây là trường hợp đặc biệt khi lời gọi khởi tạo bằng chữ hoặc hàm tạo không bao gồm bất kỳ giá trị nào của loại tham số mẫu [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. Chú thích loại biến cục bộ đặc biệt hữu ích trong những trường hợp này vì nếu không, trình biên dịch sẽ suy ra tham số mẫu là không xác định5. 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};
65. 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
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
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. nếu
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
42 là một số nguyên thì goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
43 là một mảng có kích thước goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
42 trong đó tất cả các phần tử là goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
45. Nếu goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
42 là bất kỳ số nào khác, thì một ngoại lệ sẽ được đưa ra và nếu đó là bất kỳ số nào khác thì đó sẽ là một mảng một phần tử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};
8Cho 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ợp5. 2. 3 Thuộc tính phi số
Không xác định hoặc sử dụng các thuộc tính không phải là số trên một mảng [ngoài
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
48]. Thay vào đó, hãy sử dụ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'];
50]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]. Các yếu tố nên được bỏ qua nếu chúng không được sử dụngconst /** !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};
9Việ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]. Luôn chỉ định
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
52 làm giá trị mặc định nếu tham số mảng bị hủy cấu trúc là tùy chọn và cung cấp các giá trị mặc định ở phía bên trái/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
0không được phép
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
1Mẹ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. Không có khoảng trống sau goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
51Thí dụ
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
25. 3 đối tượng chữ
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 Không sử dụng hàm tạo goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
50
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
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. Thay vào đó, hãy sử dụng một đối tượng theo nghĩa đen [goog.module['search.urlHistory.UrlHistoryService'];
81 hoặc goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
60]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
Các ký tự đối tượng có thể đại diện cho các cấu trúc [với các khóa và/hoặc ký hiệu không được trích dẫn] hoặc các ký tự [với các khóa được trích dẫn và/hoặc được tính toán]. Không trộn lẫn các loại khóa này trong một đối tượng theo nghĩa đen
không được phép
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
3Điều này cũng mở rộng để chuyển tên thuộc tính cho các hàm, như
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';
55. 3. 4 Tên thuộc tính được tính toán
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. , không được trộn lẫn với các khóa không được trích dẫn] trừ khi thuộc tính được tính là ký hiệu [e. g. , goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
63]. Các giá trị enum cũng có thể được sử dụng cho các khóa được tính toán, nhưng không được trộn lẫn với các khóa không phải enum theo cùng một nghĩa đen5. 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ênThí dụ
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
6Lư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 đenThí dụ
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
75. 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';
85. 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';
9không được phép
/** @const */
exports = {exportedFunction};
0Việ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};
15. 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ạo5. 4. 2 lĩnh vực
Đặ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]. Chú thích các trường không công khai bằng chú thích khả năng hiển thị phù hợp [/* 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] và kết thúc tên của tất cả các trường ________0____94 bằng dấu gạch dưới. 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'];
81Thí dụ
/** @const */
exports = {exportedFunction};
2Mẹ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. Các lớp có thêm cái này theo mặc định5. 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ệmMẹ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ơn5. 4. 4 phương pháp tĩnh
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};
35. 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ụ
Nếu tồn tại hoặc sẽ tồn tại các lớp con, bao gồm cả các khung tạo ra các lớp con, không thể thay đổi ngay lập tức để sử dụng cú pháp lớp ES6. Nếu một lớp như vậy sử dụng cú pháp ES6, thì tất cả các lớp con xuôi dòng không sử dụng cú pháp lớp ES6 sẽ cần phải được sửa đổi
Các khung yêu cầu giá trị
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ệngoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
66 cho đến khi lệnh gọi tớigoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
02 trả vềgoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
Trong tất cả các cách khác, hướng dẫn kiểu vẫn áp dụng cho mã này. 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};
4Ngoài ra, mặc dù
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
93 nên được ưu tiên cho tất cả mã mới, nhưng cú pháp truyền thống hơn cũng được cho phép/** @const */
exports = {exportedFunction};
5Cá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
Xác định chính xác hệ thống phân cấp nguyên mẫu của hàm tạo khó hơn so với lần đầu tiên xuất hiện. 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ửa5. 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
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
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ó 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àngNgoạ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ậy5. 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. các khung liên kết dữ liệu như Angular và Polymer hoặc để tương thích với các API bên ngoài không thể điều chỉnh]. 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 đượckhông được phép
/** @const */
exports = {exportedFunction};
65. 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 đượcMẹo. Đặc biệt, hãy cẩn thận khi gọi các phương thức khác từ toString, vì các điều kiện ngoại lệ có thể dẫn đến các vòng lặp vô hạn
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. Các giao diện được khai báo với goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
06 có thể rõ ràng [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 đenTất cả các nội dung phương thức không tĩnh trên một 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};
75. 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. Do not use goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
10. See abstract classes and methods5. 5 Functions
5. 5. 1 Top-level functions
Top-level functions may be defined directly on the
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
92 object, or else declared locally and optionally exported. See for more on exportsví dụ
/** @const */
exports = {exportedFunction};
8/** @const */
exports = {exportedFunction};
95. 5. 2 Nested functions and closures
Functions may contain nested function definitions. If it is useful to give the function a name, it should be assigned to a local
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
335. 5. 3 Arrow functions
Arrow functions provide a concise function syntax and simplify scoping
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
66 for nested functions. Prefer arrow functions over the goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
01 keyword, particularly for nested functions [but see ]Prefer arrow functions over other
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
66 scoping approaches such as goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
16, goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
17, and goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
18. Arrow functions are particularly useful for calling into callbacks as they permit explicitly specifying which parameters to pass to the callback whereas binding will blindly pass along all parametersThe left-hand side of the arrow contains zero or more parameters. Parentheses around the parameters are optional if there is only a single non-destructured parameter. When parentheses are used, inline parameter types may be specified [see ]
Tip. Always using parentheses even for single-parameter arrow functions can avoid situations where adding parameters, but forgetting to add parentheses, may result in parseable code which no longer works as intended
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]. The body may also be an implicitly returned single expression if either. 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]. The single expression form is preferred if it improves readability [e. g. , for short or simple expressions]ví dụ
import './sideeffects.js';
import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';
import {name} from './sibling.js';
0khô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';
15. 5. 4 Generators
Generators enable a number of useful abstractions and may be used as needed
When defining generator functions, attach the
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
31 to the goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
01 keyword when present, and separate it with a space from the name of the function. When using delegating yields, attach the goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
31 to the goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
26 keywordThí dụ
import './sideeffects.js';
import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';
import {name} from './sibling.js';
25. 5. 5 Parameter and return types
Function parameters and return types should usually be documented with JSDoc annotations. See for more information
5. 5. 5. 1 Default parametersOptional parameters are permitted using the equals operator in the parameter list. Optional parameters must include spaces on both sides of the equals operator, be named exactly like required parameters [i. e. , not prefixed with
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
26], use the goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
27 suffix in their JSDoc type, come after required parameters, and not use initializers that produce observable side effects. All optional parameters for concrete functions must have default values, even if that value is goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
45. In contrast to concrete functions, abstract and interface methods must omit default parameter valuesThí dụ
import './sideeffects.js';
import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';
import {name} from './sibling.js';
3Use default parameters sparingly. Prefer destructuring [as in ] to create readable APIs when there are more than a small handful of optional parameters that do not have a natural order
Note. Unlike Python's default parameters, it is okay to use initializers that return new mutable objects [such as
goog.module['search.urlHistory.UrlHistoryService'];
81 or goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
52] because the initializer is evaluated each time the default value is used, so a single object won't be shared across invocationsTip. While arbitrary expressions including function calls may be used as initializers, these should be kept as simple as possible. Avoid initializers that expose shared mutable state, as that can easily introduce unintended coupling between function calls
5. 5. 5. 2 Rest parametersUse a rest parameter instead of accessing
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
31. Rest parameters are typed with a goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
51 prefix in their JSDoc. The rest parameter must be the last parameter in the list. There is no space between the goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
51 and the parameter name. Do not name the rest parameter goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
34. Never name a local variable or parameter goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
31, which confusingly shadows the built-in nameThí dụ
import './sideeffects.js';
import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';
import {name} from './sibling.js';
45. 5. 6 Generics
Declare generic functions and methods when necessary with
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
36 in the JSDoc above the function or method definition5. 5. 7 Spread operator
Function calls may use the spread operator [
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
51]. Prefer the spread operator to goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
38 when an array or iterable is unpacked into multiple parameters of a variadic function. There is no space after the goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
51Thí dụ
import './sideeffects.js';
import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';
import {name} from './sibling.js';
55. 6 String literals
5. 6. 1 Use single quotes
Ordinary string literals are delimited with single quotes [
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
40], rather than double quotes [goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
41]Tip. if a string contains a single quote character, consider using a template string to avoid having to escape the quote
Ordinary string literals may not span multiple lines
5. 6. 2 Template literals
Use template literals [delimited with
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
42] over complex string concatenation, particularly if multiple string literals are involved. Template literals may span multiple linesIf a template literal spans multiple lines, it does not need to follow the indentation of the enclosing block, though it may if the added whitespace does not matter
Thí dụ
import './sideeffects.js';
import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';
import {name} from './sibling.js';
65. 6. 3 No line continuations
Do not use line continuations [that is, ending a line inside a string literal with a backslash] in either ordinary or template string literals. Even though ES5 allows this, it can lead to tricky errors if any trailing whitespace comes after the slash, and is less obvious to readers
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';
7Thay 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';
85. 7 chữ số
Numbers may be specified in decimal, hex, octal, or binary. Use exactly
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
43, goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
44, and goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
45 prefixes, with lowercase letters, for hex, octal, and binary, respectively. Never include a leading zero unless it is immediately followed by goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
46, goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
47, or goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
485. 8 Control structures
5. 8. 1 For loops
With ES6, the language now has three different kinds of
goog.module['search.urlHistory.UrlHistoryService'];
75 loops. All may be used, though goog.module['search.urlHistory.UrlHistoryService'];
75-goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
25 loops should be preferred when possiblegoog.module['search.urlHistory.UrlHistoryService'];
75-goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
24 loops may only be used on dict-style objects [see ], and should not be used to iterate over an array. goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
54 should be used in goog.module['search.urlHistory.UrlHistoryService'];
75-goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
24 loops to exclude unwanted prototype properties. Prefer goog.module['search.urlHistory.UrlHistoryService'];
75-goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
25 and goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
59 over goog.module['search.urlHistory.UrlHistoryService'];
75-goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
24 when possible5. 8. 2 Exceptions
Exceptions are an important part of the language and should be used whenever exceptional cases occur. Always throw
goog.module['search.urlHistory.UrlHistoryService'];
63s or subclasses of goog.module['search.urlHistory.UrlHistoryService'];
63. never throw string literals or other objects. Always use goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
64 when constructing an goog.module['search.urlHistory.UrlHistoryService'];
63This treatment extends to
goog.module['search.urlHistory.UrlHistoryService'];
65 rejection values as goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
67 is equivalent to goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
68 in async functionsCustom exceptions provide a great way to convey additional error information from functions. They should be defined and used wherever the native
goog.module['search.urlHistory.UrlHistoryService'];
63 type is insufficientƯ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 vùng chứa lỗi hoặc trả về một đối tượng có thuộc tính lỗi]
It is very rarely correct to do nothing in response to a caught exception. When it truly is appropriate to take no action whatsoever in a catch block, the reason this is justified is explained in a comment
import './sideeffects.js';
import * as goog from '../closure/goog/goog.js';
import * as parent from '../parent.js';
import {name} from './sibling.js';
9không được phép
import '../directory/file';
0Tip. 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ẽ phát hiện 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ệnh5. 8. 3. 1 mùa thu. commentedWithin a switch block, each statement group either terminates abruptly [with a
goog.module['search.urlHistory.UrlHistoryService'];
89, goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
21 or goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
22n exception], or is marked with a comment to indicate that execution will or might continue into the next statement group. Any comment that communicates the idea of fall-through is sufficient [typically goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
77]. This special comment is not required in the last statement group of the switch blockThí dụ
import '../directory/file';
15. 8. 3. 2 The goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
78 case is presentEach switch statement includes a
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
78 statement group, even if it contains no code. The goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
78 statement group must be last5. 9 this
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 JSDocNever use
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
66 to refer to the global object, the context of an goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
84, the target of an event, or unnecessarily goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
85ed or goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
86ed functions5. 10 Equality Checks
Use identity operators [
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
87/goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
88] except in the cases documented below5. 10. 1 Exceptions Where Coercion is Desirable
Catching both
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
89 and goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
45 valuesimport '../directory/file';
25. 11 Disallowed features
5. 11. 1 with
Do not use the
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
91 keyword. It makes your code harder to understand and has been banned in strict mode since ES55. 11. 2 Dynamic code evaluation
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ã]. These features are potentially dangerous and simply do not work in CSP environments5. 11. 3 Automatic semicolon insertion
Always terminate statements with semicolons [except function and class declarations, as noted above]
5. 11. 4 Non-standard features
Do not use non-standard features. This includes old features that have been removed [e. g. ,
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
94], new features that are not yet standardized [e. g. , the current TC39 working draft, proposals at any stage, or proposed but not-yet-complete web standards], or proprietary features that are only implemented in some browsers. Use only features defined in the current ECMA-262 or WHATWG standards. [Note that projects writing against specific APIs, such as Chrome extensions or Node. js, can obviously use those APIs]. Non-standard language “extensions” [such as those provided by some external transpilers] are forbidden5. 11. 5 Wrapper objects for primitive types
Never use
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
64 on the primitive object wrappers [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], nor include them in type annotationskhông được phép
import '../directory/file';
3The wrappers may be called as functions for coercing [which is preferred over using
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 or concatenating the empty string] or creating symbolsThí dụ
import '../directory/file';
45. 11. 6 Modifying builtin objects
Never modify builtin types, either by adding methods to their constructors or to their prototypes. Avoid depending on libraries that do this. Note that the JSCompiler’s runtime library will provide standards-compliant polyfills where possible; nothing else may modify builtin objects
Do not add symbols to the global object unless absolutely necessary [e. g. required by a third-party API]
5. 11. 7 Omitting 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 when invoking a constructor
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};
Never invoke a constructor in a
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
64 statement without using parentheses 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};
01không được phép
import '../directory/file';
5Use instead
import '../directory/file';
6Omitting parentheses can lead to subtle mistakes. These two lines are not equivalent
import '../directory/file';
76 Naming
6. 1 Rules common to all identifiers
Identifiers use only ASCII letters and digits, and, in a small number of cases noted below, underscores and very rarely [when required by frameworks like Angular] dollar signs
Give as descriptive a name as possible, within reason. Do not worry about saving horizontal space as it is far more important to make your code immediately understandable by a new reader. Do not use abbreviations that are ambiguous or unfamiliar to readers outside your project, and do not abbreviate by deleting letters within a word
import '../directory/file';
8không được phép
import '../directory/file';
96. 2 Rules by identifier type
6. 2. 1 Package names
Package names are all
goog.module['search.urlHistory.UrlHistoryService'];
01. For example, 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, but not 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 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};
076. 2. 2 Class names
Class, interface, record, and typedef names are written in
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. Unexported classes are simply locals. they are not marked /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94 and therefore are not named with a trailing underscoreType names are typically nouns or noun phrases. For example,
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, 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};
12. Additionally, interface names may sometimes be adjectives or adjective phrases instead [for example, 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 Method names
Tên phương thức được viết bằng
goog.module['search.urlHistory.UrlHistoryService'];
01. Names for /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94 methods must end with a trailing underscoreMethod names are typically verbs or verb phrases. For example,
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 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};
17. Getter and setter methods for properties are never required, but if they are used they should be named 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 [or optionally 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 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};
20 for booleans], 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};
21 for settersUnderscores may also appear in JsUnit test method names to separate logical components of the name. One typical pattern is
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, for example 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. There is no One Correct Way to name test methods6. 2. 4 Enum names
Enum names are written in
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, similar to classes, and should generally be singular nouns. Individual items within the enum are named in 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};
256. 2. 5 Constant names
Constant names 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};
25. all uppercase letters, with words separated by underscores. There is no reason for a constant to be named with a trailing underscore, since private static properties can be replaced by [implicitly private] module locals6. 2. 5. 1 Definition of “constant”Every constant is a
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
96 static property or a module-local goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
33 declaration, but not all /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
96 static properties and module-local goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
33s are constants. Before choosing constant case, consider whether the field really feels like a deeply immutable constant. For example, if any of that instance's observable state can change, it is almost certainly not a constant. 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';
00Constants’ names are typically nouns or noun phrases
6. 2. 5. 2 Local aliasesCá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. Follow the same rules as
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
74s [], maintaining the last part of the aliased name. Aliases may also be used within functions. Aliases must be goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
33ví dụ
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
016. 2. 6 Non-constant field names
Non-constant field names [static or otherwise] are written in
goog.module['search.urlHistory.UrlHistoryService'];
01, with a trailing underscore for private fieldsThese names are typically nouns or noun phrases. For example,
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 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};
356. 2. 7 Parameter names
Parameter names are written in
goog.module['search.urlHistory.UrlHistoryService'];
01. Note that this applies even if the parameter expects a constructorOne-character parameter names should not be used in public methods
Exception. When required by a third-party framework, parameter names may begin with 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};
37. This exception does not apply to any other identifiers [e. g. local variables or properties]6. 2. 8 Local variable names
Local variable names are written in
goog.module['search.urlHistory.UrlHistoryService'];
01, except for module-local [top-level] constants, as described above. Constants in function scopes are still named in goog.module['search.urlHistory.UrlHistoryService'];
01. Note that goog.module['search.urlHistory.UrlHistoryService'];
01 is used even if the variable holds a constructor6. 2. 9 Template parameter names
Template parameter names should be concise, single-word or single-letter identifiers, and must be all-caps, such as
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 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};
426. 2. 10 Module-local names
Module-local names that are not exported are implicitly private. They are not marked
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
94 and do not end in an underscore. This applies to classes, functions, variables, constants, enums, and other module-local identifiers6. 3 Camel case. defined
Sometimes there is more than one reasonable way to convert an English phrase into camel case, such as when acronyms or unusual constructs like IPv6 or iOS are present. To improve predictability, Google Style specifies the following [nearly] deterministic scheme
Beginning with the prose form of the name
- Convert the phrase to plain ASCII and remove any apostrophes. For example, Müller's algorithm might become Muellers algorithm
- 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]
- Recommended. if any word already has a conventional camel case appearance in common usage, split this into its constituent parts [e. g. , AdWords becomes ad words]. Note that a word such as iOS is not really in camel case per se; it defies any convention, so this recommendation does not apply
- Now lowercase everything [including acronyms], then uppercase only the first character of
- … each word, to yield upper camel case, or
- … each word except the first, to yield lower camel case
- Finally, join all the words into a single identifier
Note that the casing of the original words is almost entirely disregarded
ví dụ
Prose formCorrectIncorrectXML HTTP requestXmlHttpRequestXMLHTTPRequestnew customer IDnewCustomerIdnewCustomerIDinner stopwatchinnerStopwatchinnerStopWatchsupports IPv6 on iOS?supportsIpv6OnIossupportsIPv6OnIOSYouTube importerYouTubeImporterYoutubeImporter**Acceptable, but not recommended
Note. Some words are ambiguously hyphenated in the English language. for example nonempty and non-empty are both correct, so the method names checkNonempty and checkNonEmpty are likewise both correct
7 JSDoc
JSDoc is used on all classes, fields, and methods
7. 1 General form
The basic formatting of JSDoc blocks is as seen in this example
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
02or in this single-line example
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
03If a single-line comment overflows into multiple lines, it must use the multi-line style 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};
44 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};
45 on their own linesMany tools extract metadata from JSDoc comments to perform code validation and optimization. Như vậy, những bình luận này phải được hình thành tốt
7. 2 Markdown
JSDoc is written in Markdown, though it may include HTML when necessary
Note that tools that automatically extract JSDoc [e. g. JsDossier] will often ignore plain text formatting, so if you did this
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
04it would come out like this
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
05Instead, write a Markdown list
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
06Google style allows a subset of JSDoc tags. See for the complete list. Most tags must occupy their own line, with the tag at the beginning of the line
không được phép
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
07Simple tags that do not require any additional data [such as
/* 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] may be combined onto the same line, along with an optional type when appropriate/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
08There is no hard rule for when to combine tags, or in which order, but be consistent
For general information about annotating types in JavaScript see Annotating JavaScript for the Closure Compiler and Types in the Closure Type System
7. 4 Line wrapping
Line-wrapped block tags are indented four spaces. Wrapped description text may be lined up with the description on previous lines, but this horizontal alignment is discouraged
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
09Do not indent when wrapping 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};
50 or /* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
70 descriptionA file may have a top-level file overview. A copyright notice , author information, and default are optional. File overviews are generally recommended whenever a file consists of more than a single class definition. The top level comment is designed to orient readers unfamiliar with the code to what is in this file. If present, it may provide a description of the file's contents and any dependencies or compatibility information. Wrapped lines are not indented
Thí dụ
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
10Classes, interfaces and records must be documented with a description and any template parameters, implemented interfaces, visibility, or other appropriate tags. The class description should provide the reader with enough information to know how and when to use the class, as well as any additional considerations necessary to correctly use the class. Textual descriptions may be omitted on the constructor. 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';
11All enums and typedefs must be documented with appropriate JSDoc tags [
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 or goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
73] on the preceding line. Public enums and typedefs must also have a description. Individual enum items may be documented with a JSDoc comment on the preceding line/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
12Typedefs are useful for defining short record types, or aliases for unions, complex functions, or generic types. Typedefs should be avoided for record types with many fields, since they do not allow documenting individual fields, nor using templates or recursive references. For large record types, prefer
goog.module['my.test.helpers'];
goog.module.declareLegacyNamespace[];
goog.setTestOnly[];
06In methods and named functions, parameter and return types must be documented, except in the case of same-signature
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};
59s, where all types are omitted. The goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
66 type should be documented when necessary. Return type may be omitted if the function has no non-empty goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
21 statementsMethod, parameter, and return descriptions [but not types] may be omitted if they are obvious from the rest of the method’s JSDoc or from its signature
Method descriptions begin with a verb phrase that describes what the method does. This phrase is not an imperative sentence, but instead is written in the third person, as if there is an implied This method . before it
If a method overrides a superclass method, it must include an
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 annotation. Overridden methods inherit all JSDoc annotations from the super class method [including visibility annotations] and they should be omitted in the overridden method. However, if any type is refined in type annotations, all 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 annotations must be specified explicitly/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
13If you only need to document the param and return types of a function, you may optionally use inline JSDocs in the function's signature. These inline JSDocs specify the return and param types without tags
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
14Nế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. For example, methods which return values need 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};
64 tag/* 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';
16In anonymous functions annotations are generally optional. If the automatic type inference is insufficient or explicit annotation improves readability, then annotate param and return types like this
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
17For function type expressions, see
Property types must be documented. The description may be omitted for private properties, if name and type provide enough documentation for understanding the code
Publicly exported constants are commented the same way as properties
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
187. 10 Type annotations
Type annotations are found on
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, 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};
69 tags, and optionally on /* 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, and any visibility tags. Type annotations attached to JSDoc tags must always be enclosed in braces7. 10. 1 Nullability
The type system defines modifiers
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 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};
73 for non-null and nullable, respectively. These modifiers must precede the typeNullability modifiers have different requirements for different types, which fall into two broad categories
- Type annotations for primitives [
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,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,goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
89] and literals [goog.module['my.test.helpers']; goog.module.declareLegacyNamespace[]; goog.setTestOnly[];
80 andconst /** !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] are always non-nullable by default. Use theconst /** !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 modifier to make it nullable, but omit the redundantconst /** !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};
72const /** !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};
- Reference types [generally, anything in
08, includingconst /** !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] refer to a class, enum, record, or typedef defined elsewhere. Since these types may or may not be nullable, it is impossible to tell from the name alone whether it is nullable or not. Always use explicitconst /** !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 andconst /** !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 modifiers for these types to prevent ambiguity at use sitesconst /** !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};
Bad
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
19Good
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
207. 10. 2 Type Casts
In cases where the compiler doesn't accurately infer the type of an expression, and the assertion functions in goog. asserts cannot remedy it , it is possible to tighten the type by adding a type annotation comment and enclosing the expression in parentheses. Note that the parentheses are required
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
217. 10. 3 Template Parameter Types
Always specify template parameters. This way compiler can do a better job and it makes it easier for readers to understand what code does
Bad
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
22Good
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
23Cases when template parameters should not be used
50 is used for type hierarchy and not as map-like structuregoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
7. 10. 4 Function type expressions
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';
24When 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 desiredBad - type error, but no warning given
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
25Good
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
267. 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
Good
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
27Bad
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
287. 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 underscore8 Policies
8. 1 Issues unspecified by Google Style. Be Consistent
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';
018. 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
- 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
- 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
02 annotation/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant';
- Otherwise, leave a TODO comment. This is a last resort. If you do this, do not suppress the warning. Cảnh báo sẽ hiển thị cho đến khi nó có thể được xử lý đúng cách
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';
29Even 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 sites8. 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
- 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
- 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 Mã mới được thêm vào. sử dụng Google Phong cách
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. As a special exception, such identifiers are allowed to contain underscores, which may help to avoid conflicts with hand-written identifiers
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
/** @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 recommendedNot recommended
cú pháp.
/** @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';
30Documents 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/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
09Syntax.
/** @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';
31Indicates 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/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
12 - Deprecated. Do not useDeprecated. Do not use. Use Markdown backticks instead
Syntax.
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
13Historically,
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
14 was written as /** @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';
32Indicates that a term in a JSDoc description is code so it may be correctly formatted in generated documentation
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};
50Syntax.
/** @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/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
18Syntax.
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
19This tag is used to generate cross-reference links within generated documentation
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
34Historical 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/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
20Syntax.
/** @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';
36Reference a lookup to another class function or method
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
22Syntax.
/** @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';
37Used in a fileoverview to indicate what browsers are supported by the file
9. 1. 3 Framework specific annotations
The following annotations are specific to a particular framework
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
24 for Angular 1/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
25 for Polymerhttps. //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
/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
26 - Deprecated. Do not useDeprecated. 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/** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
29 - Deprecated. Do not useDeprecated. 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};
59 instead9. 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
04 credit is required in a source file. [Neither is explicitly recommended, either. ]/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant';
- There is no hard and fast rule governing how to order the members of a class []
- Empty blocks can usually be represented concisely as
81, as detailed in []goog.module['search.urlHistory.UrlHistoryService'];
- 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
goog.module['search.urlHistory.UrlHistoryService'];
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 guidegoog.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. Tuy nhiên, các cây con có thể chọn tham gia thực thi như vậy cục bộ9. 3. 3 Closure compiler linter
Chương trình này kiểm tra một loạt các bước sai và chống mẫu
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 qualityFor 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
37 declarations is allowedgoog.module['foo.bar']; // 'foo.bar.qux' would be fine, though goog.module['foo.bar.baz'];
- Use of
31 is allowedgoog.module['my.test.helpers']; goog.module.declareLegacyNamespace[]; goog.setTestOnly[];
- 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'];
goog.module['foo.bar']; // 'foo.bar.qux' would be fine, though
goog.module['foo.bar.baz'];
37 declarations are NOT block-scopedgoog.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';
389. 4. 2. 2 Declare variables as close as possible to first useEven 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. Ví dụ/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
399. 4. 2. 3 Use @const for constants variablesFor 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';
40While 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';
419. 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 Summarygoog.module['search.urlHistory.UrlHistoryService'];
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
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
18s first,goog.module['search.urlHistory.UrlHistoryService'];
74s second. Separate provides from requires with an empty line/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs';
- Sort the entries alphabetically [uppercase first]
- Don't wrap
18 andgoog.module['search.urlHistory.UrlHistoryService'];
74 statements. Exceed 80 columns if necessary/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs';
- 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 lineSimilar 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 limitThe lines should be sorted alphabetically, with uppercase letters coming first
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
42All 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]
Do this
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
43Not this
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
44Members on namespaces may also be provided
/* Poor: the reader has no idea what character this is. */
const units = '\u03bcs';
459. 4. 4. 2 Aliasing with /** @const {number} */
exports.CONSTANT_ONE = 1;
/** @const {string} */
exports.CONSTANT_TWO = 'Another constant';
64WARNING.
/** @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 managementOnly 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 scopeThe 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 spacesSimilar 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 columnOnly 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';
46Names 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';
479. 4. 4. 3 goog.module['search.urlHistory.UrlHistoryService'];
25Prefer 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 definedgoog.module['search.urlHistory.UrlHistoryService'];
25 vẫn có thể được sử dụng trong mã kế thừa để phá vỡ các tham chiếu vòng tròn trải rộng qua các ranh giới thư viện, nhưng mã mới hơn nên được cấu trúc để tránh điều đóCác câu lệnh của
goog.module['search.urlHistory.UrlHistoryService'];
25 phải tuân theo các quy tắc về văn phong giống như của /* 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. Toàn bộ khối câu lệnh goog.module['search.urlHistory.UrlHistoryService'];
25, /* 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 được sắp xếp theo thứ tự bảng chữ cái