数组、对象
1.使用字面值创建对象:
// bad var item = new Object();
// good var item = {};
2.使用字面值创建数组:
// bad var items = new Array();
// good var items = [];
3.如果你不知道数组的长度,使用push:
var someStack = [];
// bad someStack[someStack.length] = 'abracadabra';
// good someStack.push('abracadabra');
4.当你需要拷贝数组时使用slice
var len = items.length, itemsCopy = [], i;
// bad for (i = 0; i < len; i++) { itemsCopy[i] = items[i]; }
// good itemsCopy = items.slice();
字符串
1.对字符串使用单引号''(因为大多时候我们的字符串。特别html会出现"):
// bad var name = "Bob Parr";
// good var name = 'Bob Parr';
// bad var fullName = "Bob " + this.lastName;
// good var fullName = 'Bob ' + this.lastName;
2.超过80(也有规定140的,项目具体可制定)个字符的字符串应该使用字符串连接换行。
注: 如果过度使用,长字符串连接可能会对性能有影响. jsPerf & Discussion
// bad var errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
// bad var errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
// good var errorMessage = 'This is a super long error that ' + 'was thrown because of Batman.' + 'When you stop to think about ' + 'how Batman had anything to do ' + 'with this, you would get nowhere ' + 'fast.';
函数
1.函数表达式:
// 匿名函数表达式 var anonymous = function() { return true; };
// 有名函数表达式 var named = function named() { return true; };
// 立即调用函数表达式 (function() { console.log('Welcome to the Internet. Please follow me.'); })();
属性
1.当使用变量和特殊非法变量名时,访问属性时可以使用中括号(. 优先)。
var luke = { jedi: true, age: 28 };
function getProp(prop) { return luke[prop]; }
var isJedi = getProp('jedi');
变量
1.总是使用 var 来声明变量,如果不这么做将导致产生全局变量,我们要避免污染全局命名空间。
// bad superPower = new SuperPower();
// good var superPower = new SuperPower();
2.使用一个 var以及新行声明多个变量,缩进4个空格。
// bad var items = getItems(); var goSportsTeam = true; var dragonball = 'z';
// good var items = getItems(), goSportsTeam = true, dragonball = 'z';
3.最后再声明未赋值的变量,当你想引用之前已赋值变量的时候很有用。
// bad var i, len, dragonball, items = getItems(), goSportsTeam = true;
// bad var i, items = getItems(), dragonball, goSportsTeam = true, len;
// good var items = getItems(), goSportsTeam = true, dragonball, length, i;
4.在作用域顶部声明变量,避免变量声明和赋值引起的相关问题。
// bad function() { test(); console.log('doing stuff..');
//..other stuff.. var name = getName(); if (name === 'test') { return false; } return name; }
// good function() { var name = getName(); test(); console.log('doing stuff..'); //..other stuff.. if (name === 'test') { return false; } return name; }
// bad function() { var name = getName(); if (!arguments.length) { return false; } return true; }
// good function() { if (!arguments.length) { return false; } var name = getName(); return true; }
条件表达式
1.使用快捷方式:
// bad if (name !== '') { // ...stuff... } // good if (name) { // ...stuff... } // bad if (collection.length > 0) { // ...stuff... } // good if (collection.length) { // ...stuff... }
块
1.给所有多行的块使用大括号:
// bad if (test) return false;
// good if (test) return false;
// good if (test) { return false; }
// bad function() { return false; }
// good function() { return false; }
注释
1.使用 /** ... */进行多行注释,包括描述,指定类型以及参数值和返回值。
2.使用 // 进行单行注释,在评论对象的上面进行单行注释,注释前放一个空行。
空白
缩进、格式化能帮助团队更快得定位修复代码BUG.
1.将tab设为4个空格
// bad function() { ∙∙var name; } // bad function() { ∙var name; }
// good function() { ∙∙∙∙var name; }
2.大括号前放一个空格:
// bad function test(){ console.log('test'); }
// good function test() { console.log('test'); }
// bad dog.set('attr',{ age: '1 year', breed: 'Bernese Mountain Dog' });
// good dog.set('attr', { age: '1 year', breed: 'Bernese Mountain Dog' });
3.在做长方法链时使用缩进。
// bad $('#items').find('.selected').highlight().end().find('.open').updateCount();
// good $('#items') .find('.selected') .highlight() .end() .find('.open') .updateCount();
// bad var leds = stage.selectAll('.led').data(data).enter().append('svg:svg').class('led', true) .attr('width', (radius + margin) * 2).append('svg:g') .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')') .call(tron.led);
// good var leds = stage.selectAll('.led') .data(data) .enter().append('svg:svg') .class('led', true) .attr('width', (radius + margin) * 2) .append('svg:g') .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')') .call(tron.led);
逗号
1.不要将逗号放前面:
// bad var once , upon , aTime;
// good var once, upon, aTime;
// bad var hero = { firstName: 'Bob' , lastName: 'Parr' , heroName: 'Mr. Incredible' , superPower: 'strength' };
// good var hero = { firstName: 'Bob', lastName: 'Parr', heroName: 'Mr. Incredible', superPower: 'strength' };
2.不要加多余的逗号,这可能会在IE下引起错误,同时如果多一个逗号某些ES3的实现会计算多数组的长度。
// bad var hero = { firstName: 'Kevin', lastName: 'Flynn', }; var heroes = [ 'Batman', 'Superman', ];
// good var hero = { firstName: 'Kevin', lastName: 'Flynn' }; var heroes = [ 'Batman', 'Superman' ];
分号
1.语句结束一定要加分号:
// bad (function() { var name = 'Skywalker' return name })()
// good (function() { var name = 'Skywalker'; return name; })();
// good ;(function() { var name = 'Skywalker'; return name; })();
类型转换
在语句的开始执行类型转换。
1.字符串:
// => this.reviewScore = 9;
// bad var totalScore = this.reviewScore + '';
// good var totalScore = '' + this.reviewScore;
// bad var totalScore = '' + this.reviewScore + ' total score';
// good var totalScore = this.reviewScore + ' total score';
2.对数字使用parseInt 并且总是带上类型转换的基数。如parseInt(value, 10)
var inputValue = '4';
// bad var val = new Number(inputValue);
// bad var val = +inputValue;
// bad var val = inputValue >> 0;
// bad var val = parseInt(inputValue);
// good var val = Number(inputValue);
// good var val = parseInt(inputValue, 10);
// good /** * parseInt was the reason my code was slow. * Bitshifting the String to coerce it to a * Number made it a lot faster. */ var val = inputValue >> 0;
3.布尔值:
var age = 0;
// bad var hasAge = new Boolean(age);
// good var hasAge = Boolean(age);
// good var hasAge = !!age;
命名约定
1.避免单个字符名,让你的变量名有描述意义。
2.当命名对象、函数和实例时使用驼峰命名规则。
3.当命名构造函数或类时使用驼峰式大写。
4.命名私有属性时前面加个下划线_.
5.当保存对 this 的引用时使用 self(python 风格),避免this issue.Angular建议使用vm(MVVM模式中view-model)
构造器
1.给对象原型分配方法,而不是用一个新的对象覆盖原型,覆盖原型会使继承出现问题。
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.方法可以返回 this 帮助方法可链。
// bad Jedi.prototype.jump = function() { this.jumping = true; return true; }; Jedi.prototype.setHeight = function(height) { this.height = height; }; var luke = new Jedi(); luke.jump();
// => true luke.setHeight(20) // => undefined // good Jedi.prototype.jump = function() { this.jumping = true; return this; }; Jedi.prototype.setHeight = function(height) { this.height = height; return this; }; var luke = new Jedi(); luke.jump() .setHeight(20);
3.可以写一个自定义的toString()方法,但是确保它工作正常并且不会有副作用。
function Jedi(options) { options || (options = {}); this.name = options.name || 'no name'; }
Jedi.prototype.getName = function getName() { return this.name; };
Jedi.prototype.toString = function toString(){ return 'Jedi - ' + this.getName(); };
事件
1.当给事件附加数据时,传入一个哈希而不是原始值,这可以让后面的贡献者加入更多数据到事件数据里而不用找出并更新那个事件的事件处理器。
// 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 });
模块
这个文件应该以驼峰命名,并在同名文件夹下,同时导出的时候名字一致
对于公开API库可以考虑加入一个名为noConflict()的方法来设置导出的模块为之前的版本并返回它
总是在模块顶部声明 'use strict';,引入JSHint规范
// fancyInput/fancyInput.js (function(global) { 'use strict'; var previousFancyInput = global.FancyInput; function FancyInput(options) { this.options = options || {}; } FancyInput.noConflict = function noConflict() { global.FancyInput = previousFancyInput; return FancyInput; }; global.FancyInput = FancyInput; })(this);
jQuery
1.对于jQuery对象以$开头,以和原生DOM节点区分。
// bad var menu = $(".menu");
// good var $menu = $(".menu");
2.缓存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' }); }
2.对DOM查询使用级联的$('.sidebar ul')或 $('.sidebar ul'),jsPerf
3.对有作用域的jQuery对象查询使用 find
// bad $('.sidebar', 'ul').hide();
// bad $('.sidebar').find('ul').hide();
// good $('.sidebar ul').hide();
// good $('.sidebar > ul').hide();
// good (slower) $sidebar.find('ul');
// good (faster) $($sidebar[0]).find('ul');
4.每个页面只使用一次document的ready事件,这样便于调试与行为流跟踪。
$(function(){ //do your page init. });
5.事件利用jQuery.on从页面分离到JavaScript文件。
// bad <a id="myLink" href="#" onclick="myEventHandler();"></a>
// good <a id="myLink" href="#"></a> $("#myLink").on("click", myEventHandler);
6.对于Ajax使用promise方式。
// bad $.ajax({ ... success : function(){ }, error : function(){ } })
// good $.ajax({. .. }).then( function( ){ // success }, function( ){ // error })
7.利用promise的deferred对象解决延迟注册问题。
var dtd = $.Deferred();
// 新建一个deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd; };
8.HTML中Style、以及JavaScript中style移到CSS中class,在HTML、JavaScript中引入class,而不是直接style。
本文摘自http://m.imooc.com/article/1402