var o = {x: 1,y: 2,z: 3};
var a = [],i = 0;
for (a[i++] in o) /*empty*/;
document.write(a)//=> x,y,z
javascript数组只不过是一种特殊的对象,因此,for/in循环可以像枚举对象属性一样枚举数据索引。例如在上面的代码之后添加这段代码,就可以枚举数据索引0,1,2:
复制代码 代码如下:
var o = {x: 1,y: 2,z: 3};
var a = [],i = 0;
for (a[i++] in o) /*empty*/;
document.write(a)//=> x,y,z将对象属性复制到一个数组中
for(i in a)
document.write(i) //=>枚举数据索引 0 1 2
其实,for/in循环并不会遍历对象的所有属性,只有“可枚举”(enumerable)的属性才会遍历到(参照6.7)。由于javascript语言核心所定义的内置方法就不是“可枚举的”。比如,所有的对象都有toString(),但for/in循环并不枚举toString()这个属性。除了内置的方法之外,还有很多内置对象的属性是不可枚举的(nonenumberable)。而代码中定义的所有属性和方法都是可枚举的(6.7节会讲到,但ECMAScript5中有特殊手段可以使属性变为不可枚举)。
对象可以继承其它对象的属性,那行继承自定义属性(6.2.ii)也可以使用for/in枚举出来。
如果for/in的循环体删除了还未枚举的属性,那么这个属性将不会再枚举。如果循环体定义了对象的 新属性,这些属性通常也不会枚举到(不过。javascript有些实现可以枚举那么些在循环体中增加的属性)。
属性枚举的顺序
ECMAScript规范并没有指定for/in循环按照何种顺序来枚举对象的属性。但实际上,主流的浏览器厂商javascript实现是按照属性定义的先后顺序来枚举简单对象的属性,先定义的属性先枚举。如果使用对象直接量的形式创建对象,则将按照直接量中属性的出现顺序枚举。(有一些网和javascript库是依赖这种枚举顺序的,而浏览器厂商大多不修改这个顺序),在下面的情况下,枚举顺序取决于具体的实现(并非交互)
1.对象继承了可枚举属性
2.对象具有整数数组索引的属性
3.使用delete删除了对象已有的属性
4.使用Object.defineProperty()或者类似的方法改变了对象属性
6.跳转
javascript中令一类语句是跳转语句(jump statement)。从语句理解,它可以使javascript执行从一个位置跳转到令一个位置。
break语句是跳转到循环或其他的语句结束。continue语句是终止本次循环的执行并开始下一次循环的执行。javascript中的语句可以命名或带有标签,break和continue可以标识目标循环或者其它语句标签。
return语句可以让解释器跳出函数体的执行。并提供本次调用的返回值。throw语句触发或者抛出一个异常,它是与try/catch/finally语句一同使用的,这些语句指定了处理异常代码逻辑。这是一种复杂的跳转语句,当抛出一个异常的时候,程序将跳至最近的闭合异常辰星,这个异常程序可以是在同一个函数中或者更高层的调用栈中。
接下来,描述每一种跳转语句
i.标签语句
语句是可以添加标签的,标签是由语句前的标识符和冒号组成:
identifier:statement
通过给语句定义标签,就可以在程序中任何地方通过标签名来引用这条语句。可以对多条语句定义标签,尽管只有给语句块定义标签时它才有更有用,比如循环语句或条件判断语句。通过给循环定义一个标签名,可以在循环体内部使用break和continue来退出循环或者直接挑战到下一个循环开始。break和continue是javascript中唯一可使用语句标签的语句(本章接下来会讲述)。下面的例子,其中while循环定义了一个标签,continue语句使用了这个标签:
复制代码 代码如下: