成功的意义不在于你取得多大的成就,也不在于你有多么的伟大。因为,成功总会与努力过的人握手,只要享受了努力的过程,我们就不是失败者。
命名
通常,使用 functionNamesLikeThis, variableNamesLikeThis, ClassNamesLikeThis, EnumNamesLikeThis, methodNamesLikeThis 和 SYMBOLIC_CONSTANTS_LIKE_THIS 。具体如下:
属性和方法
文件或类中的私有属性,变量和方法名应该以下划线 "_" 开头;
保护属性, 变量和方法名不需要下划线开头,和公共变量名一样。
方法和函数参数
可选参数以 opt_ 开头;
函数的参数个数不固定时,应该添加最后一个参数 var_args 为参数的个数。你也可以不设置 var_args 而取代使用 arguments;
可选和可变参数应该在 @param 标记中说明清楚。
虽然这两个规定对编译器没有任何影响,但还是请尽量遵守。
Getters 和 Setters
Getters 和 setters 并不是必要的。但只要使用它们了,就请将 getters 命名成 getFoo() 形式,将 setters 命名成 setFoo(value) 形式。(对于布尔类型的 getters,使用 isFoo() 也可。)
命名空间
JavaScript 不支持包和命名空间。
不容易发现和调试全局命名的冲突,多个系统集成时还可能因为命名冲突导致很严重的问题。为了提高 JavaScript 代码复用率,我们遵循下面的约定以避免冲突。
为全局代码使用命名空间
在全局作用域上,使用一个唯一的,与工程/库相关的名字作为前缀标识。比如:你的工程是 "Project Sloth", 那么命名空间前缀可取为 sloth.* 。
var sloth = {};
sloth.sleep = function() {
...
};
明确命名空间所有权
当选择了一个子命名空间,请确保父命名空间的负责人知道你在用哪个子命名空间。比如说, 你为工程 'sloths' 创建一个 'hats' 子命名空间, 那确保 Sloth 团队人员知道你在使用 sloth.hats.
外部代码和内部代码使用不同的命名空间
"外部代码" 是指来自于你代码体系的外部,可以独立编译。内外部命名应该严格保持独立。如果你使用了外部库,他的所有对象都在 foo.hats.* 下,那么你自己的代码不能在 foo.hats.* 下命名,因为很有可能其他团队也在其中命名。
重命名那些名字很长的变量,提高可读性
主要是为了提高可读性。局部空间中的变量别名只需要取原名字的最后部分。
/**
* @constructor
*/
some.long.namespace.MyClass = function() {
};
/**
* @param {some.long.namespace.MyClass} a
*/
some.long.namespace.MyClass.staticHelper = function(a) {
...
};
myapp.main = function() {
var MyClass = some.long.namespace.MyClass;
var staticHelper = some.long.namespace.MyClass.staticHelper;
staticHelper(new MyClass());
};
不要对命名空间创建别名
myapp.main = function() {
var namespace = some.long.namespace;
namespace.MyClass.staticHelper(new namespace.MyClass());
};
不要在全局范围内创建别名,而仅在函数块作用域中使用。
myapp.main = function() {
var MyClass = some.long.namespace.MyClass;
MyClass.staticHelper(null);
};
文件名
文件名应该使用小写字符,以避免在有些系统平台上不识别大小写的命名方式。文件名以 .js 结尾,不要包含除 - 和 _ 外的标点符号(使用 - 优于 _)。
自定义 toString() 方法
可自定义 toString() 方法,但确保你的实现方法满足:(1)总是成功;(2)没有其他负面影响。如果不满足这两个条件,那么可能会导致严重的问题。比如:如果 toString() 调用了包含 assert 的函数,assert 输出导致失败的对象,这在 toString() 也会被调用。
延迟初始化
可以延迟变量的初始化,没有必要在每次声明变量时就将其初始化。
明确作用域
任何时候都要明确作用域,以提高可移植性和清晰度。
例如,不要依赖于作用域链中的 window 对象。可能在其他应用中,你函数中的 window 不是指之前的那个窗口对象。
代码格式化
大括号
分号会被隐式插入到代码中,所以你务必在同一行上插入大括号。例如:
if (something) {
// ...
} else {
// ...
}
数组和对象的初始化
如果初始值不是很长,就保持写在单行上:
var arr = [1, 2, 3]; // No space after [ or before ].
var obj = {a: 1, b: 2, c: 3}; // No space after { or before }.
初始值占用多行时,缩进2个空格:
// Object initializer.
var inset = {
top: 10,
right: 20,
bottom: 15,
left: 12
};
// Array initializer.
this.rows_ = [
'"Slartibartfast" ',
'"Zaphod Beeblebrox" ',
'"Ford Prefect" ',
'"Arthur Dent" ',
'"Marvin the Paranoid Android" ',
'the.mice@magrathea.com'
];
// Used in a method call.
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 字符,每个参数独占一行,并以4个空格缩进,或者与括号对齐,以提高可读性。尽可能不要让每行超过80个字符。
// Four-space, wrap at 80. Works with very long function names, survives
// renaming without reindenting, low on space.
goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
veryDescriptiveArgumentnumberOne, veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
// ...
};
// Four-space, one argument per line. Works with long function names,
// survives renaming, and emphasizes each argument.
goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
veryDescriptiveArgumentNumberOne,
veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy,
artichokeDescriptorAdapterIterator) {
// ...
};
// Parenthesis-aligned indentation, wrap at 80. Visually groups arguments,
// low on space.
function foo(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
// ...
}
// Parenthesis-aligned, one argument per line. Emphasizes each
// individual argument.
function bar(veryDescriptiveArgumentNumberOne,
veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy,
artichokeDescriptorAdapterIterator) {
// ...
}
传递匿名函数
如果参数中有匿名函数,函数体从调用该函数的左边开始缩进2个空格,而不是从 function 这个关键字开始。这让匿名函数更加易读 (不要增加很多没必要的缩进让函数体显示在屏幕的右侧)。
var names = items.map(function(item) {
return item.name;
});
prefix.something.reallyLongFunctionName('whatever', function(a1, a2) {
if (a1.equals(a2)) {
someOtherLongFunctionName(a1);
} else {
andNowForSomethingCompletelyDifferent(a2.parrot);
}
});
更多的缩进
事实上,除了初始化数组和对象,和传递匿名函数外,所有被拆开的多行文本要么选择与之前的表达式左对齐,要么以4个(而不是2个)空格作为一缩进层次。
someWonderfulHtml = ''
getEvenMoreHtml(someReallyInterestingValues, moreValues,
evenMoreParams, 'a duck', true, 72,
slightlyMoreMonkeys(0xfff))
'';
thisIsAVeryLongVariableName =
hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine();
thisIsAVeryLongVariableName = siblingOne siblingTwo siblingThree
siblingFour siblingFive siblingSix siblingSeven
moreSiblingExpressions allAtTheSameIndentationLevel;
thisIsAVeryLongVariableName = operandOne operandTwo operandThree
operandFour operandFive * (
aNestedChildExpression shouldBeIndentedMore);
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;
括号
括号只在需要的时候使用。
不要滥用括号,只在必要的时候使用它。
对于一元操作符(如 delete, typeof 和 void ),或是在某些关键词(如 return, throw, case, new )之后,不要使用括号。
字符串
使用 单引号(') 优于 双引号(") 。
var msg = 'This is some HTML';
可见性
用 @private 和 @protected 来指名类、函数、属性的可见性。
标记为 @private 的全局变量和函数,表示他们只能在当前文件中访问。
标记为 @private 的构造函数,表示该类只能在当前文件或是其静态/普通成员中实例化。私有构造函数的公共静态属性在当前文件的任何地方都可访问,通过 instanceof 操作符也可。
永远不要为全局变量,函数,构造器加 @protected 标记。
// File 1.
// AA_PrivateClass_ and AA_init_ are accessible because they are global
// and in the same file.
/**
* @private
* @constructor
*/
AA_PrivateClass_ = function() {
};
/** @private */
function AA_init_() {
return new AA_PrivateClass_();
}
AA_init_();
标记为 @private 的属性,在当前文件中可访问它。如果是类属性私有,"拥有"该属性的类的所有静态/普通成员也可访问,但它们不能被不同文件中的子类访问或覆盖。
标记为 @protected 的属性,在当前文件中可访问它。如果是类属性私有,那么"拥有"该属性的类及其子类中的所有静态/普通成员也可访问。
// File 1.
/** @constructor */
AA_PublicClass = function() {
};
/** @private */
AA_PublicClass.staticPrivateProp_ = 1;
/** @private */
AA_PublicClass.prototype.privateProp_ = 2;
/** @protected */
AA_PublicClass.staticProtectedProp = 31;
/** @protected */
AA_PublicClass.prototype.protectedProp = 4;
// File 2.
/**
* @return {number} The number of ducks we've arranged in a row.
*/
AA_PublicClass.prototype.method = function() {
// Legal accesses of these two properties.
return this.privateProp_ AA_PublicClass.staticPrivateProp_;
};
// File 3.
/**
* @constructor
* @extends {AA_PublicClass}
*/
AA_SubClass = function() {
// Legal access of a protected static property.
AA_PublicClass.staticProtectedProp = this.method();
};
goog.inherits(AA_SubClass, AA_PublicClass);
/**
* @return {number} The number of ducks we've arranged in a row.
*/
AA_SubClass.prototype.method = function() {
// Legal access of a protected instance property.
return this.protectedProp;
};
这是小编的一部分总结,有想看下面的内容点播关注哦,等待小编的更新,有想学习前端的伙伴可以私信我!
,