[Javascript] 编程实践之1: Google的Javascript代码风格9:附件

9 附件

9.1 JSDoc标签参考

JSDoc在JavaScript中有多种用途。 除了用于生成文档外,它还用于控制工具。 最著名的是Closure Compiler类型注释。

9.1.1 类型注释和其他Closure Compiler注释

Annotating JavaScript for the Closure Compiler Types in the Closure Type System中描述了Closure Compiler使用的JSDoc文档。

9.1.2 文档注释

除了用于Annotating JavaScript for the Closure Compiler 描述的JSDoc外,以下标记是通用的,并且由各种文档生成工具(例如JsDossier)很好地支持,以纯粹用于文档目的。

您可能还会在第三方代码中看到其他类型的JSDoc注释。 这些注释出现在JSDoc Toolkit Tag Reference中,但不被视为有效Google样式的一部分。

9.1.2.1 @author 或者 @owner - 不推荐

不推荐

文法:@author username@google.com (First Last)

/**
 * @fileoverview Utilities for handling textareas.
 * @author kuth@google.com (Uthur Pendragon)
 */

记录文件的作者或测试的所有者,通常只在@fileoverview注释中使用。 单元测试仪表板使用@owner标记来确定谁拥有测试结果。

9.1.2.2 @bug

文法:@bug bugnumber

/** @bug 1234567 */
function testSomething() {
  // …
}

/**
 * @bug 1234568
 * @bug 1234569
 */
function testTwoBugs() {
  // …
}

指示给定测试功能回归测试会导致哪些错误。

多个错误应每个都有自己的@bug行,以使搜索回归测试尽可能容易。

9.1.2.3 @code -弃用, 不推荐使用

不推荐使用。 请改用Markdown反引号

文法:{@code …}

由于历史原因,BatchItem被写为{@code BatchItem}。

/** Processes pending `BatchItem` instances. */
function processBatchItems() {}

表示JSDoc描述中的术语是代码,因此可以在生成的文档中正确设置其格式。

9.1.2.4 @desc

文法:@desc Message description

/** @desc Notifying a user that their account has been created. */
exports.MSG_ACCOUNT_CREATED = goog.getMsg(
    'Your account has been successfully created.');
9.1.2.5 @link

文法:{@link …}

此标记用于在生成的文档内生成交叉引用链接。

/** Processes pending {@link BatchItem} instances. */
function processBatchItems() {}

历史记录:@link标记也已用于在生成的文档中创建外部链接。 对于外部链接,请始终使用Markdown的链接语法:

/**
 * This class implements a useful subset of the
 * [native Event interface](https://dom.spec.whatwg.org/#event).
 */
class ApplicationEvent {}
9.1.2.6 @see

文法:@see Link

/**
 * Adds a single item, recklessly.
 * @see #addSafely
 * @see goog.Collect
 * @see goog.RecklessAdder#add
 */

将查询引用到另一个类函数或方法。

9.1.2.7 @supported

文法:@supported Description

/**
 * @fileoverview Event Manager
 * Provides an abstracted interface to the browsers' event systems.
 * @supported IE10+, Chrome, Safari
 */

在文件概述中用于指示文件支持哪些浏览器。

9.1.3 适用于特定框架的注释

以下注释适用于特定框架。

9.1.3.1 @ngInject 特定于Angular 1
9.1.3.2 @polymerBehavior特定于Polymer

https://github.com/google/closure-compiler/wiki/Polymer-Pass

9.1.4 有关标准Closure Compiler批注的注释

以下标记曾经是标准标记,但现已弃用。

9.1.4.1 @expose - 已弃用,不要使用。

已弃用。使用@export和/或@nocollapse作为替代。

9.1.4.2 @inheritDoc - 已弃用,不要使用。

已弃用,使用@override作为替代。

9.2 经常被误解的样式规则

这是关于JavaScript的Google样式的一些鲜为人知或经常被误解的事实的集合。 (以下是正确的陈述;这不是神话列表。)

  • 源文件中不需要版权声明或@author信用。 (也没有明确建议。)
  • 对于如何对一个类的成员(5.4 类)进行排序,没有硬性规定。
  • 空块通常可以用{}简洁地表示,如(4.1.3 空块:可能更精炼)中所述。
  • 换行的主要指令是:更喜欢在较高的语法级别(4.5.1 在哪里中断)处断开。
  • 字符串文字,注释和JSDoc中允许使用非ASCII字符,实际上,当它们使代码比等效的Unicode转义(2.3.3 非ASCII字符)更易于阅读时,建议使用非ASCII字符。

9.3 与样式相关的工具

存在以下工具来支持Google样式的各个方面。

9.3.1 Closure Compiler

该程序执行类型检查以及其他检查,优化和其他转换(例如ECMAScript 6到ECMAScript 5及以下版本的代码转换)。

9.3.2 clang-format

该程序将JavaScript源代码重新格式化为Google样式,并遵循了许多非必需但经常提高可读性的格式设置惯例。 由clang-format产生的输出符合样式指南。

不需要clang格式。 允许作者更改其输出,并允许审稿人要求此类更改; 争端以通常的方式解决。 但是,子树可以选择在本地选择加入此类实施。

9.3.3 Closure compiler linter

该程序检查各种失误和反模式。

9.3.4 一致性框架

JS Conformance Framework是Closure Compiler的一部分,该工具为开发人员提供了一种简单的方法,可以指定一组额外的检查,以使其在标准检查之上针对其代码库运行。 例如,一致性检查可能会禁止访问某些属性,禁止调用某个函数或缺少类型信息(未知)。

这些规则通常用于强制执行严格的限制(例如,定义全局变量,这可能会破坏代码库)和安全性模式(例如,使用eval或分配给innerHTML),或者更宽松地用于提高代码质量。

有关更多信息,请参见官方文档JS Conformance Framework

9.4 旧版平台的例外

9.4.1 总览

本节介绍当代码作者无法使用现代ECMAScript 6语法时的例外情况和其他规则。 如果无法使用ECMAScript 6语法,则要求使用推荐样式的例外,并在此处概述:

  • 允许使用var声明。
  • 允许使用arguments。
  • 允许没有默认值的可选参数。
9.4.2 使用var
9.4.2.1 var声明不是块作用域的

var声明的作用域是最接近的封闭函数,脚本或模块的开头,这可能会导致意外行为,尤其是对于在循环内部引用var声明的函数闭包而言。 以下代码给出了一个示例:

for (var i = 0; i < 3; ++i) {
  var iteration = i;
  setTimeout(function() { console.log(iteration); }, i*1000);
}

// logs 2, 2, 2 -- NOT 0, 1, 2
// because `iteration` is function-scoped, not local to the loop.
9.4.2.2 声明尽可能接近首次使用的变量

即使var声明的范围仅限于封闭函数的开头,但出于可读性的目的,var声明应尽可能接近其首次使用。 但是,如果在块外引用了该变量,则不要在块内放置var声明。 例如:

function sillyFunction() {
  var count = 0;
  for (var x in y) {
    // "count" could be declared here, but don't do that.
    count++;
  }
  console.log(count + ' items in y');
}
9.4.2.3 将@const用于常量变量

对于将使用const关键字的全局声明(如果可用),请使用@const注释var声明(这对于局部变量是可选的)。

9.4.3 不要使用块作用域函数声明

不要这样做:

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

尽管在ECMAScript 6之前实现的大多数JavaScript VM都在块内支持函数声明,但它尚未标准化。 实现彼此之间以及与现在标准的ECMAScript 6行为(用于块范围函数声明)不一致。 ECMAScript 5和更高版本仅允许在脚本或函数的根语句列表中进行函数声明,并在严格模式下将其明确禁止在块作用域中使用。

为了获得一致的行为,请使用通过函数表达式初始化的var在块内定义函数:

if (x) {
  var foo = function() {};
}
9.4.4 使用goog.provide / goog.require进行依赖管理
9.4.4.1 总结

警告:不建议使用goog.provide依赖项管理。 所有新文件,即使在使用goog.provide的旧文件项目中,也应使用goog.module。 以下规则仅适用于预先存在的goog.provide文件。

  • 将所有goog.provides放在第一位,goog.requires放在第二位。 空行将提供与需求分开。
  • 按字母顺序对条目进行排序(大写优先)。
  • 不要包装goog.provide和goog.require语句。 必要时超过80列。
  • 仅提供顶级符号。

goog.provide语句应组合在一起并放在最前面。 所有goog.require语句都应遵循。 这两个列表应以空行分隔。

与其他语言的import语句相似,即使goog.provide和goog.require语句超过了80列的行长限制,也应将它们写在一行中。

这些行应按字母顺序排序,大写字母排在最前面:

goog.provide('namespace.MyClass');
goog.provide('namespace.helperFoo');

goog.require('an.extremelyLongNamespace.thatSomeoneThought.wouldBeNice.andNowItIsLonger.Than80Columns');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.dom.classes');
goog.require('goog.dominoes');

在类上定义的所有成员都应在同一文件中。 包含多个在同一类上定义的成员的文件中应仅提供顶级类(例如,枚举,内部类等)。

这样做:

goog.provide('namespace.MyClass');

不要这样做:

goog.provide('namespace.MyClass');
goog.provide('namespace.MyClass.CONSTANT');
goog.provide('namespace.MyClass.Enum');
goog.provide('namespace.MyClass.InnerClass');
goog.provide('namespace.MyClass.TypeDef');
goog.provide('namespace.MyClass.staticMethod');

还可以提供名称空间上的成员:

goog.provide('foo.bar');
goog.provide('foo.bar.CONSTANT');
goog.provide('foo.bar.method');
9.4.4.2 使用Goog.scope起别名

警告不建议使用goog.scope。 即使在使用现有goog.scope的项目中,新文件也不应使用goog.scope。

goog.scope可以用于使用goog.provide / goog.require依赖项管理来缩短对代码中命名空间符号的引用。

每个文件只能添加一个goog.scope调用。 始终将其放在全局范围内。

开头的goog.scope(function(){调用前必须紧跟一个空白行,并跟随所有goog.provide语句,goog.require语句或顶级注释。该调用必须在文件的最后一行关闭 。//将goog.scope追加到合并范围的结束声明中,将分号和注释之间的空格分开两个空格。

与C ++名称空间类似,请勿在goog.scope声明下缩进。 而是从0列继续。

仅为不会重新分配给另一个对象的名称(例如,大多数构造函数,枚举和名称空间)创建别名。 不要这样做(有关如何为构造函数添加别名,请参见下文):

goog.scope(function() {
var Button = goog.ui.Button;

Button = function() { ... };
...

名称必须与它们别名的全局名称的最后一个属性相同。

goog.provide('my.module.SomeType');

goog.require('goog.dom');
goog.require('goog.ui.Button');

goog.scope(function() {
var Button = goog.ui.Button;
var dom = goog.dom;

// Alias new types after the constructor declaration.
my.module.SomeType = function() { ... };
var SomeType = my.module.SomeType;

// Declare methods on the prototype as usual:
SomeType.prototype.findButton = function() {
  // Button as aliased above.
  this.button = new Button(dom.getElement('my-button'));
};
...
});  // goog.scope
9.4.4.3 goog.forwardDeclare

最好使用goog.requireType代替goog.forwardDeclare来打破同一库中文件之间的循环依赖关系。 与goog.require不同,goog.requireType语句允许在定义名称空间之前导入它。

goog.forwardDeclare仍可在旧版代码中使用,以打破跨越库边界的循环引用,但是应构造新的代码以避免这种情况。

goog.forwardDeclare语句必须遵循与goog.require和goog.requireType相同的样式规则。 goog.forwardDeclare,goog.require和goog.requireType语句的整个块均按字母顺序排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值