代码改变世界

深入了解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()你可以从字符串中获取数值,该方法接受另一个基数参数,这经常省略,但不应该。要加上第二个参数:转化的进制

不要扩展内置原型

要使用 === 和 !== 不要使用 == 和 !=