javascript
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJavaScript/Node.js Style Guide
JavaScript/Node.js 风格指南
Apply Google JavaScript Style Guide conventions to JavaScript and Node.js code. This skill provides essential coding standards, formatting rules, and best practices for writing clean, maintainable JavaScript.
Note: Google recommends migrating to TypeScript. This guide is for JavaScript projects that have not yet migrated.
将Google JavaScript风格指南的规范应用于JavaScript和Node.js代码。本技能提供编写整洁、可维护JavaScript代码所需的核心编码标准、格式化规则及最佳实践。
注意:Google建议迁移至TypeScript。本指南适用于尚未迁移的JavaScript项目。
Core Principles
核心原则
File Basics
文件基础
File naming:
- Use lowercase only
- Use underscores () or dashes (
_) but no other punctuation- - Extension must be
.js - Examples: ,
my_module.jsuser-service.js
File encoding:
- UTF-8 only
- Use special escape sequences for special characters (,
\',\",\\,\b,\f,\n,\r,\t)\v - For non-ASCII: use actual Unicode character (e.g., ) or hex escape (e.g.,
∞) based on readability\u221e
Indentation:
- Use 2 spaces (never tabs)
- No trailing whitespace
文件命名:
- 仅使用小写字母
- 使用下划线()或短横线(
_),禁止使用其他标点符号- - 扩展名必须为
.js - 示例:,
my_module.jsuser-service.js
文件编码:
- 仅使用UTF-8编码
- 特殊字符使用转义序列(,
\',\",\\,\b,\f,\n,\r,\t)\v - 非ASCII字符:根据可读性选择使用实际Unicode字符(如)或十六进制转义(如
∞)\u221e
缩进:
- 使用2个空格(绝不使用制表符)
- 禁止行尾空白
Module System
模块系统
ES Modules (Preferred)
ES Modules(推荐)
Use and statements:
importexportjavascript
// Imports
import './sideeffects.js';
import * as goog from '../closure/goog/goog.js';
import {name, value} from './sibling.js';
// Named exports only (no default exports)
export class Foo { ... }
export function bar() { ... }
// Or export together
class Foo { ... }
function bar() { ... }
export {Foo, bar};Import rules:
- Include extension in paths (required)
.js - Use for module import names:
lowerCamelCaseimport * as fileOne from '../file-one.js'; - Keep same name for named imports, avoid aliasing unless necessary
- Do not use default exports
- Import statements are exception to 80-column limit (do not wrap)
Avoid circular dependencies - Do not create import cycles between modules.
使用和语句:
importexportjavascript
// Imports
import './sideeffects.js';
import * as goog from '../closure/goog/goog.js';
import {name, value} from './sibling.js';
// Named exports only (no default exports)
export class Foo { ... }
export function bar() { ... }
// Or export together
class Foo { ... }
function bar() { ... }
export {Foo, bar};导入规则:
- 路径中必须包含扩展名
.js - 模块导入名称使用格式:
lowerCamelCaseimport * as fileOne from '../file-one.js'; - 命名导入保持原名称,除非必要否则避免别名
- 禁止使用默认导出
- 语句不受80字符限制(无需换行)
import
避免循环依赖 - 不要在模块之间创建导入循环。
Variable Declarations
变量声明
Use const and let
使用const和let
javascript
// Use const by default
const MAX_COUNT = 100;
const users = [];
// Use let only when reassignment needed
let currentIndex = 0;
// NEVER use varOne variable per declaration:
javascript
// Good
const a = 1;
const b = 2;
// Bad
const a = 1, b = 2;Declare close to first use:
javascript
// Good - declared when needed
function process(items) {
// ... some code ...
const result = items.map(x => x * 2);
return result;
}javascript
// Use const by default
const MAX_COUNT = 100;
const users = [];
// Use let only when reassignment needed
let currentIndex = 0;
// NEVER use var每个声明仅一个变量:
javascript
// Good
const a = 1;
const b = 2;
// Bad
const a = 1, b = 2;在首次使用前就近声明:
javascript
// Good - declared when needed
function process(items) {
// ... some code ...
const result = items.map(x => x * 2);
return result;
}Formatting
格式化
Braces
大括号
K&R style (Egyptian brackets):
javascript
class InnerClass {
constructor() {}
method(foo) {
if (condition(foo)) {
try {
something();
} catch (err) {
recover();
}
}
}
}Rules:
- No line break before opening brace
- Line break after opening brace
- Line break before closing brace
- Line break after closing brace (except before ,
else,catch, comma, semicolon)while
Always use braces for control structures (even single statements):
javascript
// Good
if (condition) {
doSomething();
}
// Exception: single-line if without else
if (shortCondition()) foo();
// Bad
if (condition)
doSomething();K&R风格(埃及括号):
javascript
class InnerClass {
constructor() {}
method(foo) {
if (condition(foo)) {
try {
something();
} catch (err) {
recover();
}
}
}
}规则:
- 左大括号前不换行
- 左大括号后换行
- 右大括号前换行
- 右大括号后换行(、
else、catch、逗号、分号之前除外)while
控制结构始终使用大括号(即使是单行语句):
javascript
// Good
if (condition) {
doSomething();
}
// Exception: single-line if without else
if (shortCondition()) foo();
// Bad
if (condition)
doSomething();Column Limit
列数限制
80 characters with exceptions:
- and
importstatementsexport from - Long URLs, shell commands, file paths in comments
- Lines where wrapping is impossible
80字符,以下情况除外:
- 和
import语句export from - 注释中的长URL、Shell命令、文件路径
- 无法换行的行
Line Wrapping
换行
Break at higher syntactic levels:
javascript
// Good
currentEstimate =
calc(currentEstimate + x * currentEstimate) /
2.0;
// Bad
currentEstimate = calc(currentEstimate + x *
currentEstimate) / 2.0;Continuation lines: indent at least +4 spaces from original line.
在更高语法层级处换行:
javascript
// Good
currentEstimate =
calc(currentEstimate + x * currentEstimate) /
2.0;
// Bad
currentEstimate = calc(currentEstimate + x *
currentEstimate) / 2.0;续行:缩进至少比原行多4个空格。
Whitespace
空白字符
Horizontal spacing:
- Space after reserved words: ,
if (,for (catch ( - No space for and
function:super,function(super( - Space before opening brace: ,
if (x) {class Foo { - Space around binary/ternary operators: ,
a + bx ? y : z - Space after comma/semicolon:
foo(a, b); - Space after colon in objects:
{a: 1, b: 2} - Space around :
//// comment
Vertical spacing:
- Blank line between methods
- Blank lines within methods to create logical groups (sparingly)
水平空格:
- 保留字后加空格:,
if (,for (catch ( - 和
function后不加空格:super,function(super( - 左大括号前加空格:,
if (x) {class Foo { - 二元/三元运算符前后加空格:,
a + bx ? y : z - 逗号/分号后加空格:
foo(a, b); - 对象中冒号后加空格:
{a: 1, b: 2} - 后加空格:
//// comment
垂直空格:
- 方法之间空一行
- 方法内可适当空行以划分逻辑组(避免过多)
Semicolons
分号
Required - Every statement must end with semicolon:
javascript
const x = 1; // Required
doSomething(); // Required必须添加 - 每条语句必须以分号结尾:
javascript
const x = 1; // Required
doSomething(); // RequiredArrays and Objects
数组与对象
Array Literals
数组字面量
javascript
// Use trailing commas
const values = [
'first value',
'second value',
];
// Never use Array constructor
const a = [x1, x2, x3]; // Good
const b = new Array(x1, x2, x3); // Bad
// Destructuring
const [a, b, c, ...rest] = generateResults();
let [, b,, d] = someArray; // Skip unused elements
// Spread operator
[...foo] // Preferred over Array.prototype.slice.call(foo)
[...foo, ...bar] // Preferred over foo.concat(bar)javascript
// Use trailing commas
const values = [
'first value',
'second value',
];
// Never use Array constructor
const a = [x1, x2, x3]; // Good
const b = new Array(x1, x2, x3); // Bad
// Destructuring
const [a, b, c, ...rest] = generateResults();
let [, b,, d] = someArray; // Skip unused elements
// Spread operator
[...foo] // Preferred over Array.prototype.slice.call(foo)
[...foo, ...bar] // Preferred over foo.concat(bar)Object Literals
对象字面量
javascript
// Use trailing commas
const obj = {
a: 0,
b: 1,
};
// Never use Object constructor
const o = {a: 0, b: 1}; // Good
const o = new Object(); // Bad
// Don't mix quoted and unquoted keys
{
width: 42,
height: 50,
} // Good - all unquoted (struct style)
{
'width': 42,
'maxWidth': 43,
} // Good - all quoted (dict style)
{
width: 42,
'maxWidth': 43,
} // Bad - mixed
// Method shorthand
const obj = {
value: 1,
method() {
return this.value;
},
};
// Shorthand properties
const foo = 1;
const bar = 2;
const obj = {foo, bar};
// Destructuring
function process({num, str = 'default'} = {}) {}javascript
// Use trailing commas
const obj = {
a: 0,
b: 1,
};
// Never use Object constructor
const o = {a: 0, b: 1}; // Good
const o = new Object(); // Bad
// Don't mix quoted and unquoted keys
{
width: 42,
height: 50,
} // Good - all unquoted (struct style)
{
'width': 42,
'maxWidth': 43,
} // Good - all quoted (dict style)
{
width: 42,
'maxWidth': 43,
} // Bad - mixed
// Method shorthand
const obj = {
value: 1,
method() {
return this.value;
},
};
// Shorthand properties
const foo = 1;
const bar = 2;
const obj = {foo, bar};
// Destructuring
function process({num, str = 'default'} = {}) {}Classes
类
Class Declaration
类声明
javascript
class MyClass {
// Constructor
constructor(value) {
/** @private @const */
this.value_ = value;
/** @private */
this.mutableField = 0;
}
// Methods
getValue() {
return this.value_;
}
/** @override */
toString() {
return `MyClass(${this.value_})`;
}
}
// Inheritance
class ChildClass extends MyClass {
constructor(value, extra) {
super(value); // Must call super() first
this.extra = extra;
}
}Rules:
- Constructors are optional
- Define all fields in constructor
- Use for never-reassigned fields
@const - Use ,
@privatefor non-public fields@protected - Private field names may end with underscore
- No semicolons after methods
- Call before accessing
super()in subclassesthis
javascript
class MyClass {
// Constructor
constructor(value) {
/** @private @const */
this.value_ = value;
/** @private */
this.mutableField = 0;
}
// Methods
getValue() {
return this.value_;
}
/** @override */
toString() {
return `MyClass(${this.value_})`;
}
}
// Inheritance
class ChildClass extends MyClass {
constructor(value, extra) {
super(value); // Must call super() first
this.extra = extra;
}
}规则:
- 构造函数为可选
- 所有字段在构造函数中定义
- 永不重新赋值的字段使用
@const - 非公开字段使用、
@private@protected - 私有字段名称可以下划线结尾
- 方法后不加分号
- 子类中访问前必须调用
thissuper()
Functions
函数
Arrow Functions
箭头函数
Preferred for callbacks and short functions:
javascript
// Good
const squares = numbers.map(n => n * n);
items.forEach((item) => {
process(item);
});
// Use when 'this' from outer scope needed
class Timer {
start() {
setInterval(() => {
this.tick(); // 'this' refers to Timer instance
}, 1000);
}
}Rules:
- Prefer arrow functions for callbacks
- Use arrow functions to preserve binding
this - Omit parens for single parameter:
x => x * 2 - Use parens for zero or multiple params: ,
() => 42(a, b) => a + b - Always use braces for multi-line bodies
优先用于回调和短函数:
javascript
// Good
const squares = numbers.map(n => n * n);
items.forEach((item) => {
process(item);
});
// Use when 'this' from outer scope needed
class Timer {
start() {
setInterval(() => {
this.tick(); // 'this' refers to Timer instance
}, 1000);
}
}规则:
- 回调优先使用箭头函数
- 使用箭头函数保留外部作用域的绑定
this - 单个参数可省略括号:
x => x * 2 - 零个或多个参数使用括号:,
() => 42(a, b) => a + b - 多行函数体始终使用大括号
Function Declarations
函数声明
javascript
function myFunction(param1, param2) {
return param1 + param2;
}
// Optional parameters with defaults
function greet(name = 'Guest') {
return `Hello, ${name}`;
}
// Rest parameters
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}javascript
function myFunction(param1, param2) {
return param1 + param2;
}
// Optional parameters with defaults
function greet(name = 'Guest') {
return `Hello, ${name}`;
}
// Rest parameters
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}Control Structures
控制结构
Conditionals
条件语句
javascript
// Standard if-else
if (condition) {
doSomething();
} else if (otherCondition) {
doOther();
} else {
doDefault();
}
// Ternary for simple cases
const value = condition ? trueValue : falseValue;javascript
// Standard if-else
if (condition) {
doSomething();
} else if (otherCondition) {
doOther();
} else {
doDefault();
}
// Ternary for simple cases
const value = condition ? trueValue : falseValue;Loops
循环
javascript
// For-of for iterables
for (const item of items) {
process(item);
}
// Traditional for loop
for (let i = 0; i < array.length; i++) {
process(array[i]);
}
// For-in for object properties (use with caution)
for (const key in object) {
if (object.hasOwnProperty(key)) {
process(object[key]);
}
}javascript
// For-of for iterables
for (const item of items) {
process(item);
}
// Traditional for loop
for (let i = 0; i < array.length; i++) {
process(array[i]);
}
// For-in for object properties (use with caution)
for (const key in object) {
if (object.hasOwnProperty(key)) {
process(object[key]);
}
}Switch Statements
Switch语句
javascript
switch (value) {
case 'option1':
handleOption1();
break;
case 'option2':
handleOption2();
break;
default:
handleDefault();
}javascript
switch (value) {
case 'option1':
handleOption1();
break;
case 'option2':
handleOption2();
break;
default:
handleDefault();
}Modern Features
现代特性
Template Literals
模板字面量
javascript
// Use for string interpolation
const message = `Hello, ${name}!`;
// Multi-line strings
const html = `
<div>
<h1>${title}</h1>
</div>
`;javascript
// Use for string interpolation
const message = `Hello, ${name}!`;
// Multi-line strings
const html = `
<div>
<h1>${title}</h1>
</div>
`;Promises and Async/Await
Promise与Async/Await
javascript
// Prefer async/await
async function fetchData() {
try {
const response = await fetch(url);
const data = await response.json();
return data;
} catch (error) {
console.error('Failed:', error);
throw error;
}
}
// Promise chains when appropriate
fetch(url)
.then(response => response.json())
.then(data => process(data))
.catch(error => console.error(error));javascript
// Prefer async/await
async function fetchData() {
try {
const response = await fetch(url);
const data = await response.json();
return data;
} catch (error) {
console.error('Failed:', error);
throw error;
}
}
// Promise chains when appropriate
fetch(url)
.then(response => response.json())
.then(data => process(data))
.catch(error => console.error(error));Comments
注释
Implementation Comments
实现注释
javascript
// Single-line comments use //
// Multiple single-line comments for
// longer explanations.
/*
* Multi-line comment style.
* Subsequent lines start with * aligned
* with the * on the previous line.
*/
// Parameter name comments for clarity
someFunction(obviousParam, /* shouldRender= */ true, /* name= */ 'hello');javascript
// Single-line comments use //
// Multiple single-line comments for
// longer explanations.
/*
* Multi-line comment style.
* Subsequent lines start with * aligned
* with the * on the previous line.
*/
// Parameter name comments for clarity
someFunction(obviousParam, /* shouldRender= */ true, /* name= */ 'hello');JSDoc
JSDoc
Use JSDoc for:
- All classes
- All methods and functions (public and private)
- Properties when needed for clarity
javascript
/**
* Brief description of the function.
*
* @param {string} name The user's name
* @param {number=} age Optional age parameter
* @return {string} Greeting message
*/
function greet(name, age) {
return `Hello, ${name}`;
}
/**
* Class representing a point.
*/
class Point {
/**
* Create a point.
* @param {number} x The x coordinate
* @param {number} y The y coordinate
*/
constructor(x, y) {
/** @private @const {number} */
this.x_ = x;
/** @private @const {number} */
this.y_ = y;
}
}JSDoc适用于:
- 所有类
- 所有方法和函数(公开和私有)
- 需要明确说明的属性
javascript
/**
* Brief description of the function.
*
* @param {string} name The user's name
* @param {number=} age Optional age parameter
* @return {string} Greeting message
*/
function greet(name, age) {
return `Hello, ${name}`;
}
/**
* Class representing a point.
*/
class Point {
/**
* Create a point.
* @param {number} x The x coordinate
* @param {number} y The y coordinate
*/
constructor(x, y) {
/** @private @const {number} */
this.x_ = x;
/** @private @const {number} */
this.y_ = y;
}
}Node.js Specific
Node.js 特定规范
Module Exports
模块导出
javascript
// ES modules in Node.js (use .mjs or "type": "module" in package.json)
export class Service {}
export function helper() {}
// CommonJS (when ES modules not available)
class Service {}
function helper() {}
module.exports = {Service, helper};javascript
// ES modules in Node.js (use .mjs or "type": "module" in package.json)
export class Service {}
export function helper() {}
// CommonJS (when ES modules not available)
class Service {}
function helper() {}
module.exports = {Service, helper};Error Handling
错误处理
javascript
// Always handle errors in async code
async function processFile(path) {
try {
const content = await fs.promises.readFile(path, 'utf8');
return JSON.parse(content);
} catch (error) {
console.error(`Failed to process ${path}:`, error);
throw error;
}
}
// Use Error objects
throw new Error('Something went wrong');
throw new TypeError('Expected string');javascript
// Always handle errors in async code
async function processFile(path) {
try {
const content = await fs.promises.readFile(path, 'utf8');
return JSON.parse(content);
} catch (error) {
console.error(`Failed to process ${path}:`, error);
throw error;
}
}
// Use Error objects
throw new Error('Something went wrong');
throw new TypeError('Expected string');Common Patterns
常见模式
Object Property Access
对象属性访问
javascript
// Check existence
if (obj.property != null) {
// Property exists and is not null/undefined
}
// Use optional chaining
const value = obj?.deeply?.nested?.property;
// Nullish coalescing
const result = value ?? defaultValue;javascript
// Check existence
if (obj.property != null) {
// Property exists and is not null/undefined
}
// Use optional chaining
const value = obj?.deeply?.nested?.property;
// Nullish coalescing
const result = value ?? defaultValue;Array Operations
数组操作
javascript
// Prefer array methods over loops
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
// Check if array contains item
if (array.includes(item)) { }
// Find item
const found = array.find(item => item.id === targetId);javascript
// Prefer array methods over loops
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
// Check if array contains item
if (array.includes(item)) { }
// Find item
const found = array.find(item => item.id === targetId);Quick Reference
快速参考
Variable declaration: (default), (when reassignment needed), never
Indentation: 2 spaces
Semicolons: Required
String quotes: Single or backticks for templates
Braces: K&R style, always use for control structures
Line length: 80 characters
Naming: for variables/functions, for classes
Imports: Use extension, no default exports
Comments: for single-line, for multi-line
constletvarIndentation: 2 spaces
Semicolons: Required
String quotes: Single
'`Braces: K&R style, always use for control structures
Line length: 80 characters
Naming:
lowerCamelCaseUpperCamelCaseImports: Use
.jsComments:
///* */变量声明:(默认),(需要重新赋值时),绝不使用
缩进:2个空格
分号:必须添加
字符串引号:单引号或模板字符串反引号
大括号:K&R风格,控制结构始终使用
行长度:80字符
命名:变量/函数使用,类使用
导入:使用扩展名,禁止默认导出
注释:单行使用,多行使用
constletvar缩进:2个空格
分号:必须添加
字符串引号:单引号
'`大括号:K&R风格,控制结构始终使用
行长度:80字符
命名:变量/函数使用
lowerCamelCaseUpperCamelCase导入:使用
.js注释:单行使用
///* */Additional Resources
额外资源
Reference Files
参考文档
For comprehensive coverage of specific topics:
- - Advanced JavaScript patterns, promises, generators, proxies
references/advanced-features.md - - Complete JSDoc annotation guide
references/jsdoc-guide.md - - Detailed naming rules for all identifier types
references/naming-conventions.md - - Features to avoid and their alternatives
references/disallowed-features.md
如需特定主题的全面内容:
- - JavaScript高级模式、Promise、生成器、代理
references/advanced-features.md - - 完整JSDoc注释指南
references/jsdoc-guide.md - - 所有标识符类型的详细命名规则
references/naming-conventions.md - - 需避免的特性及替代方案
references/disallowed-features.md
Complete Style Guide
完整风格指南
The full Google JavaScript Style Guide is available at:
https://google.github.io/styleguide/jsguide.html
完整的Google JavaScript风格指南可访问:
https://google.github.io/styleguide/jsguide.html