字节笔记本

2026年2月22日

Google JavaScript 风格指南(中文版)

Google JavaScript 风格指南是 Google 开源项目使用的 JavaScript 编码规范,涵盖了语言规范和代码风格两大部分。本文档翻译自 Google 官方风格指南,旨在帮助开发者编写一致、可维护且高质量的 JavaScript 代码。

JavaScript 语言规范

var 关键字

总是使用 var 关键字定义变量。

如果不显式使用 var 关键字定义变量,变量会进入到全局上下文中,可能会和已有的变量发生冲突。另外,如果不使用 var 声明,很难说变量存在的作用域是哪个(可能在局部作用域里,也可能在 document 或者 window 上)。所以,要一直使用 var 关键字定义变量。

常量

  • 使用字母全部大写(如 NAMES_LIKE_THIS)的方式命名
  • 可以使用 @const 来标记一个常量指针(指向变量或属性,自身不可变)
  • 由于 IE 的兼容问题,不要使用 const 关键字

常量值

如果一个值是恒定的,它命名中的字母要全部大写(如 CONSTANT_VALUE_CASE)。字母全部大写意味着这个值不可以被改写。

原始类型(numberstringboolean)是常量值。

常量指针(变量和属性)

@const 注释的变量和属性意味着它是不能更改的。使用 const 关键字可以保证在编译的时候保持一致。由于 IE 的兼容问题,我们不使用 const 关键字。

javascript
/**
 * 以毫秒为单位的超时时长
 * @type {number}
 */
goog.example.TIMEOUT_IN_MILLISECONDS = 60;

/**
 * Map of URL to response string.
 * @const
 */
MyClass.fetchedUrlCache_ = new goog.structs.Map();

分号

一定要使用分号。

依靠语句间隐式的分割,可能会造成细微的调试的问题,千万不要这样做。

javascript
// 错误示例 - 不要这样做
var foo = function() {
  return 42;
}  // 这里没有分号
(function() {
  // 一些局部作用域中的初始化代码
})();

函数表达式后面要分号结束,但是函数声明就不需要:

javascript
var foo = function() { return true; }; // 这里要分号
function foo() { return true; } // 这里不用分号

嵌套函数

可以使用。嵌套函数非常有用,比如在创建持续任务或者隐藏工具方法的时候。

块内函数声明

不要使用块内函数声明。

不要这样做:

javascript
if (x) { function foo() {} }

相反,使用一个变量初始化函数表达式在块内定义一个函数:

javascript
if (x) { var foo = function() {} }

异常

可以抛出异常。如果你做一些比较复杂的项目你基本上无法避免异常,比如使用一个应用程序开发框架。

自定义异常

可以自定义异常。如果没有自定义异常,返回的错误信息来自一个有返回值的函数是难处理的,是不雅的。

标准功能

总是优先于非标准功能。为了最大的可移植性和兼容性,总是使用标准功能而不是非标准功能(例如,采用 string.charAt(3) 而非 string[3])。

原始类型的包装对象

没有理由使用原始类型的包装对象,更何况他们是危险的:

javascript
var x = new Boolean(false);
if (x) {
  alert('hi'); // 显示"hi"。
}

然而类型转换是可以的:

javascript
var x = Boolean(0);
if (x) {
  alert('hi'); // 永远都不显示。
}

多重的原型继承

不可取。多重原型继承是 Javascript 实现继承的方式。出于这个原因,最好是使用 Closure 库中的 goog.inherits() 或类似的东西。

javascript
function D() { goog.base(this) }
goog.inherits(D, B);
D.prototype.method = function() { ... };

方法和属性定义

首选的创建方法的途径是:

javascript
Foo.prototype.bar = function() { /* ... */ };

其他特性的首选创建方式是在构造函数中初始化字段:

javascript
/** @constructor */
function Foo() {
  this.bar = value;
}

删除

请使用 this.foo = null 而不是 delete

在现代的 JavaScript 引擎中,改变一个对象属性的数量比重新分配值慢得多。应该避免删除关键字。

闭包

可以使用,但是要小心。

要记住的一件事情,一个闭包的指针指向包含它的范围。因此,附加一个闭包的 DOM 元素,可以创建一个循环引用,所以,内存会泄漏。

javascript
// 可能导致内存泄漏
function foo(element, a, b) {
  element.onclick = function() { /* 使用 a 和 b */ };
}

// 更好的写法
function foo(element, a, b) {
  element.onclick = bar(a, b);
}
function bar(a, b) {
  return function() { /* 使用 a 和 b */ }
}

eval() 函数

只用于反序列化(如评估 RPC 响应)。若用于 eval() 的字符串含有用户输入,则会造成混乱的语义,使用它有风险。

with() {}

不建议使用。使用 with 会影响程序的语义,使你程序的语义发生很大的变化。

this

只在构造函数对象、方法,和创建闭包的时候使用。

正因为 this 很容易被弄错,故将其使用限制在以下必须的地方:

  • 在构造函数中
  • 在对象的方法中(包括闭包的创建)

for-in 循环

只使用在对象、映射、哈希的键值迭代中。

for-in 循环经常被不正确的用在元素数组的循环中。在数组循环时常用的一般方式:

javascript
function printArray(arr) {
  var l = arr.length;
  for (var i = 0; i < l; i++) {
    print(arr[i]);
  }
}

关联数组

不要将映射,哈希,关联数组当作一般数组来使用。如果你需要一个映射或者哈希,在这种情况下你应该使用对象来代替数组。

多行的字符串字面量

不要使用。使用字符串连接来代替:

javascript
var myString = 'A rather long string of English text, an error message ' +
    'actually that just keeps going and going -- an error ' +
    'message to make the Energizer bunny blush.';

数组和对象字面量

建议使用。使用数组和对象字面量来代替数组和对象构造函数。

javascript
// 推荐
var a = [x1, x2, x3];
var o = { a: 0, b: 1, c: 2 };

// 不推荐
var a = new Array(x1, x2, x3);
var o = new Object();

修改内置对象原型

不建议。强烈禁止修改如 Object.prototypeArray.prototype 等对象的原型。


JavaScript 风格规范

命名

通常来说,使用以下格式的命名方式:

  • functionNamesLikeThis - 函数名
  • variableNamesLikeThis - 变量名
  • ClassNamesLikeThis - 类名
  • EnumNamesLikeThis - 枚举名
  • methodNamesLikeThis - 方法名
  • CONSTANT_VALUES_LIKE_THIS - 常量值
  • foo.namespaceNamesLikeThis.bar - 命名空间
  • filenameslikethis.js - 文件名

属性和方法

  • 私有属性和方法应该以下划线开头命名
  • 保护属性和方法应该以无下划线开头命名(像公共属性和方法一样)

方法和函数参数

  • 可选函数参数以 opt_ 开头
  • 参数数目可变的函数应该具有以 var_args 命名的最后一个参数

getter 和 setter

EcmaScript 5 不鼓励使用属性的 getter 和 setter。然而,如果使用它们,那么 getter 就不要改变属性的可见状态。

读取方法必须以 getFoo() 命名,并且写入方法必须以 setFoo(value) 命名。(对于布尔型的读取方法,也可以使用 isFoo()

命名空间

在全局范围内总是使用唯一的项目或库相关的伪命名空间进行前缀标识。

javascript
var sloth = {};
sloth.sleep = function() { ... };

文件名

为了避免在大小写敏感的平台上引起混淆,文件名应该小写。文件名应该以 .js 结尾,并且应该不包含除了 -_(相比较 _ 更推荐 -)以外的其它标点。

代码格式

大括号

由于隐含分号的插入,无论大括号括起来的是什么,总是在同一行上开始你的大括号。

javascript
if (something) {
  // ...
} else {
  // …
}

数组和对象初始化表达式

当单行数组和对象初始化表达式可以在一行写开时,写成单行是允许的。

javascript
var arr = [1, 2, 3];
var obj = {a: 1, b: 2, c: 3};

多行数组和对象初始化表达式缩进两个空格:

javascript
var inset = {
  top: 10,
  right: 20,
  bottom: 15,
  left: 12
};

函数参数

如果可能,应该在同一行上列出所有函数参数。如果这样做将超出每行 80 个字符的限制,参数必须以一种可读性较好的方式进行换行。

javascript
// 四个空格,每行一个参数
goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
    veryDescriptiveArgumentNumberOne,
    veryDescriptiveArgumentTwo,
    tableModelEventHandlerProxy,
    artichokeDescriptorAdapterIterator) {
  // ...
};

更多的缩进

事实上,除了初始化数组和对象和传递匿名函数外,所有被拆开的多行文本应与之前的表达式左对齐,或者以 4 个(而不是 2 个)空格作为一缩进层次。

空行

使用新的空行来划分一组逻辑上相关联的代码片段。

二元和三元操作符

操作符始终跟随着前行,这样你就不用顾虑分号的隐式插入问题。

javascript
var x = a ? b : c;
var y = a ?
    longButSimpleOperandB :
    longButSimpleOperandC;

括号

只用在有需要的地方。通常只在语法或者语义需要的地方有节制地使用。

绝对不要对一元运算符如 deletetypeofvoid 使用括号或者在关键词如 returnthrow 和其他的之后使用括号。

字符串

使用 ' 代替 "。使用单引号代替双引号来保证一致性。当我们创建包含有 HTML 的字符串时这样做很有帮助。

javascript
var msg = 'This is some HTML';

可见性(私有和保护类型字段)

鼓励使用 @private@protected JSDoc 注释。

  • 加了 @private 标记的全局变量和函数只能被同一文件中的代码所访问
  • 标记 @private 的属性可以被同一文件中的所有的代码访问
  • 标记 @protected 的属性可以被同一文件中的所有的代码访问,任何含有属性的子类的静态方法和实例方法也可访问

注释

注释语法

使用 JSDoc 格式进行注释。

顶层/文件层注释

javascript
/**
 * @fileoverview 描述文件内容。
 */

方法和功能注释

javascript
/**
 * 方法的描述
 * @param {string} arg1 参数1的说明
 * @param {number} arg2 参数2的说明
 * @return {boolean} 返回值的说明
 */

技巧和诀窍

True 和 False 布尔表达式

下面的布尔表达式都返回 false

  • null
  • undefined
  • '' 空字符串
  • 0 数字零

但下面这些情况要格外小心:

javascript
// 以下都返回 true
if (0) { }
if ('0') { }

条件(三元)操作符(?:)

javascript
var x = a ? b : c;

&& 和 ||

javascript
// 设置默认值
var foo = a || b;

// 条件执行
a && foo();

总结

Google JavaScript 风格指南提供了一套完整的编码规范,涵盖了从变量声明到代码格式的方方面面。遵循这些规范可以帮助团队:

  1. 提高代码可读性 - 一致的命名和格式让代码更容易理解
  2. 减少错误 - 避免常见的 JavaScript 陷阱(如隐式分号、全局变量污染等)
  3. 便于维护 - 清晰的结构和注释使代码更易于维护
  4. 增强协作 - 统一的风格让团队成员可以更高效地协作

建议将此指南作为团队编码规范的参考,并根据实际项目需求进行适当调整。


参考链接

分享: