A string consists of digits ranging from 2 to 9, inclusive Letter Combination Dữ liệu thử nghiệm Giải pháp mẫu Mã HTML Mã JavaScript đầu ra Sơ đồJavaScript Function. Exercise-13 with Solution
Write a JavaScript program to get all possible letter combinations that can represent the number using recursion
1. 'abc',
2. 'chắc chắn',
3. 'ghi',
4. 'jkl',
5. 'mno',
6. 'pqr',
7. 'stu',
8. 'vwx'
9. 'yz'
("12") -> ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
("9") -> ["y", "z"]
Bản thử trực tiếp
Xem Bút javascript-recursion-function-exercise-13 của w3resource (@w3resource) trên CodePen
Cải thiện giải pháp mẫu này và đăng mã của bạn qua Disqus
Trước. Thuật toán tìm kiếm nhị phân sử dụng đệ quy
Kế tiếp. Câu lệnh có điều kiện Javascript và bài tập vòng lặp
Mức độ khó của bài tập này là gì?
Dễ dàng trung bình khóKiểm tra kỹ năng Lập trình của bạn với bài kiểm tra của w3resource
Theo dõi chúng tôi trên Facebook và Twitter để cập nhật thông tin mới nhất.
JavaScript. Lời khuyên trong ngày
Kiểm tra xem Chuỗi có bắt đầu bằng Chuỗi đã cho không
Các chuỗi JavaScript có phương thức startedWith để kiểm tra xem một chuỗi có bắt đầu bằng một chuỗi đã cho hay không
Chúng ta có thể gọi nó bằng cách sử dụng
Sau đó, nó sẽ trở lại đúng
Nó cũng nhận một đối số thứ hai, cho phép chúng ta chỉ định chỉ mục của ký tự mà chúng ta muốn bắt đầu kiểm tra.
Chẳng hạn, chúng ta có thể viết
Sau đó, startedWith bắt đầu tìm kiếm ở chỉ mục 8, vì vậy nó trả về false
Giới thiệu. https. //chút. ly/3mp5NgH
- Xu hướng hàng tuần
- Bài tập lập trình Java cơ bản
- Truy vấn con SQL
- Bài tập cơ sở dữ liệu Adventureworks
- Bài tập cơ bản C# Sharp
- SQL COUNT() với sự khác biệt
- Bài tập chuỗi JavaScript
- Xác thực biểu mẫu HTML JavaScript
- Bài tập bộ sưu tập Java
- hàm SQL COUNT()
- Tham gia bên trong SQL
- Hàm JavaScript Bài tập
- Hướng dẫn Python
- Bài tập mảng Python
- Tham gia chéo SQL
- Bài tập về mảng Sharp trong C#
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ỉ bao gồm các vấn đề thẩm mỹ về định dạng mà còn cả các loại quy ước hoặc tiêu chuẩn viết mã khác. Tuy nhiên, tài liệu này tập trung chủ yếu vào các quy tắc cứng rắn và nhanh chóng mà chúng tôi tuân theo trên toàn cầu và tránh đưa ra lời khuyên không thể thực thi rõ ràng (dù là do con người hay công cụ)
1. 1 Ghi chú thuật ngữ
Trong tài liệu này, trừ khi được giải thích khác
Thuật ngữ nhận xét luôn đề cập đến nhận xét triển khai. Chúng tôi không sử dụng cụm từ nhận xét tài liệu, thay vào đó sử dụng thuật ngữ chung “JSDoc” cho cả văn bản mà con người có thể đọc được và chú thích mà máy có thể đọc được trong phạm vi /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 48
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 (_______5_______50), nhưng không có dấu chấm câu bổ sung. Thực hiện theo quy ước mà dự án của bạn sử dụng. Phần mở rộng của tên tệp phải là /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 51
2. 2 Mã hóa tập tin. UTF-8
Các tệp nguồn được mã hóa bằng UTF-8
2. 3 ký tự đặc biệt
2. 3. 1 Ký tự khoảng trắng
Ngoài trình tự kết thúc dòng, ký tự khoảng cách ngang ASCII (0x20) là ký tự khoảng trắng duy nhất xuất hiện ở bất kỳ đâu trong tệp nguồn. Điều này ngụ ý rằng
Tất cả các ký tự khoảng trắng khác trong chuỗi ký tự được thoát và
Các ký tự tab không được sử dụng để thụt lề
2. 3. 2 Trình tự thoát hiểm đặc biệt
Đối với bất kỳ ký tự nào có trình tự thoát đặc biệt (_______5_______52, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 53, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 54, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 55, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 56, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 57, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 58, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 59, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 60), trình tự đó được sử dụng thay vì trình tự thoát số tương ứng (e. g /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 61, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 62, hoặc /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 63). Thoát bát phân kế thừa không bao giờ được sử dụng
2. 3. 3 ký tự không phải ASCII
Đối với các ký tự không phải ASCII còn lại, ký tự Unicode thực tế (e. g. /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 64) hoặc bộ thoát hex hoặc Unicode tương đương (e. g. /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 65) được sử dụng, chỉ phụ thuộc vào cái nào làm cho mã dễ đọc và dễ hiểu hơn
Mẹo. Trong trường hợp thoát Unicode và đôi khi ngay cả khi các ký tự Unicode thực được sử dụng, một nhận xét giải thích có thể rất hữu ích
/* Best: perfectly clear even without a comment. */ const units = 'μs'; /* Allowed: but unnecessary as μ is a printable character. */ const units = '\u03bcs'; // 'μs' /* Good: use escapes for non-printable characters with a comment for clarity. */ return '\ufeff' + content; // Prepend a byte order mark. /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs';Mẹo. Đừng bao giờ làm cho mã của bạn khó đọc hơn chỉ vì sợ rằng một số chương trình có thể không xử lý đúng các ký tự không phải ASCII. Nếu điều đó xảy ra, các chương trình đó bị hỏng và chúng phải được sửa
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à /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 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ó
- /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 70 JSDoc, nếu có
- Câu lệnh /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 66, nếu tệp /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 66
- ES /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 68 câu lệnh, nếu một mô-đun ES
- 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
- Việc triển khai tệp
Chính xác một dòng trống phân tách từng phần hiện có, ngoại trừ việc triển khai tệp, có thể có 1 hoặc 2 dòng trống trước
3. 1 Giấy phép hoặc thông tin bản quyền, nếu có
Nếu thông tin giấy phép hoặc bản quyền thuộc về một tệp, thì nó thuộc về đây
3. 2 /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 70 JSDoc, nếu có
Xem các quy tắc định dạng
3. 3 tuyên bố /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 66
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à ngoại lệ đối với giới hạn 80 cột
Toàn bộ đối số với google. mô-đun là những gì xác định một không gian tên. Đó là tên gói (một mã định danh phản ánh đoạn cấu trúc thư mục chứa mã) cộng với, tùy chọn, lớp/enum/giao diện chính mà nó xác định được nối vào cuối
Ví 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 về tất cả các không gian tên con, vì chúng tồn tại trong cùng một thư mục
3. 3. 2 /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 81
Câu lệnh duy nhất /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 66 có thể tùy chọn được theo sau bởi lệnh gọi tới /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 83. Tránh /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 84 khi có thể
Ví dụ
goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly();/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 81 tồn tại để dễ dàng chuyển đổi từ các không gian tên dựa trên phân cấp đối tượng truyền thống nhưng đi kèm với một số hạn chế đặt tên. Vì tên mô-đun con phải được tạo sau không gian tên cha, nên tên này không được là con hoặc cha của bất kỳ /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 66 nào khác (ví dụ: /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 87 và /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 88 không thể tồn tại an toàn, cũng như /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 87 và /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 90)
3. 3. 3 /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 66 Xuất khẩu
Các lớp, enum, hàm, hằng số và các ký hiệu khác được xuất bằng cách sử dụng đối tượng /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 92. Các ký hiệu đã 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à 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 cục bộ mô-đun 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ác
import './sideeffects.js'; import * as goog from '../closure/goog/goog.js'; import * as parent from '../parent.js'; import {name} from './sibling.js'; 3. 4. 1. 1. 1 Phần mở rộng tệp trong đường dẫn nhậ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ào
import '../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_______5_______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 nhập mô-đun (_______40_______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 tệp hoặc đường dẫn của mô-đun đã nhập trong bí danh kết quả
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 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 cục bộ mô-đun 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'); 07
Khô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'); 2_______40_______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'); 08
goog.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'; 69
goog.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'); 13
goog.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 ES
3. 4. 4. 2 tốt. yêu cầu trong các mô-đun ES/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74 trong các mô-đun 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ầu
Mộ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 ____40_______33
Ghi 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 ES
Chỉ 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 có tên
goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 03. 5 goog.module('search.urlHistory.UrlHistoryService'); 37
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 ____40_______40
Trong 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 lệnh gọi tới ____40_______40
3. 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
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ại
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 tạo thành một khối liền kề không có dòng trống. Khối này theo khai báo /* 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ệp
Mỗ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 cứ đâ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'; 75
Ngoạ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, phải sử dụng một bí danh dài hơn để ngăn các loại bản địa che giấu, 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 trong
Mộ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'; 74
Nếu một mô-đun được nhập chỉ vì các tác dụng phụ của nó, lệnh gọi phải là một /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74 (không phải là một /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 75) và phép gán có thể được 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 được ưu tiên trước, được sắp xếp theo thứ tự bảng chữ cái của các tên đó. Sau đó, yêu cầu phá hủy, được sắp xếp lại theo tên ở phía bên trái. Cuối cùng, bất kỳ cuộc gọi yêu cầu nào độc lập (thường là những cuộc gọi này dành cho các mô-đun được nhập chỉ vì tác dụng phụ của chúng)
Mẹo. Không cần phải ghi nhớ lệnh này và thực thi thủ công. Bạn có thể dựa vào IDE của mình để báo cáo các yêu cầu không được sắp xếp chính xác
Nếu một bí danh hoặc tên mô-đun dài sẽ khiến một dòng vượt quá giới hạn 80 cột, thì nó không được ngắt dòng. các dòng yêu cầu là một ngoại lệ đối với giới hạn 80 cột
Ví 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 đã tích hợp với một số trình soạn thảo phổ biến
4. 1 niềng răng
4. 1. 1 Niềng răng được sử dụng cho tất cả các cấu trúc điều khiển
Niềng răng được yêu cầu cho tất cả các cấu trúc điều khiển (i. e. goog.module('search.urlHistory.UrlHistoryService'); 73, goog.module('search.urlHistory.UrlHistoryService'); 74, goog.module('search.urlHistory.UrlHistoryService'); 75, goog.module('search.urlHistory.UrlHistoryService'); 76, goog.module('search.urlHistory.UrlHistoryService'); 77, cũng như bất kỳ câu lệnh nào khác), ngay cả khi phần nội dung chỉ chứa một câu lệnh duy nhất. Câu lệnh đầu tiên của một khối không trống phải bắt đầu trên dòng của chính nó
không được phép
goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 4Ngoại lệ. Một câu lệnh if đơn giản có thể nằm 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 nhọn 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 goog.module('search.urlHistory.UrlHistoryService'); 74, goog.module('search.urlHistory.UrlHistoryService'); 79, goog.module('search.urlHistory.UrlHistoryService'); 77 hoặc dấu phẩy, dấu chấm phẩy hoặc dấu ngoặc đơn bên phải
Ví 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/goog.module('search.urlHistory.UrlHistoryService'); 74 hoặc goog.module('search.urlHistory.UrlHistoryService'); 84/goog.module('search.urlHistory.UrlHistoryService'); 79/goog.module('search.urlHistory.UrlHistoryService'); 86)
Ví 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'); 9____46_______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(); 1____46_______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ẫu
Ví dụ
goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 3_______46_______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 đó
Ví 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 goog.module('search.urlHistory.UrlHistoryService'); 89 và trường hợp sau
Ví 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 /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 66, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74 và /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 75 (xem và )
- Câu lệnh mô-đun ES /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 68 và goog.module('search.urlHistory.UrlHistoryService'); 08 (xem và )
- 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ả
Tip. Extracting a method or local variable may solve the problem without the need to line-wrap
4. 5. 1 Where to break
The prime directive of line-wrapping is. prefer to break at a higher syntactic level
Preferred
goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 7nản lòng
goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 8In the preceding example, the syntactic levels from highest to lowest are as follows. assignment, division, function call, parameters, number constant
Operators are wrapped as follows
- When a line is broken at an operator the break comes after the symbol. (Note that this is not the same practice used in Google style for Java. )
- This does not apply to the dot (goog.module('search.urlHistory.UrlHistoryService'); 95), which is not actually an operator
- A method or constructor name stays attached to the open parenthesis (goog.module('search.urlHistory.UrlHistoryService'); 96) that follows it
- A comma (goog.module('search.urlHistory.UrlHistoryService'); 97) stays attached to the token that precedes it
Ghi chú. The primary goal for line wrapping is to have clear code, not necessarily code that fits in the smallest number of lines
4. 5. 2 Indent continuation lines at least +4 spaces
When line-wrapping, each line after the first (each continuation line) is indented at least +4 from the original line, unless it falls under the rules of block indentation
When there are multiple continuation lines, indentation may be varied beyond +4 as appropriate. In general, continuation lines at a deeper syntactic level are indented by larger multiples of 4, and two lines use the same indentation level if and only if they begin with syntactically parallel elements
addresses the discouraged practice of using a variable number of spaces to align certain tokens with previous lines
4. 6 Whitespace
4. 6. 1 Vertical whitespace
A single blank line appears
- Between consecutive methods in a class or object literal
- Exception. A blank line between two consecutive properties definitions in an object literal (with no other code between them) is optional. Such blank lines are used as needed to create logical groupings of fields
- Within method bodies, sparingly to create logical groupings of statements. Blank lines at the start or end of a function body are not allowed
- Optionally before the first or after the last method in a class or object literal (neither encouraged nor discouraged)
- As required by other sections of this document (e. g. )
Multiple consecutive blank lines are permitted, but never required (nor encouraged)
4. 6. 2 Horizontal whitespace
Use of horizontal whitespace depends on location, and falls into three broad categories. leading (at the start of a line), trailing (at the end of a line), and internal. Leading whitespace (i. e. , indentation) is addressed elsewhere. Trailing whitespace is forbidden
Beyond where required by the language or other style rules, and apart from literals, comments, and JSDoc, a single internal ASCII space also appears in the following places only
- Separating any reserved word (such as goog.module('search.urlHistory.UrlHistoryService'); 73, goog.module('search.urlHistory.UrlHistoryService'); 75, or goog.module('search.urlHistory.UrlHistoryService'); 79) except for goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 01 and goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 02, from an open parenthesis (goog.module('search.urlHistory.UrlHistoryService'); 96) that follows it on that line
- Separating any reserved word (such as goog.module('search.urlHistory.UrlHistoryService'); 74 or goog.module('search.urlHistory.UrlHistoryService'); 79) from a closing curly brace (goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 06) that precedes it on that line
- Before any open curly brace (goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though
goog.module('foo.bar.baz');
07), with two exceptions
- Before an object literal that is the first argument of a function or the first element in an array literal (e. g. goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 08)
- In a template expansion, as it is forbidden by the language (e. g. valid. goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 09, invalid. goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 10)
- On both sides of any binary or ternary operator
- After a comma (goog.module('search.urlHistory.UrlHistoryService'); 97) or semicolon (goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 12). Note that spaces are never allowed before these characters
- After the colon (goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 13) in an object literal
- On both sides of the double slash (goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 14) that begins an end-of-line comment. Here, multiple spaces are allowed, but not required
- After an open-block comment character and on both sides of close characters (e. g. for short-form type declarations, casts, and parameter name comments. goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 15; or goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 16; or goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 17)
4. 6. 3 Horizontal alignment. discouraged
Terminology Note. Horizontal alignment is the practice of adding a variable number of additional spaces in your code with the goal of making certain tokens appear directly below certain other tokens on previous lines
This practice is permitted, but it is generally discouraged by Google Style. It is not even required to maintain horizontal alignment in places where it was already used
Here is an example without alignment, followed by one with alignment. Both are allowed, but the latter is discouraged
goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 9Tip. Alignment can aid readability, but it creates problems for future maintenance. Consider a future change that needs to touch just one line. This change may leave the formerly-pleasing formatting mangled, and that is allowed. More often it prompts the coder (perhaps you) to adjust whitespace on nearby lines as well, possibly triggering a cascading series of reformattings. Thay đổi một dòng đó hiện có bán kính vụ nổ. This can at worst result in pointless busywork, but at best it still corrupts version history information, slows down reviewers and exacerbates merge conflicts
4. 6. 4 Function arguments
Prefer to put all function arguments on the same line as the function name. If doing so would exceed the 80-column limit, the arguments must be line-wrapped in a readable way. To save space, you may wrap as close to 80 as possible, or put each argument on its own line to enhance readability. Indentation should be four spaces. Aligning to the parenthesis is allowed, but discouraged. Below are the most common patterns for argument wrapping
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 Grouping parentheses. recommended
Optional grouping parentheses are omitted only when the author and reviewer agree that there is no reasonable chance that the code will be misinterpreted without them, nor would they have made the code easier to read. It is not reasonable to assume that every reader has the entire operator precedence table memorized
Do not use unnecessary parentheses around the entire expression following goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 18, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 19, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 20, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 21, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 22, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 23, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 24, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 25, or goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 26
Parentheses are required for type casts. goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 27
This section addresses implementation comments. JSDoc is addressed separately in
Block comments are indented at the same level as the surrounding code. They may be in goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 28 or goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 14-style. For multi-line goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 28 comments, subsequent lines must start with * aligned with the goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 31 on the previous line, to make comments obvious with no extra context
const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 1Comments are not enclosed in boxes drawn with asterisks or other characters
Do not use JSDoc (/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 48) for implementation comments
“Parameter name” comments should be used whenever the value and method name do not sufficiently convey the meaning, and refactoring the method to be clearer is infeasible . Their preferred format is before the value 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}; 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
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'); 37
5. 1. 2 Mỗi khai báo một biến
Mỗi khai báo biến cục bộ chỉ khai báo một biến. 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ụng
5. 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. Instead, local variables are declared close to the point they are first used (within reason), to minimize their scope
5. 1. 4 Declare types as needed
JSDoc type annotations may be added either on the line above the declaration, or else inline before the variable name if no other JSDoc is present
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}; 4Mixing inline and JSDoc styles is not allowed. the compiler will only process the first JsDoc and the inline annotations will be lost
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}; 5Tip. There are many cases where the compiler can infer a templatized type but not its parameters. This is particularly the case when the initializing literal or constructor call does not include any values of the template parameter type (e. g. , empty arrays, objects, goog.module('search.urlHistory.UrlHistoryService'); 64s, or goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 40s), or if the variable is modified in a closure. Local variable type annotations are particularly helpful in these cases since otherwise the compiler will infer the template parameter as unknown
5. 2 Array literals
5. 2. 1 Use trailing commas
Include a trailing comma whenever there is a line break between the final element and the closing bracket
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}; 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
The constructor is error-prone if arguments are added or removed. Use a literal instead
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}; 7This works as expected except for the third case. if goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 42 is a whole number then goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 43 is an array of size goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 42 where all elements are goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 45. If goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 42 is any other number, then an exception will be thrown, and if it is anything else then it will be a single-element array
Instead, write
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}; 8Explicitly allocating an array of a given length using goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 47 is allowed when appropriate
5. 2. 3 Non-numeric properties
Do not define or use non-numeric properties on an array (other than goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 48). Use a goog.module('search.urlHistory.UrlHistoryService'); 64 (or goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 50) instead
5. 2. 4 Destructuring
Array literals may be used on the left-hand side of an assignment to perform destructuring (such as when unpacking multiple values from a single array or iterable). A final rest element may be included (with no space between the goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 51 and the variable name). Elements should be omitted if they are unused
const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 9Destructuring may also be used for function parameters (note that a parameter name is required but ignored). Always specify goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 52 as the default value if a destructured array parameter is optional, and provide default values on the left hand side
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 0không được phép
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 1Tip. For (un)packing multiple values into a function’s parameter or return, prefer object destructuring to array destructuring when possible, as it allows naming the individual elements and specifying a different type for each
5. 2. 5 Spread operator
Array literals may include the spread operator (goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 51) to flatten elements out of one or more other iterables. The spread operator should be used instead of more awkward constructs with goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 54. There is no space after the goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 51
Ví dụ
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 25. 3 Object literals
5. 3. 1 Use trailing commas
Include a trailing comma whenever there is a line break between the final property and the closing brace
5. 3. 2 Do not use the goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 50 constructor
While goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 50 does not have the same problems as goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 41, it is still disallowed for consistency. Use an object literal (goog.module('search.urlHistory.UrlHistoryService'); 81 or goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 60) instead
5. 3. 3 Do not mix quoted and unquoted keys
Object literals may represent either structs (with unquoted keys and/or symbols) or dicts (with quoted and/or computed keys). Do not mix these key types in a single object literal
không được phép
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 3This also extends to passing the property name to functions, like goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 61. In particular, doing so will break in compiled code because the compiler cannot rename/obfuscate the string literal
không được phép
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 4This is best implemented as
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 55. 3. 4 Computed property names
Computed property names (e. g. , goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 62) are allowed, and are considered dict-style (quoted) keys (i. e. , must not be mixed with non-quoted keys) unless the computed property is a symbol (e. g. , goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 63). Enum values may also be used for computed keys, but should not be mixed with non-enum keys in the same literal
5. 3. 5 Method shorthand
Methods can be defined on object literals using the method shorthand (goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 64) in place of a colon immediately followed by a goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 01 or arrow function literal
Ví dụ
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 6Note that goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 66 in a method shorthand or goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 01 refers to the object literal itself whereas goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 66 in an arrow function refers to the scope outside the object literal
Ví dụ
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 75. 3. 6 Shorthand properties
Shorthand properties are allowed on object literals
Ví dụ
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 85. 3. 7 Phá hủy
Object destructuring patterns may be used on the left-hand side of an assignment to perform destructuring and unpack multiple values from a single object
Destructured objects may also be used as function parameters, but should be kept as simple as possible. a single level of unquoted shorthand properties. Deeper levels of nesting and computed properties may not be used in parameter destructuring. Specify any default values in the left-hand-side of the destructured parameter (goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 69, rather than goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 70), and if a destructured object is itself optional, it must default to goog.module('search.urlHistory.UrlHistoryService'); 81. The JSDoc for the destructured parameter may be given any name (the name is unused but is required by the compiler)
Ví dụ
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 9không được phép
/** @const */ exports = {exportedFunction}; 0Destructuring may also be used for /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74 statements, and in this case must not be wrapped. the entire statement occupies one line, regardless of how long it is (see )
5. 3. 8 Enums
Enumerations are defined by adding the goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 73 annotation to an object literal. Additional properties may not be added to an enum after it is defined. Enums must be constant, and all enum values must be deeply immutable
/** @const */ exports = {exportedFunction}; 15. 4 Classes
5. 4. 1 Constructors
Constructors are optional. Subclass constructors must call goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 74 before setting any fields or otherwise accessing goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 66. Interfaces should declare non-method properties in the constructor
5. 4. 2 Fields
Set all of a concrete object’s fields (i. e. all properties other than methods) in the constructor. Annotate fields that are never reassigned with /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 96 (these need not be deeply immutable). Annotate non-public fields with the proper visibility annotation (/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 94, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 78, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 79), and end all /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 94 fields' names with an underscore. Fields are never set on a concrete class' goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 81
Ví dụ
/** @const */ exports = {exportedFunction}; 2Tip. Properties should never be added to or removed from an instance after the constructor is finished, since it significantly hinders VMs’ ability to optimize. Nếu cần, các trường được khởi tạo sau này phải được đặt rõ ràng thành goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 45 trong hàm tạo để ngăn thay đổi hình dạng sau này. Việc thêm goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 83 vào một đối tượng sẽ kiểm tra xem các thuộc tính không được khai báo không được thêm/truy cập. Classes have this added by default
5. 4. 3 Computed properties
Computed properties may only be used in classes when the property is a symbol. Dict-style properties (that is, quoted or computed non-symbol keys, as defined in ) are not allowed. A goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 63 method should be defined for any classes that are logically iterable. Beyond this, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 85 should be used sparingly
Tip. be careful of using any other built-in symbols (e. g. , goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 86) as they are not polyfilled by the compiler and will therefore not work in older browsers
5. 4. 4 phương thức 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ư
Static methods should only be called on the base class itself. Static methods should not be called on variables containing a dynamic instance that may be either the constructor or a subclass constructor (and must be defined with goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 87 if this is done), and must not be called directly on a subclass that doesn’t define the method itself
không được phép
/** @const */ exports = {exportedFunction}; 35. 4. 5 Old-style class declarations
While ES6 classes are preferred, there are cases where ES6 classes may not be feasible. For example
If there exist or will exist subclasses, including frameworks that create subclasses, that cannot be immediately changed to use ES6 class syntax. If such a class were to use ES6 syntax, all downstream subclasses not using ES6 class syntax would need to be modified
Frameworks that require a known goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 66 value before calling the superclass constructor, since constructors with ES6 super classes do not have access to the instance goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 66 value until the call to goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 02 returns
In all other ways the style guide still applies to this code. 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'); 33, default parameters, rest, and arrow functions should all be used when appropriate
goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 93 allows for a class-like definition similar to ES6 class syntax
/** @const */ exports = {exportedFunction}; 4Alternatively, while goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 93 should be preferred for all new code, more traditional syntax is also allowed
/** @const */ exports = {exportedFunction}; 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. Methods should be defined on the prototype of the constructor
Defining constructor prototype hierarchies correctly is harder than it first appears. For that reason, it is best to use goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 95 from the Closure Library
5. 4. 6 Do not manipulate goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 81s directly
The goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 97 keyword allows clearer and more readable class definitions than defining goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 81 properties. Ordinary implementation code has no business manipulating these objects, though they are still useful for defining classes as defined in . Mixins and modifying the prototypes of builtin objects are explicitly forbidden
Exception. Framework code (such as Polymer, or Angular) may need to use goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 81s, and should not resort to even-worse workarounds to avoid doing so
5. 4. 7 Getters and Setters
Do not use JavaScript getter and setter properties. They are potentially surprising and difficult to reason about, and have limited support in the compiler. Provide ordinary methods instead
Exception. there are situations where defining a getter or setter is unavoidable (e. g. data binding frameworks such as Angular and Polymer, or for compatibility with external APIs that cannot be adjusted). In these cases only, getters and setters may be used with caution, provided they are defined with the goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 00 and goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 01 shorthand method keywords or goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 02 (not goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 03, which interferes with property renaming). Getters must not change observable state
không được phép
/** @const */ exports = {exportedFunction}; 65. 4. 8 Overriding toString
The goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 04 method may be overridden, but must always succeed and never have visible side effects
Tip. Beware, in particular, of calling other methods from toString, since exceptional conditions could lead to infinite loops
5. 4. 9 Interfaces
Interfaces may be declared with goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 05 or goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 06. Interfaces declared with goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 06 can be explicitly (i. e. via goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 08) or implicitly implemented by a class or object literal
All non-static method bodies on an interface must be empty blocks. Fields must be declared as uninitialized members in the class constructor
Ví dụ
/** @const */ exports = {exportedFunction}; 75. 4. 10 Abstract Classes
Use abstract classes when appropriate. Abstract classes and methods must be annotated with 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 methods
5. 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 exports
ví 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'); 33
5. 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 parameters
The 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. , cho các biểu thức ngắn hoặc đơn giản)
ví dụ
import './sideeffects.js'; import * as goog from '../closure/goog/goog.js'; import * as parent from '../parent.js'; import {name} from './sibling.js'; 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 keyword
Ví 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 values
Ví 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 invocations
Tip. 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 name
Ví 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 definition
5. 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'); 51
Ví 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
Chuỗi ký tự thông thường không được trải dài trên nhiều dòng
5. 6. 2 Template literals
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 lines
If 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
Ví 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'; 7Instead, write
import './sideeffects.js'; import * as goog from '../closure/goog/goog.js'; import * as parent from '../parent.js'; import {name} from './sibling.js'; 85. 7 Number literals
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. Không bao giờ thêm số 0 ở đầu trừ khi ngay sau nó là goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 46, goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 47 hoặc goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 48
5. 8 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 possible
goog.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 possible
5. 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'); 63
This 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 functions
Custom 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
Prefer throwing exceptions over ad-hoc error-handling approaches (such as passing an error container reference type, or returning an object with an error property)
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. Unlike in some other languages, patterns like the above simply don’t work since this will catch the error thrown by goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 70. Use goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 71 instead
5. 8. 3 Switch statements
Terminology Note. Inside the braces of a switch block are one or more statement groups. Each statement group consists of one or more switch labels (either goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 72 or goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 73), followed by one or more statements
5. 8. 3. 1 Fall-through. 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 block
Ví 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 last
5. 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 JSDoc
Never 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 functions
5. 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 below
5. 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 values
import '../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 ES5
5. 11. 2 Dynamic code evaluation
Do not use goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 84 or the goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 93 constructor (except for code loaders). These features are potentially dangerous and simply do not work in CSP environments
5. 11. 3 Automatic semicolon insertion
Luôn kết thúc câu lệnh bằng dấu chấm phẩy (ngoại trừ khai báo hàm và lớp, như đã lưu ý ở trên)
5. 11. 4 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 forbidden
5. 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 annotations
khô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 symbols
Ví 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
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}; 01
khô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. Đừng lo lắng về việc tiết kiệm không gian theo chiều ngang vì điều quan trọng hơn nhiều là làm cho mã của bạn dễ hiểu ngay lập tức đối với người đọc mới. 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 Quy tắc theo loại định danh
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}; 07
6. 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. Các lớp chưa được xuất chỉ đơn giản là các lớp cục bộ. chúng không được đánh dấu /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 94 và do đó không được đặt tên với dấu gạch dưới
Tên loại thường là danh từ hoặc cụm danh từ. Ví dụ: const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 10, const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 11 hoặc const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 12. Ngoài ra, tên giao diện đôi khi có thể là tính từ hoặc cụm tính từ thay thế (ví dụ: const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 13)
6. 2. 3 Method names
Method names are written in goog.module('search.urlHistory.UrlHistoryService'); 01. Tên của phương pháp /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 94 phải kết thúc bằng dấu gạch dưới
Tên phương thức thường là động từ hoặc cụm động từ. 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. Các phương thức getter và setter cho các thuộc tính không bao giờ được yêu cầu, nhưng nếu chúng được sử dụng thì chúng nên được đặt tên là const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 18 (hoặc tùy chọn là const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 19 hoặc const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 20 đối với booleans) hoặc const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 21 đối với setters
Dấu gạch dưới cũng có thể xuất hiện trong tên phương thức thử nghiệm JsUnit để phân tách các thành phần logic của tên. 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. Không có một cách chính xác nào để đặt tên cho các phương pháp thử nghiệm
6. 2. 4 tên liệt kê
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. Các mục riêng lẻ trong enum được đặt tên trong const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 25
6. 2. 5 tên không đổi
Tên hằng sử dụng const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 25. tất cả các chữ cái viết hoa, với các từ được phân tách bằng dấu gạch dưới. Không có lý do gì để một hằng số được đặt tên với dấu gạch dưới ở cuối, vì các thuộc tính tĩnh riêng tư có thể được thay thế bằng các cục bộ mô-đun (ngầm riêng tư)
6. 2. 5. 1 Định nghĩa “hằng số”Mỗi hằng số là một thuộc tính tĩnh /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 96 hoặc một khai báo goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 33 mô-đun-cục bộ, nhưng không phải tất cả các thuộc tính tĩnh /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 96 và goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 33 mô-đun cục bộ đều là hằng số. Trước khi chọn trường hợp không đổi, hãy xem xét liệu trường có thực sự giống như một hằng số bất biến sâu sắc hay không. 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'; 00Tên hằng thường là danh từ hoặc cụm danh từ
6. 2. 5. 2 Bí danh cục bộCác bí danh cục bộ nên được sử dụng bất cứ khi nào chúng cải thiện khả năng đọc so với các tên đủ điều kiện. Thực hiện theo các quy tắc tương tự như /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74s (), giữ nguyên phần cuối của tên bí danh. Bí danh cũng có thể được sử dụng trong các chức năng. Bí danh phải là goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 33
ví dụ
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 016. 2. 6 Tên trường không cố định
Tên trường không cố định (tĩnh hoặc cách khác) được viết bằng goog.module('search.urlHistory.UrlHistoryService'); 01, với dấu gạch dưới cho các trường riêng tư
Những tên này thường là danh từ hoặc cụm danh từ. 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}; 35
6. 2. 7 tên tham số
Tên tham số được viết bằng goog.module('search.urlHistory.UrlHistoryService'); 01. Note that this applies even if the parameter expects a constructor
One-character parameter names should not be used in public methods
Exception. Khi được yêu cầu bởi khung của bên thứ ba, tên tham số có thể bắt đầu bằng const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 37. This exception does not apply to any other identifiers (e. g. local variables or properties)
6. 2. 8 Tên biến cục bộ
Tên biến cục bộ được viết bằng goog.module('search.urlHistory.UrlHistoryService'); 01, ngoại trừ các hằng số mô-đun-cục bộ (cấp cao nhất), như được mô tả ở trên. Các hằng số trong phạm vi chức năng vẫn được đặt tên trong goog.module('search.urlHistory.UrlHistoryService'); 01. Note that goog.module('search.urlHistory.UrlHistoryService'); 01 is used even if the variable holds a constructor
6. 2. 9 Tên tham số mẫu
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}; 42
6. 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. Điều này áp dụng cho các lớp, hàm, biến, hằng, enum và các mã định danh mô-đun-cục bộ khác
6. 3 Vỏ lạc đà. xác định
Đôi khi, có nhiều cách hợp lý để chuyển đổi một cụm từ tiếng Anh thành trường hợp lạc đà, chẳng hạn như khi có từ viết tắt hoặc cấu trúc bất thường như IPv6 hoặc iOS. Để cải thiện khả năng dự đoán, Google Style chỉ định lược đồ xác định (gần như) sau đây
Bắt đầu với hình thức văn xuôi của tên
- Chuyển đổi cụm từ thành ASCII đơn giản và xóa mọi dấu nháy đơn. Ví dụ, thuật toán của Müller có thể trở thành thuật toán của Mueller
- Divide this result into words, splitting on spaces and any remaining punctuation (typically hyphens)
- Khuyến khích. if any word already has a conventional camel case appearance in common usage, split this into its constituent parts (e. g. , AdWords trở thành từ quảng cáo). 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
- … mỗi từ ngoại trừ từ đầu tiên, để mang lại trường hợp lạc đà thấp hơn
- Cuối cùng, nối tất cả các từ thành một định danh duy nhất
Lưu ý rằng cách viết hoa của các từ gốc gần như hoàn toàn bị bỏ qua
ví dụ
Prose formCorrectIncorrectXML HTTP requestXmlHttpRequestXMLHTTPRequestnew customer IDnewCustomerIdnewCustomerIDinner stopwatchinnerStopwatchinnerStopWatchsupports IPv6 on iOS?supportsIpv6OnIossupportsIPv6OnIOSYouTube importerYouTubeImporterYoutubeImporter**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 lines
Many tools extract metadata from JSDoc comments to perform code validation and optimization. As such, these comments must be well-formed
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 description
A file may have a top-level file overview. Thông báo bản quyền, thông tin tác giả và mặc định là tùy chọn. File overviews are generally recommended whenever a file consists of more than a single class definition. Nhận xét cấp cao nhất được thiết kế để hướng người đọc không quen thuộc với mã đến nội dung trong tệp này. If present, it may provide a description of the file's contents and any dependencies or compatibility information. Wrapped lines are not indented
Ví 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'; 11Tất cả các enum và typedef phải được ghi lại bằng các thẻ JSDoc thích hợp (const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 56 hoặc goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 73) ở dòng trước. Public enums and typedefs must also have a description. Các mục enum riêng lẻ có thể được ghi lại bằng nhận xét JSDoc trên dòng trước
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 12Typedefs rất hữu ích để xác định các loại bản ghi ngắn hoặc bí danh cho các liên kết, các hàm phức tạp hoặc các loại chung. Typedefs nên tránh đối với các loại bản ghi có nhiều trường, vì chúng không cho phép ghi lại các trường riêng lẻ, cũng như không sử dụng mẫu hoặc tham chiếu đệ quy. Đối với các loại bản ghi lớn, hãy ưu tiên goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 06
Trong các phương thức và hàm được đặt tên, tham số và kiểu trả về phải được ghi lại, ngoại trừ trường hợp của các const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 59 có cùng chữ ký, trong đó tất cả các kiểu được bỏ qua. Loại goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 66 phải được ghi lại khi cần thiết. Kiểu trả về có thể được bỏ qua nếu hàm không có câu lệnh goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 21 không trống
Các mô tả phương thức, tham số và trả về (nhưng không phải kiểu) có thể bị bỏ qua nếu chúng hiển nhiên từ phần còn lại của JSDoc của phương thức hoặc từ chữ ký của nó
Mô tả phương thức bắt đầu bằng một cụm động từ mô tả chức năng của phương thức. Cụm từ này không phải là một câu mệnh lệnh, mà thay vào đó được viết ở ngôi thứ ba, như thể có một ngụ ý. trước nó
Nếu một phương thức ghi đè một phương thức của lớp bậc trên, nó phải bao gồm một chú thích const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 59. Các phương thức bị ghi đè kế thừa tất cả các chú thích JSDoc từ phương thức siêu hạng (bao gồm cả các chú thích khả năng hiển thị) và chúng nên được bỏ qua trong phương thức bị ghi đè. Tuy nhiên, nếu bất kỳ loại nào được tinh chỉnh trong chú thích loại, thì tất cả chú thích const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 63 và const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 64 phải được chỉ định rõ ràng
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 13Nếu bạn chỉ cần ghi lại thông số và kiểu trả về của hàm, bạn có thể tùy ý sử dụng JSDocs nội tuyến trong chữ ký của hàm. Các JSDoc nội tuyến này chỉ định các loại trả về và thông số không có thẻ
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 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. Ví dụ: các phương thức trả về giá trị cần thẻ const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 64
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 15/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 16Trong các chú thích chức năng ẩn danh thường là tùy chọn. Nếu suy luận loại tự động không đủ hoặc chú thích rõ ràng cải thiện khả năng đọc, thì hãy chú thích thông số và trả về các loại như thế này
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 17Đối với các biểu thức loại chức năng, xem
Property types must be documented. The description may be omitted for private properties, if name and type provide enough documentation for understanding the code
Các hằng số được xuất công khai được nhận xét giống như các thuộc tính
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 187. 10 Loại chú thích
Chú thích loại được tìm thấy trên các thẻ const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 63, const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 64, goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 82 và const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 69 và tùy chọn trên thẻ /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 96, const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 49 và bất kỳ thẻ hiển thị nào. Các chú thích loại được đính kèm với các thẻ JSDoc phải luôn được đặt trong dấu ngoặc nhọn
7. 10. 1 Nullability
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. Các công cụ sửa đổi này phải đứng trước loại
Công cụ sửa đổi tính vô hiệu có các yêu cầu khác nhau đối với các loại khác nhau, được chia thành hai loại chính
- Type annotations for primitives (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}; 74, const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 75, const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 76, const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 77, goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 45, goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 89) and literals (const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 80 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}; 81) are always non-nullable by default. Use the 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 modifier to make it nullable, but omit the redundant 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
- Các loại tham chiếu (nói chung, mọi thứ trong const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 08, bao gồm cả const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 85) đề cập đến một lớp, enum, bản ghi hoặc typedef được xác định ở nơi khác. Vì các loại này có thể có hoặc không thể vô hiệu hóa, nên không thể chỉ từ cái tên mà biết nó có thể vô hiệu hóa hay không. Luôn sử dụng các công cụ sửa đổi rõ ràng const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 73 và const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 72 cho các loại này để tránh sự mơ hồ tại các trang web sử dụng
Bad
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 19Tốt
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 207. 10. 2 Type Casts
Trong trường hợp trình biên dịch không suy luận chính xác loại biểu thức và các hàm xác nhận trong goog. khẳng định không thể khắc phục nó, có thể thắt chặt loại bằng cách thêm nhận xét chú thích loại và đặt biểu thức trong ngoặc đơn. Lưu ý rằng dấu ngoặc đơn là bắt buộc
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 217. 10. 3 Template Parameter Types
Luôn chỉ định tham số mẫu. Bằng cách này, trình biên dịch có thể thực hiện công việc tốt hơn và giúp người đọc dễ dàng hiểu mã làm gì hơn
Bad
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 22Tốt
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 23Các trường hợp không nên sử dụng tham số mẫu
- goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 50 is used for type hierarchy and not as map-like structure
7. 10. 4 Function type expressions
Terminology Note. biểu thức loại hàm đề cập đến một chú thích loại cho các loại hàm với từ khóa goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 01 trong chú thích (xem ví dụ bên dưới)
Khi định nghĩa hàm được đưa ra, không sử dụng biểu thức kiểu hàm. Chỉ định tham số và kiểu trả về 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}; 63 và const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 64 hoặc với chú thích nội tuyến (xem phần ). Điều này bao gồm các hàm ẩn danh và các hàm được xác định và gán cho một const (trong đó hàm jsdoc xuất hiện phía trên toàn bộ biểu thức gán)
Cần có các biểu thức kiểu hàm, ví dụ, bên trong const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 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 hoặc const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 64. Cũng sử dụng nó cho các biến hoặc thuộc tính của kiểu hàm, nếu chúng không được khởi tạo ngay với định nghĩa hàm
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 24Khi sử dụng biểu thức kiểu hàm, luôn chỉ định rõ ràng kiểu trả về. Mặt khác, loại trả về mặc định là không xác định (_______57_______73), dẫn đến hành vi kỳ lạ và không mong muốn, và hiếm khi là điều thực sự mong muốn
Xấu - gõ lỗi, nhưng không đưa ra cảnh báo
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 25Tốt
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 267. 10. 5 khoảng trắng
Trong một chú thích loại, cần có một dấu cách hoặc ngắt dòng sau mỗi dấu phẩy hoặc dấu hai chấm. Các ngắt dòng bổ sung có thể được chèn vào để cải thiện khả năng đọc hoặc tránh vượt quá giới hạn cột. Những dấu ngắt này nên được chọn và thụt lề theo hướng dẫn hiện hành (e. g. Và ). Không có khoảng trắng nào khác được phép trong chú thích loại
Tốt
/* 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 chú thích hiển thị
Chú thích khả năng hiển thị (/* 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) có thể được chỉ định trong khối /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 70 hoặc trên bất kỳ biểu tượng hoặc thuộc tính được xuất nào. Không chỉ định khả năng hiển thị cho các biến cục bộ, cho dù trong một chức năng hay ở cấp cao nhất của mô-đun. All /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 94 names must end with an underscore
8 chính sách
8. 1 Sự cố không được chỉ định bởi Google Style. Be Consistent
Đối với bất kỳ câu hỏi về phong cách nào không được giải quyết dứt khoát bởi thông số kỹ thuật này, hãy ưu tiên thực hiện những gì mà mã khác trong cùng một tệp đang thực hiện. Nếu điều đó không giải quyết được câu hỏi, hãy xem xét mô phỏng các tệp khác trong cùng một gói
8. 2 Cảnh báo trình biên dịch
8. 2. 1 Sử dụng bộ cảnh báo tiêu chuẩn
Các dự án càng nhiều càng tốt nên sử dụng /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 01
8. 2. 2 Cách xử lý cảnh báo
Trước khi làm bất cứ điều gì, hãy chắc chắn rằng bạn hiểu chính xác những gì cảnh báo đang nói với bạn. Nếu bạn không chắc tại sao lại xuất hiện cảnh báo, hãy yêu cầu trợ giúp
Khi bạn hiểu cảnh báo, hãy thử các giải pháp sau theo thứ tự
- Đầu tiên, sửa chữa nó hoặc làm việc xung quanh nó. Thực hiện một nỗ lực mạnh mẽ để thực sự giải quyết cảnh báo hoặc tìm cách khác để hoàn thành nhiệm vụ tránh hoàn toàn tình huống
- Nếu không, hãy xác định xem đó có phải là báo động giả không. Nếu bạn tin rằng cảnh báo không hợp lệ và mã thực sự an toàn và chính xác, hãy thêm nhận xét để thuyết phục người đọc về sự thật này và áp dụng chú thích /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 02
- Otherwise, leave a TODO comment. Đây là một phương sách cuối cùng. Nếu bạn làm điều này, đừng chặn cảnh báo. 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
Các cảnh báo bị loại bỏ ở phạm vi hợp lý hẹp nhất, thường là của một biến cục bộ hoặc phương thức rất nhỏ. Thường thì một biến hoặc phương thức được trích xuất chỉ vì lý do đó
Ví dụ
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 29Ngay cả một số lượng lớn các biện pháp ngăn chặn trong một lớp vẫn tốt hơn là làm mù cả lớp trước kiểu cảnh báo này
Đánh dấu các phương thức, lớp hoặc giao diện không dùng nữa bằng chú thích /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 03. Nhận xét không dùng nữa phải bao gồm hướng dẫn đơn giản, rõ ràng để mọi người khắc phục trang web cuộc gọi của họ
8. 4 Mã không có trong Google Style
Đôi khi, bạn sẽ gặp phải các tệp trong cơ sở mã của mình không đúng với Google Style. Chúng có thể đến từ việc mua lại hoặc có thể đã được viết trước khi Google Style đưa ra quan điểm về một số vấn đề hoặc có thể không thuộc Google Style vì bất kỳ lý do nào khác
8. 4. 1 Định dạng lại mã hiện có
Khi cập nhật kiểu mã hiện có, hãy làm theo các hướng dẫn sau
- Không bắt buộc phải thay đổi tất cả mã hiện có để đáp ứng các nguyên tắc về kiểu dáng hiện tại. Định dạng lại mã hiện có là sự đánh đổi giữa mã rời và tính nhất quán. Các quy tắc về phong cách phát triển theo thời gian và những loại chỉnh sửa này để duy trì sự tuân thủ sẽ tạo ra sự xáo trộn không cần thiết. Tuy nhiên, nếu những thay đổi quan trọng đang được thực hiện đối với một tệp thì tệp đó sẽ nằm trong Google Style
- Hãy cẩn thận để không cho phép các sửa đổi phong cách cơ hội làm xáo trộn trọng tâm của CL. Nếu bạn thấy mình thực hiện nhiều thay đổi về phong cách không quan trọng đối với trọng tâm của CL, hãy quảng bá những thay đổi đó thành một CL riêng
8. 4. 2 Mã mới được thêm vào. sử dụng Google Phong cách
Các tệp hoàn toàn mới sử dụng Google Style, bất kể lựa chọn kiểu của các tệp khác trong cùng một gói
Khi thêm mã mới vào tệp không có trong Google Style, trước tiên nên định dạng lại mã hiện có, tuân theo lời khuyên trong
Nếu việc định dạng lại này không được thực hiện, thì mã mới phải nhất quán nhất có thể với mã hiện có trong cùng một tệp, nhưng không được vi phạm hướng dẫn về kiểu dáng
8. 5 Quy tắc phong cách cục bộ
Các nhóm và dự án có thể áp dụng các quy tắc kiểu bổ sung ngoài những quy tắc trong tài liệu này, nhưng phải chấp nhận rằng các thay đổi dọn dẹp có thể không tuân theo các quy tắc bổ sung này và không được chặn các thay đổi dọn dẹp đó do vi phạm bất kỳ quy tắc bổ sung nào. Cẩn thận với các quy tắc quá mức không phục vụ mục đích. Hướng dẫn về phong cách không tìm cách xác định phong cách trong mọi tình huống có thể xảy ra và bạn cũng vậy.
8. 6 Mã được tạo. chủ yếu được miễn
Mã nguồn được tạo bởi quá trình xây dựng không bắt buộc phải có trong Google Style. Tuy nhiên, mọi số nhận dạng được tạo sẽ được tham chiếu từ mã nguồn viết tay phải tuân theo các yêu cầu đặt tên. Là một ngoại lệ đặc biệt, các số nhận dạng như vậy được phép chứa dấu gạch dưới, điều này có thể giúp tránh xung đột với các số nhận dạng viết tay
9 phụ lục
9. 1 tham chiếu thẻ JSDoc
JSDoc phục vụ nhiều mục đích trong JavaScript. Ngoài việc được sử dụng để tạo tài liệu, nó còn được sử dụng để kiểm soát công cụ. Được biết đến nhiều nhất là các chú thích loại Trình biên dịch đóng cửa
9. 1. 1 Chú thích loại và các chú thích Trình biên dịch đóng cửa khác
Tài liệu cho JSDoc được Trình biên dịch đóng sử dụng được mô tả trong Chú thích JavaScript cho Trình biên dịch đóng và các loại trong Hệ thống loại đóng
9. 1. 2 Chú thích tài liệu
Ngoài JSDoc được mô tả trong Chú thích JavaScript cho Trình biên dịch đóng, các thẻ sau là phổ biến và được hỗ trợ tốt bởi các công cụ tạo tài liệu khác nhau (chẳng hạn như JsDossier) cho các mục đích tài liệu thuần túy
Bạn cũng có thể thấy các loại chú thích JSDoc khác trong mã của bên thứ ba. Các chú thích này xuất hiện trong Tham chiếu thẻ của Bộ công cụ JSDoc nhưng không được coi là một phần của kiểu Google hợp lệ
Không được khuyến khích
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'; 30Tài liệu về tác giả của tệp hoặc chủ sở hữu của bài kiểm tra, thường chỉ được sử dụng trong phần bình luận /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 70. Thẻ /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 05 được sử dụng bởi bảng điều khiển kiểm tra đơn vị để xác định ai sở hữu kết quả kiểm tra
cú pháp. /** @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'; 31Cho biết những lỗi mà chức năng kiểm tra đã cho kiểm tra hồi quy
Mỗi lỗi nên có dòng /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 09 riêng, để giúp việc tìm kiếm các bài kiểm tra hồi quy trở nên dễ dàng nhất có thể
không dùng nữa. Không được dùng. Sử dụng backticks Markdown để thay thế
cú pháp. /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 13
Trong lịch sử, /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 14 được viết là /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 15
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 32Cho biết rằng một thuật ngữ trong mô tả JSDoc là mã để nó có thể được định dạng chính xác trong tài liệu được tạo
cú pháp. /** @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'; 33cú pháp. /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 19
Thẻ này được sử dụng để tạo liên kết tham chiếu chéo trong tài liệu được tạo
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 34Ghi chú lịch sử. Các thẻ @link cũng đã được sử dụng để tạo các liên kết bên ngoài trong tài liệu được tạo. Đối với các liên kết bên ngoài, hãy luôn sử dụng cú pháp liên kết của Markdown để thay thế
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 35cú pháp. /** @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'; 36Tham chiếu tra cứu đến một hàm hoặc phương thức lớp khác
cú pháp. /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 23
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 37Được sử dụng trong phần tổng quan về tệp để cho biết trình duyệt nào được tệp hỗ trợ
9. 1. 3 Chú thích cụ thể của khung
Các chú thích sau đây dành riêng cho một khung cụ thể
https. //github. com/google/closure-compiler/wiki/Polymer-Pass
9. 1. 4 Lưu ý về chú thích Trình biên dịch đóng cửa tiêu chuẩn
The following tags used to be standard but are now deprecated
không dùng nữa. Không được dùng. Sử dụng const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 49 và/hoặc goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 87 thay thế
không dùng nữa. Do not use. Sử dụng const /** !Array */ exportedArray = [1, 2, 3]; const /** !Array */ moduleLocalArray = [4, 5, 6]; /** @return {number} */ function moduleLocalFunction() { return moduleLocalArray.length; } /** @return {number} */ function exportedFunction() { return moduleLocalFunction() * 2; } exports = {exportedArray, exportedFunction}; 59 để thay thế
9. 2 Quy tắc phong cách thường bị hiểu lầm
Đây là tập hợp các sự kiện ít được biết đến hoặc thường bị hiểu lầm về Google Style cho JavaScript. (Sau đây là những tuyên bố đúng; đây không phải là danh sách những huyền thoại. )
- Không yêu cầu tuyên bố bản quyền cũng như tín dụng /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 04 trong tệp nguồn. (Cả hai đều không được khuyến nghị rõ ràng. )
- There is no hard and fast rule governing how to order the members of a class ()
- Các khối rỗng thường có thể được biểu diễn chính xác dưới dạng goog.module('search.urlHistory.UrlHistoryService'); 81, như được trình bày chi tiết trong ()
- Chỉ thị chính của line-wrapping là. thích ngắt ở cấp độ cú pháp cao hơn ()
- Các ký tự không phải ASCII được cho phép ở dạng chuỗi ký tự, nhận xét và JSDoc, và trên thực tế được khuyến nghị khi chúng làm cho mã dễ đọc hơn so với lối thoát Unicode tương đương ()
Các công cụ sau tồn tại để hỗ trợ các khía cạnh khác nhau của Google Style
9. 3. 1 Trình biên dịch đóng cửa
Chương trình này thực hiện kiểm tra kiểu và các kiểm tra khác, tối ưu hóa và các chuyển đổi khác (chẳng hạn như giảm mã ECMAScript 6 xuống ECMAScript 5)
9. 3. 2 goog.module('search.urlHistory.UrlHistoryService'); 71
Chương trình này định dạng lại mã nguồn JavaScript thành Google Style và cũng tuân theo một số phương pháp định dạng nâng cao khả năng đọc không bắt buộc nhưng thường xuyên. Đầu ra do goog.module('search.urlHistory.UrlHistoryService'); 71 tạo ra tuân theo hướng dẫn về phong cách
goog.module('search.urlHistory.UrlHistoryService'); 71 không bắt buộc. Các tác giả được phép thay đổi đầu ra của nó và người đánh giá được phép yêu cầu những thay đổi đó; . 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 Đóng trình biên dịch 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 Khung tuân thủ
JS Conformance Framework là một công cụ nằm trong Closure Compiler cung cấp cho các nhà phát triển một phương tiện đơn giản để chỉ định một tập hợp các kiểm tra bổ sung sẽ được chạy đối với cơ sở mã của họ trên các kiểm tra tiêu chuẩn. Ví dụ: kiểm tra sự phù hợp có thể cấm truy cập vào một thuộc tính nhất định hoặc lệnh gọi đến một chức năng nhất định hoặc thiếu thông tin loại (không xác định)
Các quy tắc này thường được sử dụng để thực thi các hạn chế quan trọng (chẳng hạn như xác định toàn cầu, có thể phá vỡ cơ sở mã) và các mẫu bảo mật (chẳng hạn như sử dụng goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 84 hoặc gán cho ____58_______37) hoặc để cải thiện chất lượng mã một cách lỏng lẻo hơn
Để biết thêm thông tin, hãy xem tài liệu chính thức về Khung tuân thủ JS
9. 4 Ngoại lệ cho các nền tảng cũ
9. 4. 1. Khái quát chung
Phần này mô tả các ngoại lệ và quy tắc bổ sung cần tuân theo khi cú pháp ECMAScript 6 hiện đại không có sẵn cho tác giả mã. Các ngoại lệ đối với kiểu được đề xuất là bắt buộc khi không thể sử dụng cú pháp ECMAScript 6 và được nêu tại đây
- Cho phép sử dụng khai báo goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 37
- Cho phép sử dụng goog.module('my.test.helpers'); goog.module.declareLegacyNamespace(); goog.setTestOnly(); 31
- Cho phép tham số tùy chọn không có giá trị mặc định
9. 4. 2 Sử dụng goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 37
9. 4. 2. 1 goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 37 khai báo KHÔNG nằm trong phạm vi khốiCác khai báo goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 37 nằm trong phạm vi bắt đầu của hàm, tập lệnh hoặc mô-đun kèm theo gần nhất, điều này có thể gây ra hành vi không mong muốn, đặc biệt là với các bao hàm tham chiếu tới các khai báo goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 37 bên trong các vòng lặp. Đoạn mã sau đưa ra một ví dụ
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 389. 4. 2. 2 Khai báo các biến càng gần với lần sử dụng đầu tiên càng tốtMặc dù khai báo goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 37 nằm trong phạm vi bắt đầu của chức năng kèm theo, khai báo goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 37 phải càng gần với lần sử dụng đầu tiên càng tốt, vì mục đích dễ đọc. Tuy nhiên, không đặt khai báo goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 37 bên trong khối nếu biến đó được tham chiếu bên ngoài khối. Ví dụ
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 399. 4. 2. 3 Sử dụng @const cho các biến hằngĐối với các khai báo toàn cầu nơi từ khóa goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 33 sẽ được sử dụng, nếu có, hãy chú thích khai báo goog.module('foo.bar'); // 'foo.bar.qux' would be fine, though goog.module('foo.bar.baz'); 37 bằng @const thay thế (đây là tùy chọn cho các biến cục bộ)
9. 4. 3 Không sử dụng khai báo hàm phạm vi khối
Đừng làm điều này
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 40Mặc dù hầu hết các máy ảo JavaScript được triển khai trước khi ECMAScript 6 hỗ trợ khai báo hàm trong các khối nhưng nó không được chuẩn hóa. Việc triển khai không nhất quán với nhau và với hành vi ECMAScript 6 tiêu chuẩn hiện nay để khai báo hàm phạm vi khối. ECMAScript 5 trở về trước chỉ cho phép khai báo hàm trong danh sách câu lệnh gốc của tập lệnh hoặc hàm và cấm rõ ràng chúng trong phạm vi khối ở chế độ nghiêm ngặt
Để có được hành vi nhất quán, thay vào đó, hãy sử dụng một ____________37 được khởi tạo với một biểu thức hàm để xác định một hàm trong một khối
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 419. 4. 4 Quản lý phụ thuộc với goog.module('search.urlHistory.UrlHistoryService'); 18//* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74
9. 4. 4. 1. Tóm tắtCẢNH BÁO. goog.module('search.urlHistory.UrlHistoryService'); 18 quản lý phụ thuộc không được dùng nữa. Tất cả các tệp mới, ngay cả trong các dự án sử dụng goog.module('search.urlHistory.UrlHistoryService'); 18 cho các tệp cũ hơn, nên sử dụng. Các quy tắc sau đây chỉ dành cho các tệp goog.module('search.urlHistory.UrlHistoryService'); 18 đã có từ trước
- Đặt tất cả goog.module('search.urlHistory.UrlHistoryService'); 18 đầu tiên, /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74 giây. Tách cung cấp khỏi yêu cầu bằng một dòng trống
- Sắp xếp các mục theo thứ tự bảng chữ cái (viết hoa trước)
- Không bọc câu lệnh goog.module('search.urlHistory.UrlHistoryService'); 18 và /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74. Vượt quá 80 cột nếu cần
- Chỉ cung cấp các biểu tượng cấp cao nhất
goog.module('search.urlHistory.UrlHistoryService'); 18 câu lệnh nên được nhóm lại với nhau và đặt ở vị trí đầu tiên. Tất cả các câu lệnh /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74 phải tuân theo. Hai danh sách phải được phân tách bằng một dòng trống
Tương tự như câu lệnh nhập bằng các ngôn ngữ khác, câu lệnh goog.module('search.urlHistory.UrlHistoryService'); 18 và /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74 phải được viết trên một dòng, ngay cả khi chúng vượt quá giới hạn độ dài dòng 80 cột
Các dòng nên được sắp xếp theo thứ tự bảng chữ cái, với các chữ cái viết hoa đến trước
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 42Tất cả các thành viên được xác định trên một lớp phải ở trong cùng một tệp. Only top-level classes should be provided in a file that contains multiple members defined on the same class (e. g. enums, các lớp bên trong, v.v.)
Làm cái này
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 43Không phải cái này
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 44Thành viên trên không gian tên cũng có thể được cung cấp
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 459. 4. 4. 2 Bí danh với /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 64CẢNH BÁO. /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 64 không được dùng nữa. Các tệp mới không nên sử dụng /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 64 ngay cả trong các dự án có sử dụng /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 64 hiện tại
/** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 64 có thể được sử dụng để rút ngắn các tham chiếu đến các ký hiệu được đặt tên trong mã bằng cách sử dụng quản lý phụ thuộc goog.module('search.urlHistory.UrlHistoryService'); 18/_______5_______74
Chỉ có thể thêm một lệnh gọi /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 64 cho mỗi tệp. Luôn đặt nó trong phạm vi toàn cầu
Lời gọi /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 72 mở đầu phải được đặt trước chính xác một dòng trống và theo sau mọi câu lệnh goog.module('search.urlHistory.UrlHistoryService'); 18, câu lệnh /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74 hoặc nhận xét cấp cao nhất. Lệnh gọi phải được đóng ở dòng cuối cùng trong tệp. Nối /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 75 vào phần kết thúc của phạm vi. Tách nhận xét khỏi dấu chấm phẩy bằng hai dấu cách
Tương tự như không gian tên C++, không thụt lề dưới các khai báo /** @const {number} */ exports.CONSTANT_ONE = 1; /** @const {string} */ exports.CONSTANT_TWO = 'Another constant'; 64. Thay vào đó, hãy tiếp tục từ cột 0
Chỉ tạo bí danh cho các tên sẽ không được gán lại cho đối tượng khác (e. g. , hầu hết các hàm tạo, enum và không gian tên). Đừng làm điều này (xem bên dưới để biết cách đặt bí danh cho hàm tạo)
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 46Tên phải giống với thuộc tính cuối cùng của toàn cầu mà chúng đang đặt bí danh
/* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 479. 4. 4. 3 goog.module('search.urlHistory.UrlHistoryService'); 25Thích sử dụng /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 75 thay vì goog.module('search.urlHistory.UrlHistoryService'); 25 để phá vỡ sự phụ thuộc vòng tròn giữa các tệp trong cùng một thư viện. Không giống như /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 74, câu lệnh /* Poor: the reader has no idea what character this is. */ const units = '\u03bcs'; 75 được phép nhập một không gian tên trước khi nó được xác định
goog.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 dài 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