代码格式¶
我们原则上遵循 C++格式规范 ,并且进行以下额外的说明。
大括号¶
由于隐含分号的插入,无论大括号括起来的是什么,总是在同一行上开始你的大括号。例如:
if (something) {
// ...
} else {
// …
}
数组和对象初始化表达式¶
当单行数组和对象初始化表达式可以在一行写开时,写成单行是允许的。
var arr = [1, 2, 3]; //之后无空格[或之前]
var obj = {a: 1, b: 2, c: 3}; //之后无空格[或之前]
多行数组和对象初始化表达式缩进两个空格,括号的处理就像块一样单独成行。
//对象初始化表达式
var inset = {
top: 10,
right: 20,
bottom: 15,
left: 12
};
//数组初始化表达式
this.rows_ = [
'"Slartibartfast"
'"Zaphod Beeblebrox"
'"Ford Prefect"
'"Arthur Dent"
'"Marvin the Paranoid Android"
'the.mice@magrathea.com'
];
//在方法调用中使用
goog.dom.createDom(goog.dom.TagName.DIV, {
id: 'foo',
className: 'some-css-class',
style: 'display:none'
}, 'Hello, world!');
长标识符或值在对齐的初始化列表中存在问题,所以初始化值不必对齐。例如:
CORRECT_Object.prototype = {
a: 0,
b: 1,
lengthyName: 2
};
不要像这样:
WRONG_Object.prototype = {
a : 0,
b : 1,
lengthyName: 2
};
函数参数¶
如果可能,应该在同一行上列出所有函数参数。如果这样做将超出每行80个字符的限制,参数必须以一种可读性较好的方式进行换行。为了节省空间,在每一行你可以尽可能的接近80个字符,或者把每一个参数单独放在一行以提高可读性。缩进可能是四个空格,或者和括号对齐。下面是最常见的参数换行形式:
// 四个空格,每行包括80个字符。适用于非常长的函数名,
// 重命名不需要重新缩进,占用空间小。
goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
// ...
};
//四个空格,每行一个参数。适用于长函数名,
// 允许重命名,并且强调每一个参数。
goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
veryDescriptiveArgumentNumberOne,
veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy,
artichokeDescriptorAdapterIterator) {
// ...
};
// 缩进和括号对齐,每行80字符。 看上去是分组的参数,
// 占用空间小。
function foo(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
// ...
}
// 和括号对齐,每行一个参数。看上去是分组的并且
// 强调每个单独的参数。
function bar(veryDescriptiveArgumentNumberOne,
veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy,
artichokeDescriptorAdapterIterator) {
// ...
}
当函数调用本身缩进,你可以自由地开始相对于原始声明的开头或者相对于当前函数调用的开头,进行4个空格的缩进。以下都是可接受的缩进风格。
if (veryLongFunctionNameA(
veryLongArgumentName) ||
veryLongFunctionNameB(
veryLongArgumentName)) {
veryLongFunctionNameC(veryLongFunctionNameD(
veryLongFunctioNameE(
veryLongFunctionNameF)));
}
匿名函数传递¶
当在一个函数的参数列表中声明一个匿名函数时,函数体应该与声明的左边缘缩进两个空格,或者与function关键字的左边缘缩进两个空格。这是为了匿名函数体更加可读(即不被挤在屏幕的右侧)。
prefix.something.reallyLongFunctionName('whatever', function(a1, a2) {
if (a1.equals(a2)) {
someOtherLongFunctionName(a1);
} else {
andNowForSomethingCompletelyDifferent(a2.parrot);
}
});
var names = prefix.something.myExcellentMapFunction(
verboselyNamedCollectionOfItems,
function(item) {
return item.name;
});
使用goog.scope命名别名¶
goog.scope 可用于在使用 the Closure Library 的工程中缩短命名空间的符号引用。
每个文件只能添加一个 goog.scope 调用。始终将它放在全局范围内。
开放的 goog.scope(function() { 调用必须在之前有一个空行,并且紧跟 goog.provide 声明、 goog.require 声明或者顶层的注释。调用必须在文件的最后一行闭合。在scope声明闭合处追加 // goog.scope 。注释与分号间隔两个空格。
和C++命名空间相似,不要在 goog.scope 声明下面缩进。相反,从第0列开始。
只取不会重新分配给另一个对象(例如大多数的构造函数、枚举和命名空间)的别名。不要这样做:
goog.scope(function() {
var Button = goog.ui.Button;
Button = function() { ... };
...
别名必须和全局中的命名的最后一个属性相同。
goog.provide('my.module');
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
更多的缩进¶
事实上,除了 初始化数组和对象 和传递匿名函数外,所有被拆开的多行文本应与之前的表达式左对齐,或者以4个(而不是2个)空格作为一缩进层次。
someWonderfulHtml = '' +
getEvenMoreHtml(someReallyInterestingValues, moreValues,
evenMoreParams, 'a duck', true, 72,
slightlyMoreMonkeys(0xfff)) +
'';
thisIsAVeryLongVariableName =
hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine();
thisIsAVeryLongVariableName = 'expressionPartOne' + someMethodThatIsLong() +
thisIsAnEvenLongerOtherFunctionNameThatCannotBeIndentedMore();
someValue = this.foo(
shortArg,
'Some really long string arg - this is a pretty common case, actually.',
shorty2,
this.bar());
if (searchableCollection(allYourStuff).contains(theStuffYouWant) &&
!ambientNotification.isActive() && (client.isAmbientSupported() ||
client.alwaysTryAmbientAnyways())) {
ambientNotification.activate();
}
空行¶
使用新的空行来划分一组逻辑上相关联的代码片段。例如:
doSomethingTo(x);
doSomethingElseTo(x);
andThen(x);
nowDoSomethingWith(y);
andNowWith(z);
二元和三元操作符¶
操作符始终跟随着前行, 这样你就不用顾虑分号的隐式插入问题。否则换行符和缩进还是遵循其他谷歌规范指南。
var x = a ? b : c; // All on one line if it will fit.
// Indentation +4 is OK.
var y = a ?
longButSimpleOperandB : longButSimpleOperandC;
// Indenting to the line position of the first operand is also OK.
var z = a ?
moreComplicatedB :
moreComplicatedC;
点号也应如此处理。
var x = foo.bar().
doSomething().
doSomethingElse();