JavaScript学习(2):对象、集合以及错误处理
在这篇文章里,我们讨论一下JavaScript中的对象、数组以及错误处理。
1. 对象
对象是JavaScript中的一种基本类型,它内部包含一些属性,我们可以对这些属性进行增删操作。
1.1 属性
JavaScript中的值,有时会包括一些与其相关联的值,这些相关联的值,我们称之为属性。
访问属性
下面是一个非常简单的示例:
1 var a = "this is test"; 2 print("type of a:" + typeof a); 3 print(a["length"]); 4 print(a.length); 5 6 //输出结果 7 type of a:string 8 12 9 12
上述代码中,第3行和第4行的作用是一样的,都是输出a的长度。我们可以看到a是string类型的变量,它包含了一个名为length的属性,这个属性可以返回字符串的长度。当需要调用属性时,我们可以使用"变量名[属性名称]"的方式,也可以使用“变量名.属性名称”的方式。后者是前者的一个简写形式。
但是当属性命名以数字等开头时,我们只能以“[]”的形式来引用,例如:
1 var temp={"1":"a", "2":"b", "3":"c"}; 2 print(temp["1"]); 3 //print(temp.1);
上述代码最后一行如果不注释掉,就会发生错误,因为“1”不符合JavaScript变量的命名规则。
在JavaScript中,对象由一个属性集合构成,每个属性的值还可以是一个属性集合,以此类推。
删除属性
当我们试图访问一个不存在的属性时,会返回undefined,我们可以通过delete操作来删除。另外我们可以使用in操作来判断属性是否存在。
来看下面的示例:
1 var temp={"1":"a", "2":"b", "3":"c"}; 2 print(temp["1"]); 3 print("\'1\' in temp:" + ("1" in temp)); 4 delete temp["1"]; 5 print(temp["1"]); 6 print("\'1\' in temp:" + ("1" in temp)); 7 8 //输出结果 9 a 10 '1' in temp:true 11 undefined 12 '1' in temp:false
可以看到,在使用了delete操作后,属性已经被删除了。
遍历属性
对于我们在程序中添加的属性,是可以通过循环的方式进行遍历的:
1 var temp={"1":"a", "2":"b", "3":"c"}; 2 for(var name in temp){ 3 print("temp["+name+"]="+temp[name]) 4 } 5 print(temp); 6 7 //输出结果 8 temp[1]=a 9 temp[2]=b 10 temp[3]=c 11 [object Object]
非常有意思的是直接print对象时,输出的是[object,object]。
1.2 修改对象
JavaScript中也有值类型和引用类型之分,我们可以通过修改对象中属性的值来改变对象。
来看下面的示例:
1 var a={"start":10}; 2 var b=a; 3 var c={"start":10}; 4 print("a==b:" + (a==b)); 5 print("a==c:" + (a==c)); 6 print("a.start:" + a.start); 7 print("b.start:" + b.start); 8 print("c.start:" + c.start); 9 a.start=20; 10 print("a.start:" + a.start); 11 print("b.start:" + b.start); 12 print("c.start:" + c.start); 13 14 //输出结果 15 a==b:true 16 a==c:false 17 a.start:10 18 b.start:10 19 c.start:10 20 a.start:20 21 b.start:20 22 c.start:10
2. 数组
我们可以把对象看做是一个实体模型,它内部包含的信息作为属性存在。如果需要表示多个实体模型时,我们可以考虑使用集合。
我们使用"[]"来定义数组,来看下面的示例:
1 function arrayTest(){ 2 var temp=["a","b","c"]; 3 temp.push("d"); 4 temp.push("e"); 5 for(var i = 0; i < temp.length; i++){ 6 print(temp[i]); 7 } 8 } 9 10 //输出结果 11 a 12 b 13 c 14 d 15 e
我们有两种方式向数组中添加元素:1)初始化数组时;2)使用push方法。
我们可以使用join方法将数组转换成一个字符串,也可以使用split方法将一个字符串转换成字符串数组,如下:
1 var temp=["a","b","c"]; 2 temp.push("d"); 3 temp.push("e"); 4 print(temp.join(" ")); 5 print(temp); 6 var a="a b c d e"; 7 print(a.split(" ")); 8 9 //输出结果 10 a b c d e 11 a,b,c,d,e 12 a,b,c,d,e
可以看到当我们直接print数组时,它输出了数组中的每一个元素,但我们print对象时,它并没有输出对象中的属性。
3. 错误处理
在编写程序时发生的错误可以分为两类:程序员错误和运行时错误。
对于程序员错误的处理策略,我们通常是期望程序尽快出错,这样可以弄清楚哪里出了问题。同时我们也可以采取防御性编程,例如添加输入检查。
对于运行时错误,我们应该尽量对错误进行处理,例如回滚,尽量避免程序崩溃。
3.1 处理错误的方式
在JavaScript中,我们有几种方式可以用来处理错误。
返回特殊值
对于不符合业务逻辑的输入,我们可以返回一个特殊值,例如undefined,这样可以提示用户方法的返回值是不正常的。
例如我们在JavaScript学习(1):基础中提到的学习成绩分类的示例,对于输入的分数大于100或者小于0的情况,明显不符合正常的业务,我们可以返回undefined。
这种错误处理方式的坏处:1)如何确定特殊的返回值,如果undefined在某种情况下也是正常业务的返回值,那么我们如何处理?2)需要函数的调用方知道特殊的返回值,并且在每次调用的时候,对特殊返回值进行处理。
异常
我们可以通过throw、try...catch的方式来实现异常处理,下面是一个简单示例:
1 function divide(a,b){ 2 if (b == 0) throw "can not divide 0"; 3 return a/b; 4 } 5 6 function errorTest(){ 7 try{ 8 divide(1,0); 9 } 10 catch(error){ 11 print("error occurs:" + error); 12 } 13 } 14 15 16 //输出结果 17 error occurs:can not divide 0
我们可以自定义Error对象,这样在catch时,可以更加细化的处理指定的异常。如下示例:
1 var zeroError = new Error("can not divide 0"); 2 3 function errorTest(){ 4 try{ 5 throw new Error("test"); 6 divide(1,1); 7 } 8 catch(error){ 9 if (error==zeroError){ 10 print("error occurs:" + error.message); 11 } 12 else{ 13 print(error.message); 14 } 15 } 16 } 17 18 //输出结果 19 test
我们可以在catch后面添加finally语句,和Java一样,可以在finally语句中释放资源,恢复业务状态等操作。