深入了解javascript系列学习笔记(一):编写高质量JavaScript代码的基本要点
2013-04-03 14:56 极乐鸟 阅读(392) 评论(0) 编辑 收藏 举报代码维护成本比较高,所以要编写可维护的代码。下面分点介绍如何编写可维护的代码。
全局变量和局部变量
javascript通过函数来管理作用域。
在每个函数的外面可以通过this来访问全局对象。在浏览器中这个全局对象是window,即在全局作用域访问时:this === window
全局变量容易出现命名冲突,所以要尽量少使用全局变量。在声明变量的时候一定要使用var来声明,未经声明被使用的变量会成为全局变量,这种情况下生成的全局变量为隐式全局变量
隐式全局变量和明确定义的全局变量间有些小的差异,就是通过delete
操作符让变量未定义的能力。
- 通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的。
- 无var创建的隐式全局变量(无论是否在函数中创建)是能被删除的。
1 var a = 1; 2 b = 0; 3 //删除 4 delete a; 5 delete b; 6 //删除结果测试 7 console.log(typeof a);//number 8 console.log(typeof b);//undefined
在使用连等的方式来赋值的时候要格外注意:下面的函数中a是局部变量,b是全局变量
1 function test(){ 2 var a = b = {name:"syh"}; 3 } 4 test(); 5 console.log( typeof a);//udefinded 6 console.log(typeof b);//object
使用连等的方式来赋值的时候要使用下面的方式:先声明变量,再赋值
1 function test(){ 2 var a,b; 3 a = b = {name:"syh"}; 4 ... 5 }
当要声明多个变量的时候,尽量要使用一个var来声明:
var a = 0; var b = 1; var c = 2; //使用一个var来声明 var a = 0, b = 1, c = 2; //推荐使用 var a = 0 ,b = 1 ,c = 2;
javascript可以在函数的任意位置声明变量,但是这与在顶部声明变量在起同样的作用:从下面的例子可以看出,所声明的变量都被悬置到函数的顶部
1 var param = "test"; 2 (function(){ 3 console.log(param);//undefined 4 var param = "test1"; 5 console.log(param);//test1 6 }())
for循环 和 for-in循环
for循环一般用来作数组循环
// 次佳的循环 for (var i = 0; i < myarray.length; i++) { //... } //推荐方式 for (var i = 0,arrLength = myarray.length; i < arrLength ; i++) { // ... }
for-in
循环应该用在非数组对象的遍历上,使用for-in
进行循环也被称为“枚举”。虽然for-in循环也可用来遍历数组,但是不推荐这样做。
对象有一个hasOwnProperty()方法,可以用来过滤定义在原型上的属性和方法
// 对象 var man = { hands: 2, legs: 2, heads: 1 }; // 在代码的某个地方 // 一个方法添加给了所有对象 if (typeof Object.prototype.clone === "undefined") { Object.prototype.clone = function () {}; } // 1. // for-in 循环 for (var i in man) { if (man.hasOwnProperty(i)) { // 过滤 console.log(i, ":", man[i]); } } /* 控制台显示结果 hands : 2 legs : 2 heads : 1 */ // 2. // 反面例子: // for-in loop without checking hasOwnProperty() for (var i in man) { console.log(i, ":", man[i]); } /* 控制台显示结果 hands : 2 legs : 2 heads : 1 clone: function() */
另外一种使用hasOwnProperty()
的形式是过滤Object.prototype上的方法。像是:
(现在还没有理解)
1 for (var i in person) { 2 if (Object.prototype.hasOwnProperty.call(person, i)) { // 过滤 3 console.log(i, ":", person[i]); 4 } 5 } 6 //输出结果 7 /*name : syh 8 age : 10*/
其好处在于在person对象重新定义hasOwnProperty情况下避免命名冲突。也避免了长属性查找对象的所有方法,你可以使用局部变量“缓存”它。
var i, hasOwn = Object.prototype.hasOwnProperty; for (i in person) { if (hasOwn.call(person, i)) { // 过滤 console.log(i, ":", person[i]); } }
其他
避免使用eval();记住该咒语“eval()是魔鬼”。此方法接受任意的字符串,并当作JavaScript代码来处理。
// 反面示例 setTimeout("myFunc()", 1000); setTimeout("myFunc(1, 2, 3)", 1000); // 更好的 setTimeout(myFunc, 1000); setTimeout(function () { myFunc(1, 2, 3); }, 1000);
parseInt()你可以从字符串中获取数值,该方法接受另一个基数参数,这经常省略,但不应该。要加上第二个参数:转化的进制
不要扩展内置原型
要使用 === 和 !== 不要使用 == 和 !=