《编写高质量代码188个建议》读书笔记
2014-05-05 22:43 臭小子1983 阅读(298) 评论(0) 编辑 收藏 举报第一章 JavaScript语言基础
一、代码的执行速度决定的因素是:
1、代码量少,运行速度不一定快 2、代码量多,速度也不一定慢
建议1:警惕Unicode代码
javascript代码每个字符都两字节,这样函数名和变量名都可以使用中文来命名
1 <script> 2 var 人名 = "张三"; 3 console.log(人名); 4 5 function 技术(开发){ 6 console.log(开发); 7 } 8 9 技术("哈哈"); 10 </script>
建议2:辨析js语句中的词、句和段
建议3:减少全局变量污染
定义全局变量的3种方式:
1、在函数外面直接执行var 语句。 var f = 'value';
2、直接添加到window对象上。 window.f = 'value';
3、不使用var声明的变量。 f = value
避免全局变量的方法:
1 // 没有一个全局变量 2 (function(w){ 3 function getColor(){ 4 // 执行代码 5 } 6 7 getColor(); 8 })(window); 9 10 // 使用命名空间 11 var RRG = RRG || {}; 12 RRG.DOM = { 13 // 处理DOM 14 } 15 16 RRG.Event = { 17 // 处理Event 18 }
建议4:注意javascript数据类型的特殊性
1、防止浮点溢出:
二进制的浮点不能正确的处理十进制的小数, num = 0.1 + 0.2; // num不等于0.3
整数运算是精确的所以可以改写成: num = (1+2)/10; // 返回0.3
2、正确测数据类型:
js有六个类型:number、string、boolean、object、function、undefined
typeof null返回"object",而不是null、解决方法:
1 function type(o){ 2 return (o === null) ? "null" : typeof o; 3 }
3、避免误用parseInt
parseInt是将字符串转成整型
parseInt("123abc"); // 123
parseInt("1.73"); // 1
parseInt(".73"); // NAN
parseInt("010"); // 字符串第一个字符为0以八进制来求值,返回8 parseInt("0x10"); // 十六进制,返回16
parseInt("08"); // IE内核下返回0,因为以八进制
解决方法:
parseInt("08", 10); // 返回8
4、正确处理js特殊值
1、NaN:NaN是一个特殊的数量值,它不表示一个数字,尽管下面表达式返回true。
type NaN === "number"; // true;
NaN === NaN // false
isNaN(NaN); // true;
2、Infinity:表示无穷大
3、null和undefinded
五种基本类型:string、number、boolean、null和undefined
null:表示一个对象为空或不存在对象引用
undefined:当一个变量没有值的时候会返回undefined
console.log(null == undefined); // true;
console.log(null === undefined); // false;
建议5:谨慎使用运算符
1、用===,不用==
0 == "0"; // true;
0 === "0"; // false
建议6:养成优化表达式的思维方式
1、加小括号:
if(a+b > b && a-b < c || a>b>c) 改写成 if( (a+b > b) && (a-b < c) || (a>b>c))
2、使用if分解
var a.b = new c(a.d ? a.e(1) : a.f(1))
改写成:
var a.b;
if(a.d){
a.b = new c(a.e(1));
}
else{
a.b = new c(a.f(1));
}
建议7:使用查表法提高条件检测的性能
当有大量离散值需要测试时,switch要比if快的多
1 <script> 2 switch(value){ 3 case 0: 4 return result0; 5 break; 6 case 1: 7 return result1; 8 break; 9 case 2: 10 return result2; 11 break; 12 case 3: 13 return result3; 14 break; 15 default: ; 16 } 17 18 // 可以改写成 19 var arr = [result0, result1, result2, result3]; 20 return arr[value]; 21 </script>
建议33:优化循环结构
1、结构优化
循环一般与条件判断句语混在一起
1 var a = true; 2 for(var i=0; i<10000; i++){ 3 if(a){ 4 // code... 5 } 6 } 7 8 // 改写成 9 if(a){ 10 for(var i=0; i<10000; i++){ 11 // code... 12 } 13 }
2、避免不必要的重复操作
1 <script> 2 for(var i=0; i<10000; i++){ 3 var arr = [1, 2, 3, 4, 5, 6]; 4 alert(arr); 5 } 6 7 // 改写成 8 var arr = [1, 2, 3, 4, 5, 6]; 9 for(var i=0; i<10000; i++){ 10 alert(arr); 11 } 12 </script>
3、妥善定义循环变量
1 <script> 2 var s = 0; 3 for(var i= 0, s=20; i< s; i++){ 4 // code... 5 } 6 </script>
第二章 字符串、正则表达式和数组
合并、分解、搜索、遍历以及其它的字符串处理方式
建议36:获取字符有多少字节
字符有单字节和双字节,charCodeAt > 255 为双字节,也就是汉字为双字符字母和数字和特殊符号都为单字节
1 <script> 2 var str = "soaear"; 3 var n = 0; 4 5 for(var i=0; i<str.length; i++){ 6 if(str.charCodeAt(i) > 255){ 7 n += 2; 8 } 9 else{ 10 n++; 11 } 12 } 13 14 // 使用正则 15 for(var i=0; i<str.length; i++){ 16 var t = str.charAt(i); 17 if(/^[\u0000-\u00ff]$/.test(t)){ 18 n++; 19 } 20 else{ 21 n += 2; 22 } 23 } 24 </script>
建议37:推荐使用replace()
var b = s.replace("html", "htm"); // 将所有的html字符替换成htm
另外还有
search():搜索所在的位置,如果没有返回-1
test():如果存在返回true,否则返回false
match():如果存在以数组返回,否则返回null
建议37:使用splice删除数组
1 <script> 2 var arr = [1, 2, 3, 4, 5, 6]; 3 4 // 参数1:开始位置 参数2:结束位置 参数3:要替换的字符 5 var ss = arr.splice(3,5); // 返回 [4, 5] 6 console.log(ss); 7 </script>
建议38:数组的排序使用sort
1 <script> 2 var arr = [200,1,20,3,19, 30,12,359, 402, 33, 47,3595]; 3 4 // 从大到小排序 5 arr.sort(function(a,b){ 6 return a - b; // 从小到大排序 7 }) 8 console.log(arr); 9 10 // 奇偶排序 11 arr.sort(function(a, b){ 12 a = a % 2; 13 b = b % 2; 14 if(a == 0) { return -1 } 15 if(b == 0) { return 1 } 16 }) 17 console.log(arr); // 返回[12, 20, 30, 200, 402, 1, 3, 47, 3595, 359, 19, 33] 18 </script>
第五章 DOM编程
减少ECMAScript对DOM的操作
建议107:应清理HTML DOM流程
HTML DOM文档加载是按顺序执行的,与浏览器的渲染方式有关系,一般浏览器的渲染操作:
1、解析HTML结构
2、加载外部脚本和样式
3、解析并执行脚本
4、构造DOM模型
5、加载外部图片等外部文件
6、页面加载完成
建议108:谨慎访问DOM
修改一个DOM元素会消耗性能,因为会导致页面的重排重绘,特别是循环时访问DOM元素
1 <script> 2 for(var i= 0, len=1000; i<len; i++){ 3 document.getElementById("box").innerHTML = i; 4 } 5 6 // 可以改写成 7 var conut = 0; 8 for(var i= 0,len=1000; i<len; i++){ 9 conut += i; 10 } 11 document.getElementById("box").innerHTML = conut; 12 </script>
建议109:比较innerHTML与DOM创建元素方法createElement
innerHTML要比DOM创建元素的方法要快一些
建议111:克隆节点比创建节点更好
element.cloneNode()代替document.createElement()
克隆比较有效率,但提高并不太多
建议113:用局部变量访问集合元素
1 <script> 2 // 比较慢的方法 3 function collection(){ 4 var coll = document.getElementsByTagName("div"), len = coll.length, name = ""; 5 for(var i=0; i<len; i++){ 6 name = document.getElementsByTagName("div")[i].nodeName; 7 name = document.getElementsByTagName("div")[i].nodeType; 8 name = document.getElementsByTagName("div")[i].tagName; 9 } 10 return name; 11 } 12 13 // 较快的方法 14 function collection(){ 15 var coll = document.getElementsByTagName("div"), len = coll.length, name = ""; 16 for(var i=0; i<len; i++){ 17 name = coll[i].nodeName; 18 name = coll[i].nodeType; 19 name = coll[i].tagName; 20 } 21 return name; 22 } 23 24 // 最快的方法 25 function collection(){ 26 var coll = document.getElementsByTagName("div"), len = coll.length, name = "", el = null; 27 for(var i=0; i<len; i++){ 28 el = coll[i]; 29 name = el.nodeName; 30 name = el.nodeType; 31 name = el.tagName; 32 } 33 return name; 34 } 35 </script>
建议117:减少重绘、重排
改变了宽度、高度、定位边框、内边距等,都会使元素重排.
改变颜色不会影响到宽、高这样只会完成重绘
一、发生重排:
1、添加、删除可见的DOM元素
2、元素的位置改变
3、元素的尺寸改变,(边距、填充、边框宽度、宽度高度)
4、内容的改变,如图片或文字所被另一个图片文字所代替
5、最初的页面渲染
6、浏览器窗口尺寸的改变
建议118:DOM将事件拖管
第六章 客户端编程
建议123:比较IE和W3C事件流
IE支持冒泡事件,非IE支持的是捕获事件.
<p onclick="aa()"></p>
冒泡事件为:事流程流为p-body-html-document-window
捕获事件为:window-document-html-body-p
建议127:妥善使用DOMContentOnloaded事件
load事件是需要等到页面中的图片全部都加载完成后才会触发,而DOMContentOnloaded事件是DOM文档加载完成后就会被触发
1 <img src="http://c.hiphotos.baidu.com/image/pic/item/9f510fb30f2442a7abf0bc2dd343ad4bd01302bf.jpg"> 2 3 <script> 4 window.addEventListener("load", function(){ 5 console.log("页面初始化完成"); 6 }, false); 7 8 window.addEventListener("DOMContentLoaded", function(){ 9 console.log("DOM树已加载完成"); 10 }, false); 11 </script>
建议129:自定义事件
第七章 数据交互和存储
建议147:ajax性能向导
有两种方法避免发出一个不必要的请求:
1、在服务器,设置HTTP头,确保返回的报文将被缓存在浏览器中.
2、在客户端,对于本地缓存已获取的数据,不要多次请求同一数据.
Expires头设置:
建议149:警惕基于DOM的跨域侵入
1、基于DOM跨域脚本编制
XSS跨站脚本攻击,攻击者向web页面插入恶意代码,然后提交给服务器,
2、通过URL重定向钓鱼
网络钓鱼表示通过欺骗手段窃取用户个人信息,常见的是通过URL重定向钓鱼漏洞行为方式
3、客户端Javascript cookie引用
4、javascript脚本劫持