JavaScript循环之for/in循环
今天学到了JavaScript的语句篇。同其他常见编程语言如C、Java等一样,JavaScript中的语句包含:①表达式语句②复合语句和空语句③声明语句④条件语句⑤循环语句⑥跳转语句,当然JavaScript还有⑦其他三种语句。那么标题叫做JavaScript循环之for/in循环,主要是因为我觉得这里面大多语句跟C、Java那些一样,没必要再浪费口舌介绍了,但for/in循环是第一次在JavaScript中接触的。当然,这些都是非常基础的内容,只是做为学习笔记,初学JavaScript可以看看,熟练掌握的就不必再浪费时间阅读了。
首先,先说下稍微有点特殊性的空语句吧。空语句只有一个分号即: ; ,很简单,令人不禁要想有毛用? 。曾经听说过:世界上任何事物如果存在,必有它存在的原因。空语句也不例外,它还是有点作用滴。JavaScript解释器执行空语句时它显然不会执行任何动作。但实践证明,当创建一个具有空循环体的循环时,空语句有时很有用。例如:
//初始化一个数组a
for(var i=0; i<a.length; a[i++]=0) ;
在这个循环中,所有操作都在表达式a[i++]=0中完成,并不需要任何循环体,然而JavaScript需要循环体中至少要包含一条语句,因此这里用了空语句。当然这个也可以用while循环实现,只是这个简洁了点而已。
空语句目测也就那点作用了。至于JavaScript中的声明语句,那肯定得详细说说变量声明提前特性了啊,这是JavaScript的一个重点啊,很抱歉这里就不详说了,如果想要了解,请点击:http://www.cnblogs.com/craftsman-gao/p/4720635.html 。条件语句中,if 和else if 也都跟C、Java一样,就不多废话了,switch 语句倒是有一个容易忽略的知识点。当执行switch语句时,首先计算switch后括号中的表达式的值,然后查找case子句的表达式的值是否和switch后面括号中表达式的值相同,来进行匹配,重点是:这里比较两个表达式的值是否相同时使用的是完全相等,即"===" 。
好了,现在到真正要说的循环语句了。JavaScript中的循环有四种,:while、do/while、for 和 for/in。前三种也是没啥特点,所以就直接说for/in了。先看其语法:
1 for(variable in object)
2 statement
variable通常是一个变量名,也可以是一个可以产生左值的表达式或者一个通过var 语句声明的变量,总之必须是一个适合用于赋值表达式左侧的值。object是一个表达式,这个表达式的计算结果是一个对象。同样,statement 是一个语句或语句块,它构成了循环的主体。使用for/in循环可以很方便的遍历对象属性成员:
1 for(var p in o)
2 console.log(o[p]);
在执行for/in语句过程中,JavaScript解释器首先计算object表达式。如果表达式为null 或者 undefined , JavaScript解释器将会跳过循环并执行后续代码。如果表达式等于一个原始值,这个原始值将会转换成与之对应的包装对象。否则,表达式本身已经是对象了。JavaScript会依次枚举对象的属性来执行循环。在每次循环之前,JavaScript都会将对象的一个属性名(一个字符串)赋值给variable。
需要注意的是,只要for/in循环中variable的值可以当做赋值表达式的左值,它可以是任意表达式。例如,可以使用下面这段代码把所用对象属性复制到一个数组中:
1 var o = {x:1, y:2, z:3};
2 var a =[], i=0;
3 for(a[i++] in o) ;//注意这里就用了空语句
因为,JavaScript数组是一种特殊的对象,因此,for/in循环可以像枚举对象属性一样枚举数组索引。例如:
1 for(var i in arr)
2 console.log(i);//依次输出数组的索引值
注意:for/in循环并不会遍历对象的所有属性,只有“可枚举(enumerable)”的属性才会遍历到(这一点是对象的内容了,以后再做详说吧)。由JavaScript语言核心所定义的内置方法就不是“可枚举的”。比如,所有的对象都有方法toString(),但for/in循环并不枚举toString这个属性。除了内置方法之外,还有很多内置对象的属性也是“不可枚举的“。而代码中定义的所有属性和方法是可枚举的。对象可以继承其他对象的属性,那些继承的自定义属性也可以使用for/in枚举出来。关于属性枚举的顺序,ECMAScript规范并没有指定,主流浏览器厂商的JavaScript实现是按照属性定义的先后顺序来枚举简单对象的属性,先定义的属性先枚举。如果使用对象直接量的形式创建对象,则将按照直接量中属性出现顺序枚举。
还有两点需要注意:a.如果for/in的循环体删除了还未枚举的属性,那么这个属性将不会再枚举到;b.如果循环体定义了对象的新属性,这些属性通常也不会枚举到;
另外的三种语句就是:①with②debugger(用于调试程序时给程序打断点)③"use strict"。不过这里先暂且不说这三个了。
[新增(2105.09.07)]今天在写比较两个对象的各个属性值是否完全相同时,发现for/in循环中,调用对象属性值只能使用[]运算符,并不能使用.运算符,不管是在遍历数组还是普通对象。又算是学习路上发现的一坑吧,这里记录下。
[新增(2105.09.011)]在使用for/in循环遍历对象的属性时。对象的hasOwnProperty()方法用来检测给定的名字是否是对象的自有属性,对于继承属性它将返回false,例如:。
1 var o = {x:1}; 2 o.hasOwnProperty('x'); //true: 对象o有一个自有属性x 3 o.hasOwnProperty('y'); //false:对象o不存在属性y 4 o.hasOwnProperty('toString'); //false:toString是继承属性