文件名须全部小写,下划线(_)和短横线(-)
源文件采用 UTF-8 编码。
左花括号不另起新行
左花括号后紧跟换行
右花括号前需要换行
如果右花括号结束了语句,或者它是函数、类、类中的方法的结束括号,则其后面需要换行。如果后面紧跟的是 else
,catch
或 while
,或逗号,分号以及右括号,则不需要跟一个换行。
新开代码块中代码需要加 2 个空格的缩进
一如其他代码块一样,switch 语句中每个条件块也是增加 2 个空格的缩进。 每个 switch 标签后新起一行,加缩进,就像是创建了一个带花括号的代码块一样。每个标签开始时缩进又恢复,相当于只有 switch 标签中的内容是当作代码块来处理的。
每个声明语句后都跟换行。
语句后需用分号结束。不能依赖于编辑器的自动分号插入功能。
换行的的准则是:尽量在优先级高的语法层面(higher syntactic level)进行
语法优先级从高到低依次为:赋值,除法,函数调用,参数,数字常量。
当发生换行时,第一行后面跟着的其他行至少缩进 4 个空格,除非满足代码块的缩进规则,另说。
换行后后续跟随多行时,缩进可适当大于 4 个空格。通常,语法中低优先级的后续行以 4 的倍数进行缩进,如果只有两行并且处于同一优先级,则保持一样的缩进即可。
以下场景需要有一个空行:
类或对象中的方法间 a. 例外的情形:对象中属性间的空行是可选的。如果有的话,一般是用来将属性进行分组。
方法体中,尽量少地使用空行来进行代码的分隔。函数体开始和结束都不要加空行。 3.类或对象中首个方法前及最后一个方法后的空行,既不提倡也不反对。
适用此风格中其他条目的规定(e.g.3.4 goog.require statements)。
连续多个空行不是必需的,但了不鼓励这么做。
水平方向的空格依位置为定,有三种大的分类:行首(一行的开始),行尾(一行的结束)以及行间(一行中除去行首及行尾的部分)。行首的空格(i.e. 缩进)无处不在。行尾的空格是禁止的。
除了 Javascript 本身及其他规则的要求,还有字面量,注释,JSDoc 等需要的空格外,单个的 ASCII 类型的空格在以下情形中也是需要的。
将关键字(譬如 if
,for
,catch
)与括号((
)分隔。
将关键字(else
,catch
)与闭合括号(}
) 分隔。
对于左花括号有两种例外: a. 作为函数首个参数的对象之前,数组中首个对象元素 (e.g. foo({a: [{c: d}]})
) b. 在模板表达式中,因为模板语法的限制不能加空格(e.g. abc${1 + 2}def
)。
二元,三元操作符的两边
逗号或分号后。但其前面是不允许有空格的。
对象字面量中冒号后面。
双斜线(//
)两边。这里可以使用多个空格,但也不是必需的。
JSDoc 注释及其两边 e.g. 简写的类型声明 this.foo = /** @type {number} */ (bar);
或类型转换(cast)function(/** string */ foo) {
。
推荐将函数的所有参数放在与函数名同一行的位置。如果这样会导致列宽超限,那参数应该以一种易读的方式进行换行。为了节省空间,尽量超过宽度限制时才进行换行,换行后每个参数一行以提高可读性。换行后缩进为 4 个空格。与括号对齐是可以的,但不推荐。
块状注释与被注释代码保持相同缩进。/* ... */
和 //
都是。对于多行的 /* ... */
注释,后续注释行以 *
开头且与上一行缩进保持一致。参数的注释紧随参数之后,用于在函数名或参数名无法完全表达其意思的情况。
注意区分 JSDoc(/** ... */
),上面不注释不能写成这样。
const
和 let
所有本地变量使用 const
或 let
来声明。默认使用 const
,除非该变量需要重新赋值。杜绝使用 var
。
一次只声明一个本地变量,let a = 1, b = 2;
这样的做法是禁止的。
本地变量不要全部一次性声明在代码块的开头。声明在该变量每一次需要被使用的地方,以减少其影响范围。
JSDoc 类型注释可以添加在声明语句上面,或者内联到变量名前面。
始终在元素后面带上一个结束的逗号。
对象属性分为不包含引号或 Symbols 的 structs 类型和包含引号或运算属性的 dicts 类型。两种类型不要混合使用,应该保持一致。
包名使用小写开头的驼峰命名 lowerCamelCase
类,接口,record (这是什么?) 以及 typedef names (类型定义符) 使用大写开头的驼峰 UpperCamelCase
。
未被导出的类只本地使用,并没有用 @private
标识,所以命名上不需要以下划线结尾。
类型名称通常为名词或名词短语。比如,Request
,ImmutableList
,或者 VisibilityMode
。此外,接口名有时会是一个形容词或形容短语(比如 Readable
)。
方法名使用小写开头的驼峰。私有方法需以下划线结尾。
方法名一般为动词或动词短语。比如 sendMessage
或者 stop_
。属性的 Getter 或 Setter 不是必需的,如果有的话,也是小写驼峰命名且需要类似这样 getFoo
(对于布尔值使用 isFoo
或 hasFoo
形式),setFoo(value)
。
注:私有属性或方法以下划线开头才是主流吧
单元测试代码中的方法名会出现用下划线来分隔组件形式。一种典型的形式是这样的test<MethodUnderTest>_<state>
,例如 testPop_emptyStack
。对于这种测试代码中的方法,命名上没有统一的要求
枚举使用大写开头的驼峰,和类相似,一般一个单数形式的名词。枚举中的元素写成 CONSTANT_CASE
。
常量写成 CONSTANT_CASE
:所有字母使用大写,以下划线分隔单词。私有静态属性可以用内部变量代替,所以不会有使用私有枚举的情况,也就无需将常量以下划线结尾来命名。
每个常量都是 @const
标识的静态属性或 模块内部通过 const
声明的变量,但并不是所有 @const
标识的静态属性或 const
声明的变量都是常理。需要常量时,先想清楚该对象是否真的不可变。例如,如果该对象中做生意状态可被改变,显然不适合作为常量。只是想着不去改变它的值是不够的,我们要求它需要从本质上来说应该一成不变。
非常量字段(静态或其他)使用小写开头的驼峰,如果是私有的私有的则以下划线结尾。
一般是名词或名词短语。例如 computedValues
,index_
。
参数使用小写开头的驼峰。即使参数需要一个构造器来初始化时,也是这一规则。
公有方法的参数名不能只使用一个字母。
例外:如果三方库需要,参数名可以用 $
开头。此例外不适用于其他标识符(e.g. 本地变量或属性)。
本地变量使用小写开头的驼峰,除非是上面介绍过的本地常量。函数中的常量命名仍然使用小写开头的驼峰lowerCamelCase
。即使该变量指向的是构造器也使用 lowerCamelCase。
模板参数力求简洁,用一个单词,一个字母表示,全部使用大写,例如 TYPE
,THIS
。
有时将一个英文短语转成驼峰有很多形式,例如首字母进行缩略,IPv6
以及 iOS
这种都有出现。为保证代码可控,本规范规定出如下规则。
将短语移除撇号转成 ASCII 表示。例如 Müller's algorithm
表示成 Muellers algorithm
。
将上述结果拆分成单词,以空格或其他不发音符号(中横线)进行分隔。 a. 推荐的做法:如果其中包含一个已经常用的驼峰翻译,直接提取出来(e.g. AdWords
会成为 ad words
)。需要注意的是 iOS
本身并不是个驼峰形式,它不属性任何形式,所以它不适用本条规则。
将所有字母转成小写,然后将以下情况中的首字母大写: a. 每个单词的首字母,这样便得到了大写开头的驼峰 b. 除首个单词的其他所有单词的首字母,这样得到小写开头的驼峰
将上述结果合并。
过程中原来名称中的大小写均被忽略。
示例:
Prose form | Correct | Incorrect |
---|---|---|
XML HTTP request | XmlHttpRequest | XMLHTTPRequest |
new customer ID | newCustomerId | newCustomerID |
inner stopwatch | innerStopwatch | innerStopWatch |
supports IPv6 on iOS? | supportsIpv6OnIos | supportsIPv6OnIOS |
ouTube importer | YouTubeImporter | YoutubeImporter* |
*这种情况可接受,但不推荐。
注释:一些英文词汇通过中横线连接的方式是有歧义的,比如 "nonempty" 和 "non-empty" 都是正确写法,所以方法名 checkNonempty checkNonEmpty 都算正确。
JSDoc 使用在了所有的类,字段以及方法上。
JSDoc 基本的形式如下:
/** * Multiple lines of JSDoc text are written here, * wrapped normally. * @param {number} arg A number to do something to. */ function doSomething(arg) { … }
或者这种单行的形式:
/** @const @private {!Foo} A short bit of JSDoc. */ this.foo_ = foo;
如果单行形式长到需要折行,则需要切换到多行模式而不是使用单行形式。
有许多工具会对 JSDoc 文档进行解析以提取出有效的信息对代码进行检查和优化。所以这些注释需要好好写。
取而代之,我们应该按 markdown 的语法来格式化
换行之后的 tag 块使用四个空格进行缩进。。
一个文件可以在头部有个总览。包括版权信息,作者以及默认可选的可见信息/visibility level等。文件中包含多个类时,头部这个总览显得很有必要。它可以帮助别人快速了解该文件的内容。如果写了,则应该有一个描述字段简单介绍文件中的内容以及一些依赖,或者其他信息。换行后不缩进。
类的注释
类,接口以及 records 需要有描述,参数,实现的接口以及可见性或其他适当的 tags 注释。类的描述需要告诉读者类的作用及何时使用该类,以及其他一些可以帮助别人正确使用该类的有用信息。构造器上的文本描述可省略。@constructor
和 @extends
不与 class
一起使用,除非该类是用来声明接口 @interface
或者扩展一个泛型类。
枚举和 typedef 需要写文档。仅有的枚举和 typedef 其文档的描述不能为空。枚举中单个元素的文档可直接写在元素的前面一行。
二、《数学之美》第一章读后感
文字和语言vs数字和信息
数字、文字、自然语言都是信息的载体,之间都有联系,同一个目的都是为了记录和传播信息。信息源——编码——信道——解码——接收者。高效的记录信息便是文字的起源,因为不同的文明之间相互隔绝便产生了不同的文字,又因为文明之间的融合和交流便产生了翻译,罗塞塔石碑用三种文字记录了同一件事,让我们对5000年前的埃及文明的了解程度比1000多年前的玛雅文明要了解得多
信息的冗余是安全的保证,双语或者多语言对照的语料对翻译至关重要
数字在早期只是承载信息的工具,并不具备任何抽象的意义,因为我们有十个手指,几乎所有的文明都选择了十进制,二十进制不方便所以灭绝了。
我们把所有西方的拼音文字称为罗马式的语言。古人说话比较快,听的人接收也快,信道比较宽,信息传递就不用压缩,因为书写不方便就是信道比较窄,传递之前要尽量压缩,所以司马迁用53万字记载了上千年中国历史。词可以被认为是有效而且封闭的集合,语言是无限和开放的集合。