【原】javascript最佳实践
摘要:这篇文章主要内容的来源是《javascript高级程序设计第三版》,因为第二遍读完,按照书里面的规范,发觉自己在工作中没有好好遵守。所以此文也是对自己书写js的一种矫正。
1、可维护性
1.1
可理解性——其他人可以接手代码并理解它的意图和一般途径,而无需原开发人员的完整解释。
直观性——代码中的东西一看就能明白,不管其操作过程多么复杂。
可适应性——代码以一种数据上的变化不要求完全重写的方法撰写。
可扩展性——在代码架构上已考虑到在未来允许对核心功能进行扩展。
可调试性——当有地方出错时,代码可以给予你足够的信息来尽可能直接地确定问题所在。
1.2 代码约定:
变量和函数命名
命名的一般规则如下所示:
变量名应为名词如 car 或 person。
函数名应该以动词开始,如 getName()。返回布尔类型值的函数一般以 is 开头,如isEnable()。
变量和函数都应使用合乎逻辑的名字,不要担心长度。长度问题可以通过后处理和压缩来缓解。
变量类型透明:
// 通过初始化来指定变量的类型 var found=false; //布尔型 var count=-1; //数字 var name=''; //字符串 var array=[]; //数组
1.3松散耦合:
1.3.1、解耦HTML/javascript
就是说一些事件不要在html元素里面加onclick等来执行,而是将HTML和javascript分离,通过外部文件和使用DOM附加行为来包含javascript
1.3.2、解耦CSS/javascript
就是说尽量是通过class名来控制样式,而不是在js里面书写样式。这样如果大量用js来改样式,维护上来说将是一场噩梦。
例如:
// bad element.style.color="red"; //good element.className="edit";
1.3.3、解耦应用逻辑 / 事件处理程序
就是说 将应用逻辑 和事件处理程序相分离 ,这样两者分别处理各自的东西。如下:
//bad function handlekeyPress(event){ event=EventUtil.getEvent(event); if(event.keyCode==13){ var target=EventUtil.getTarget(event); var value=5*parseInt(target.value); if(value>10){ document.getElementById("error-msg").style.display="block"; } } } // good function validateValue(value){ var value=5*parseInt(value); if(value>10){ document.getElementById("error-msg").style.display="block"; } } function handlekeyPress(event){ event=EventUtil.getEvent(event); if(event.keyCode==13){ var target=EventUtil.getTarget(event); validateValue(target.value) } }
1.4 编程实践
1.4.1避免全局变量:
// bad 两个全局变量,避免 var name="Nicholas"; function sayName(){ alert(name); } // good 一个全局变量,推荐 var MyApplication={ name:"Nicholas", sayName:function(){ alert(this.name); } }
或者
// 如果变量和函数不需要在“外面”引用,可以写一个自执行函数 (function(){ var name = 'Nicholas'; function sayName(){ alert(name); } })();
1.4.2避免与null进行比较
// bad function sortArray(values){ if(values !=null){ values.sort(comparator); } } //good function sortArray(values){ if(values instanceof Array){ values.sort(comparator); } }
2、性能
2.1注意作用域,使用全局查找要比局部查找开销大很多
// bad //包含了三个对于全局document对象的引用。如果很多次,影响性能 function updateUI(){ var imgs=document.getElementsByTagName('img'); for(var i=0,len=imgs.length;i<len;i++){ imgs[i].title=document.title+"image"+i; } var msg=document.getElementById('msg'); mgs.innerHTML="Update complete ."; } // good //将document对象存在本地的doc中,然后在余下的代码中替换原来的document,只需要一次全局查找 function updateUI(){ var doc=document; var imgs=doc.getElementsByTagName('img'); for(var i=0,len=imgs.length;i<len;i++){ imgs[i].title=doc.title+"image"+i; } var msg=doc.getElementById('msg'); mgs.innerHTML="Update complete ."; }
2.2 选择正确的方法:
2.2.1. 避免不必要的属性查找
计算机算法的复杂度使用O来表示,其中最简单,最快捷的是O(1)。看下图
使用变量和数组要比访问对象上的属性更有效率前者是O(1)的操作,后者是一个 O(n)操作,
因为对象上的任何属性查找都要访问变量或者数组花费更长时间,因为必须在原型链中对拥有该名称的属性进行一次搜索。简而言之,属性查找越多,执行时间就越长。
例如:
//快 var value = 5; var sum = 10 + value; alert(sum); // 快 var values = [5, 10]; var sum = values[0] + values[1]; alert(sum); //较慢 var values = { first: 5, second: 10}; var sum = values.first + values.second; alert(sum);
2.2.2 Switch 语句较快
如果有一系列复杂的 if-else 语句,可以转换成单个 switch 语句则可以得到更快的代码。 还可以通过将 case 语句按照最可能的到最不可能的顺序进行组织, 来进一步优化 switch 语句
2.2.3 最小化语句数
有个地方很多开发人员都容易创建很多语句,那就是多个变量的声明。很容易看到代码中由多个
var 语句来声明多个变量
然而,在 JavaScript 中所有的
变量都可以使用单个 var 语句来声明。
但是个人倾向于第一种写法。
//4 个语句 —— 很浪费 var count = 5; var color = "blue"; var values = [1,2,3]; var now = new Date(); //一个语句 var count = 5, color = "blue", values = [1,2,3], now = new Date(); //但是为了更好的维护,还是第一种写法比较好。而且不会那么容易出错。 //所以支持第一种写法
使用数组和对象字面量
// bad //用 4 个语句创建和初始化数组——浪费 var values = new Array(); values[0] = 123; values[1] = 456; values[2] = 789; //用 4 个语句创建和初始化对象——浪费 var person = new Object(); person.name = "Nicholas"; person.age = 29; person.sayName = function(){ alert(this.name); }; // good //只用一条语句创建和初始化数组 var values = [123, 456, 789]; //只用一条语句创建和初始化对象 var person = { name : "Nicholas", age : 29, sayName : function(){ alert(this.name); } };
2.2.4 在For语句之外声明变量
// bad // 每次迭代都需要检查数组的长度,并且每次都要遍历DOM树找到container元素—效率低 for(var i = 0; i < someArray.length; i++) { var container = document.getElementById('container'); container.innerHtml += 'number: ' + i; console.log(i); } // good var container = document.getElementById('container'); for(var i = 0, len = someArray.length; i < len; i++) { container.innerHtml += 'number: ' + i; console.log(i); }
2.2.5 构建字符串的最快方式
// 这个方法比使用for更快 var arr = ['item 1', 'item 2', 'item 3', ...]; var list = '<ul><li>' + arr.join('</li><li>') + '</li></ul>';
2.3 压缩
2.3.1 文件压缩
原则:
删除额外的空白(包括换行) ;
删除所有注释;
缩短变量名。
JavaScript 有不少压缩工具可用其中最优秀的(有争议的)是 YUI 压缩器 http://yuilibrary.com/
检测js代码是否有错的工具:JSLint www.jslint.com
总结下来,发觉自己平时没有好好遵守这些规范,慢慢纠正