Arrays
1 给数组添加项时,使用push 而不用 arr[arr.length] = ''"
var arr = [];
//bad
arr[arr.length] = '123321';
//good
arr.push('123321');
2 复制数组时候:使用slice
var len = items.length;
var itemsCopy = [];
var i;
//bad
for(i = 0; i < len; i++){
itemsCopy[i] = item[i];
}
//good
itemsCopy = items.slice();
3 将一个类数组转成数组时候:使用slice
var args = Array.prototype.slice.call(arr);
Functions
1 不要在非函数代码块(if while 等)中声明函数, 把那个函数赋给一个变量。浏览器允许你这么做,但它们的解析表现不一致。
// bad
if (currentUser) {
function test() {
console.log('Nope.');
}
}
// good
var test;
if (currentUser) {
test = function test() {
console.log('Yup.');
};
}
2 永远不要把参数命名为 arguments. 这将取代函数作用域内的arguments对象。
Properties
1 使用.来访问对象的属性
var luke = {
jedi: true,
age: 28
};
//bad
var isJedi = luke['jedi'];
//good
var isJedi = luke.jedi;
2 当通过变量访问属性时使用中括号[]。
var luke = {
jedi: true,
age: 28
};
function getProp(prop) {
return luke[prop];
}
var isJedi = getProp('jedi');
变量
1 总是使用var 来声明变量。避免产生全局变量,避免污染全局命名空间。
2 每个var 只能声明一个变量。原因:如果var 声明多给变量,容易导致较长的行长度,并且在修改时容易造成逗号和分号的混淆.
3 在作用域的顶部声明变量,这样做,可以避免因变量提升而带来的问题。
//bad
function () {
test();
console.log("doing stuff...");
//..other stuff..
if(name === 'test') {
return false;
}
return name;
}
//good
function () {
var name = getName();
test();
console.log('dong stuff..');
//..other stuff..
if(name === 'test'){
return false;
}
return name;
}
4 最后声明未赋值的变量。当你需要引用前面的变量赋值时这将变得很有作用。
//bad
var i;
var items = getItems();
var dragonball;
var goSportsTeam = true;
var len;
//good
var items = getItems();
var dragonball;
var goSportsTeam = true;
var len;
变量提升
1 变量声明会提升至作用域顶部,但赋值不会。
2 匿名函数表达式会提升它们的变量名,但不会提升函数的赋值
3 命名函数表达式会提升变量名,但不会提升函数名或函数体
4 函数声明提升它们的名字和函数体
function example() {
console.log(named); // => undefined
named(); // => TypeError named is not a function
superPower(); // => ReferenceError superPower is not defined
var named = function superPower() {
console.log('Flying');
};}
function example() {
console.log(named); // => undefined
named(); // => TypeError named is not a function
var named = function named() {
console.log('named');
}
}
条件
1 优先使用 === 和 !== 而不是 == 和 !=
2 尽可能使用简洁的表达式。
//字符串为空
// good
if (!name){
}
// bad
if (name === ''){
}
//字符串非空
// good
if (name) {
}
// bad
if(name !== ''){
}
//数组非空
// good
if (collection.length) {
}
// bad
if(collection.length > 0){
}
//布尔不成立
// good
if(!notTrue){
}
// bad
if(notTrue === false){
}
// null 或 undefined
// good
if(noValue == null){
}
// bad
if(noValue === null || typeof noValue === 'undefined'){
}
3 按执行频率排列分支的顺序。原因:提高执行效率和检查代码的出错效率。
命名
1 变量,函数名、函数的参数,类的属性、方法,命名空间使用Camel(骆驼)命名法。
var loadingModules = {}; //变量
function stringFormat(theBells) {}; //函数名,参数
function Person(name, age){ //类的属性,方法
this.name = name;
this.age = age;
}
Person.prototype.getName = function() {};
equipments.heavyWeapons = {}; //命名空间
2 类名,枚举变量名使用Pascal(帕斯卡)命名法。
function TextNode() {} //类名
var TargetState = {}; //枚举变量
3 常量,枚举变量的属性 使用 全部字母大写,单词间以下划线分隔 的命名方式。
var HTML_ENTITY = {}; //常量
var TargetState = { //枚举变量属性
READING: 1,
READED: 2,
READY: 3
};
4 以下划线"_"开头命名私有变量
//bad
this._firstName_ = "123";
this.firstName = '123';
//good
this._firstName = '123';
5 当要保存this时候,使用_this来保存
//bad
function () {
var self = this;
return function () {
console.log(self);
}
}
//good
function () {
var _this = this;
return function () {
console.log(_this);
}
}
6 类名使用 名词,函数名使用 动宾短语, Promise对象(遗留问题) 用动宾短语的进行时。
function Engine(options) {} //类名
function getStyle(){ //函数名
}
var loadingData = ajax.get('url'); //Promise对象
loadingData.then(callback);
7 boolean 类型的变量使用 is 或 has 开头。
var isReady = false;
var hasMoreCommands = false;
8 给函数命名。这在做堆栈轨迹时很有帮助
//bad
var log = function (msg) {
console.log(msg);
};
//good
var log = function log(msg) {
console.log(msg);
}
9 如果你的文件导出一个类,你的文件名应该与类名完全相同
class checkBox {
//..
}
module.exports = checkBox;
//in some other file
//bad
var CheckBox = require('./checkBox');
//bad
var CheckBox = require('./check_box');
//good
var CheckBox = require('./CheckBox');
空格
此部分只需要了解,因为sublineText3的格式化代码插件已经帮助开发人员做到了
1 二元运算符两侧必须有一个空格,一元运算符与操作对象之间不允许有空格。
a = b + c;
var a = !true;
2 用作代码块起始的左花括号"{"前必须有一个空格。
//bad
function show (){
}
//good
function show () {
}
3 if / else / for / while / function...关键字后,必须有一个空格。
if (condition) {
}
4 对象中,属性中":"之后必须有空格,":"之前不允许有空格。
var obj = {
a: 1,
b: 2
};
5 "," 和";"前不允许有空格。
//bad
callFunc(a , b);
//good
callFunc(a, b);
6 在函数调用、函数声明、括号表达式、属性访问、if/for 等语句中,()和 [] 内紧贴括号部分不允许有空格。
// bad
callFunc( param1, param2, param3 );
if( num > list.length ){
}
while( len-- ){
}
// good
callFunc(param1, param2, param3);
if(num > list.length)}{
}
while(len--) {
}
换行问题
1 单行声明的数组与对象,如果包含元素,{}和[]内紧贴括号部分不允许包含空格。另外当内部元素的形式较为复杂时候,还应该换行书写。
//bad
var arr1 = [ 1, 2, 3 ];
var obj3 = { name: 'obj', age: 20};
//good
var arr1 = [1, 2, 3];
var obj1 = {
name: 'obj',
age: 20,
sex: 1
};
2 运算符处换行时,运算符必须在新行的行首。(并未强调换行时,运算符必须在行首)
if (user.isAuthenticated()
&& user.isInRole('admin')
&& user.hasAuthority('add-admin')
|| user.hasAuthority('delete-admin')
) {
// Code
}
var result = number1 + number2 + number3
+ number4 + number5;
3 在语句的行长度超过 120 时, 根据逻辑条件合理缩进。(额外)
// 按一定长度截断字符串,并使用 + 运算符进行连接。
// 分隔字符串尽量按语义进行,如不要在一个完整的名词中间断开。
// 特别的,对于HTML片段的拼接,通过缩进,保持和HTML相同的结构。
var html = '' // 此处用一个空字符串,以便整个HTML片段都在新行严格对齐
+ '<article>'
+ '<h1>Title here</h1>'
+ '<p>This is a paragraph</p>'
+ '<footer>Complete</footer>'
+ '</article>';
// 也可使用数组来进行拼接,相对 + 更容易调整缩进。
var html = [
'<article>',
'<h1>Title here</h1>',
'<p>This is a paragraph</p>',
'</article>'];
html = html.join('');
// 当参数过多时,将每个参数独立写在一行上,并将结束的右括号 ) 独立一行。
// 所有参数必须增加一个缩进。
foo(
aVeryVeryLongArgument,
anotherVeryLongArgument,
callback
);
// 链式调用较长时采用缩进进行调整。
$('#items')
.find('.selected')
.highlight()
.end();
// 也可以按逻辑对参数进行组合。
// 最经典的是baidu.format函数,调用时将参数分为“模板”和“数据”两块
baidu.format(
dateFormatTemplate,
year, month, date, hour, minute, second
);
4 当在程序中生成一个字符串时候,使用Array 而不是用 "+"拼接
var items;
var messages;
var length;
var i;
messages = [{
state: 'success',
message: 'This one worked.'
}, {
state: 'success',
message: 'This one worked as well.'
}, {
state: 'error',
message: 'This one did not work.'
}];
length = messages.length;
// bad
function inbox(messages) {
items = '<ul>';
for (i = 0; i < length; i++) {
items += '<li>' + messages[i].message + '</li>';
}
return items + '</ul>';
}
// good
function inbox(messages) {
items = [];
for (i = 0; i < length; i++) {
// use direct assignment in this case because we're micro-optimizing.
items[i] = '<li>' + messages[i].message + '</li>';
}
return '<ul>' + items.join('') + '</ul>';
}
类型转换
在语句开始时执行类型转换
1 转字符串
//bad
var str = str2 + '';
//good
var str = '' + str2;
//bad
var str = '' + str2 + '123';
//good
var str = '123' + str2;
2 转Number,转换数字时总是带上类型转换基数
var num = '4';
//bad
var val = parseInt(num);
//good
var val = Number(num);
var val = parseInt(inputValue, 10);
3 转Booleans
var age = 0;
//bad
var hasAge = new Boolean(age);
//good
var hasAge = Boolean(age);
var hasAge = !!age
构造函数
给对象原型分配方法,而不是使用一个新对象覆盖原型。覆盖原型将导致继承出现问题:重设原型将覆盖原有原型!
function Jedi() {
console.log('new jedi');
}
// bad
Jedi.prototype = {
fight: function fight() {
console.log('fighting');
},
block: function block() {
console.log('blocking');
}
};
// good
Jedi.prototype.fight = function fight() {
console.log('fighting');
};
Jedi.prototype.block = function block() {
console.log('blocking');
};
2 为了能实现链式调用,可以在每个方法中返回return this
// bad
Jedi.prototype.jump = function jump() {
this.jumping = true;
return true;
};
Jedi.prototype.setHeight = function setHeight(height) {
this.height = height;
};
var luke = new Jedi();
luke.jump(); // => true
luke.setHeight(20); // => undefined
// good
Jedi.prototype.jump = function jump() {
this.jumping = true;
return this;
};
Jedi.prototype.setHeight = function setHeight(height) {
this.height = height;
return this;
};
var luke = new Jedi();
luke.jump()
.setHeight(20);
事件
在注册事件(on)以及触发注册事件(trigger)中,参数要以json的格式传递。这是为了以后修改过程中,不需要更新trigger函数。
//bad
$(this).trigger('listingUpdated', listing.id);
...
$(this).on('listingUpdated', function (e, listingId) {
// do something with listingId
});
//good
$(this).trigger('listingUpdated', { listingId : listing.id });
...
$(this).on('listingUpdated', function (e, data) {
// do something with data.listingId
});
JQuery
1 jQuery对象以$开发命名
// bad
var sidebar = $('.sidebar');
// good
var $sidebar = $('.sidebar');
2 当多次使用jQuery对象的时候,缓存jQuery对象
// bad
function setSidebar() {
$('.sidebar').hide();
// ...stuff...
$('.sidebar').css({ 'background-color': 'pink' });}
// good
function setSidebar() {
var $sidebar = $('.sidebar');
$sidebar.hide();
// ...stuff...
$sidebar.css({
'background-color': 'pink'
});
}
3 查找jQuery对象的时候,如果存在层级(父子)关系的时候,使用$('.sidebar ul') 或 $('.sidebar > ul')
//bad
$('ul', '.sidebar').hide();
$('.sidebar').find('ul').hide();
//good
$('.sidebar ul').hide();
$('.sidebar > ul').hide();
$sidebar.find('ul').hide();
4 对有作用域的jQuery对象查询使用find
参考文献
https://github.com/airbnb/javascript/tree/master/es5#naming-conventions
https://github.com/sivan/javascript-style-guide/blob/master/es5/README.md#variables
网友评论