javascript

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

JavaScript/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.js
    ,
    user-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.,
    \u221e
    ) based on readability
Indentation:
  • Use 2 spaces (never tabs)
  • No trailing whitespace
文件命名
  • 仅使用小写字母
  • 使用下划线(
    _
    )或短横线(
    -
    ),禁止使用其他标点符号
  • 扩展名必须为
    .js
  • 示例:
    my_module.js
    ,
    user-service.js
文件编码
  • 仅使用UTF-8编码
  • 特殊字符使用转义序列(
    \'
    ,
    \"
    ,
    \\
    ,
    \b
    ,
    \f
    ,
    \n
    ,
    \r
    ,
    \t
    ,
    \v
  • 非ASCII字符:根据可读性选择使用实际Unicode字符(如
    )或十六进制转义(如
    \u221e
缩进
  • 使用2个空格(绝不使用制表符)
  • 禁止行尾空白

Module System

模块系统

ES Modules (Preferred)

ES Modules(推荐)

Use
import
and
export
statements:
javascript
// 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
    .js
    extension in paths (required)
  • Use
    lowerCamelCase
    for module import names:
    import * 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.
使用
import
export
语句:
javascript
// 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
    扩展名
  • 模块导入名称使用
    lowerCamelCase
    格式:
    import * as fileOne from '../file-one.js';
  • 命名导入保持原名称,除非必要否则避免别名
  • 禁止使用默认导出
  • import
    语句不受80字符限制(无需换行)
避免循环依赖 - 不要在模块之间创建导入循环。

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 var
One 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
    ,
    while
    , comma, semicolon)
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:
  • import
    and
    export from
    statements
  • 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
    function
    and
    super
    :
    function(
    ,
    super(
  • Space before opening brace:
    if (x) {
    ,
    class Foo {
  • Space around binary/ternary operators:
    a + b
    ,
    x ? 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 + b
    ,
    x ? 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();  // Required

Arrays 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
    @const
    for never-reassigned fields
  • Use
    @private
    ,
    @protected
    for non-public fields
  • Private field names may end with underscore
  • No semicolons after methods
  • Call
    super()
    before accessing
    this
    in subclasses
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
  • 私有字段名称可以下划线结尾
  • 方法后不加分号
  • 子类中访问
    this
    前必须调用
    super()

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
    this
    binding
  • 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:
const
(default),
let
(when reassignment needed), never
var

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:
lowerCamelCase
for variables/functions,
UpperCamelCase
for classes
Imports: Use
.js
extension, no default exports
Comments:
//
for single-line,
/* */
for multi-line
变量声明
const
(默认),
let
(需要重新赋值时),绝不使用
var

缩进:2个空格
分号:必须添加
字符串引号:单引号
'
或模板字符串反引号
`

大括号:K&R风格,控制结构始终使用
行长度:80字符
命名:变量/函数使用
lowerCamelCase
,类使用
UpperCamelCase

导入:使用
.js
扩展名,禁止默认导出
注释:单行使用
//
,多行使用
/* */

Additional Resources

额外资源

Reference Files

参考文档

For comprehensive coverage of specific topics:
  • references/advanced-features.md
    - Advanced JavaScript patterns, promises, generators, proxies
  • references/jsdoc-guide.md
    - Complete JSDoc annotation guide
  • references/naming-conventions.md
    - Detailed naming rules for all identifier types
  • references/disallowed-features.md
    - Features to avoid and their alternatives
如需特定主题的全面内容:
  • references/advanced-features.md
    - JavaScript高级模式、Promise、生成器、代理
  • references/jsdoc-guide.md
    - 完整JSDoc注释指南
  • 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