一、for each...in数组
使用一个变量迭代一个对象的全部属性值,对于每个属性值,有一个指定的语句块被执行.浏览器
做为ECMA-357(E4X)标准的一部分,for each...in语句已被废弃,E4X中的大部分特性已被删除,但考虑到向后兼容,for each...in只会被禁用而不会被删除,可使用ES6中新的for...of语句来代替.缓存
for each...in
是 ECMA-357 (E4X) 标准的一部分, 大部分非Mozilla浏览器都没有实现该标准, E4X并非 ECMAScript 标准的一部分.ide
语法函数
for each (variable in object) {
ui
statement
this
}
spa
参数prototype
variable
翻译
var
关键字是可选的.该变量是函数的局部变量而不是语句块的局部变量.
object
statement
{ ... }
) 将多条语句括住.
描述
一些对象的内置属性是没法被遍历到的,包括全部的内置方法,例如String对象的indexOf
方法.不过,大部分的用户自定义属性都是可遍历的.
示例
警告:永远不要使用for each...in语句遍历数组,仅用来遍历常规对象
下面的代码片断演示如何遍历一个对象的属性值, 并计算它们的和:
var sum = 0; var obj = {prop1: 5, prop2: 13, prop3: 8}; for each (var item in obj) { sum += item; } print(sum); // 输出"26",也就是5+13+8的值
摘自https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for_each...in
2.for...in
以任意顺序遍历一个对象的可枚举属性。对于每一个不一样的属性,语句都会被执行.
语法
for (variable in object) {...}
variable
object
for...in
循环只遍历可枚举属性。像 Array
和 Object
使用内置构造函数所建立的对象都会继承自Object.prototype
和String.prototype
的不可枚举属性,例如 String
的 indexOf()
方法或 Object
的toString()
方法。循环将遍历对象自己的全部可枚举属性,以及对象从其构造函数原型中继承的属性(更接近原型链中对象的属性覆盖原型属性)。
for...in
循环以任意序迭代一个对象的属性(请参阅delete
运算符,了解为何不能依赖于迭代的表面有序性,至少在跨浏览器设置中)。若是一个属性在一次迭代中被修改,在稍后被访问,其在循环中的值是其在稍后时间的值。一个在被访问以前已经被删除的属性将不会在以后被访问。在迭代进行时被添加到对象的属性,可能在以后的迭代被访问,也可能被忽略。一般,在迭代过程当中最好不要在对象上进行添加、修改或者删除属性的操做,除非是对当前正在被访问的属性。这里并不保证是否一个被添加的属性在迭代过程当中会被访问到,不保证一个修改后的属性(除非是正在被访问的)会在修改前或者修改后被访问,不保证一个被删除的属性将会在它被删除以前被访问。
for...in
提示:for...in
不该该用于迭代一个 Array
,其中索引顺序很重要。
数组索引只是具备整数名称的枚举属性,而且与通用对象属性相同。不能保证for ... in
将以任何特定的顺序返回索引。for ... in
循环语句将返回全部可枚举属性,包括非整数类型的名称和继承的那些。
由于迭代的顺序是依赖于执行环境的,因此数组遍历不必定按次序访问元素。所以当迭代访问顺序很重要的数组时,最好用整数索引去进行for
循环(或者使用 Array.prototype.forEach()
或 for...of
循环)。
若是你只要考虑对象自己的属性,而不是它的原型,那么使用 getOwnPropertyNames()
或执行 hasOwnProperty()
来肯定某属性是不是对象自己的属性(也能使用propertyIsEnumerable
)。或者,若是你知道不会有任何外部代码干扰,您可使用检查方法扩展内置原型。
下面的函数接受一个对象做为参数。被调用时迭代传入对象的全部可枚举属性而后返回一个全部属性名和其对应值的字符串。
var obj = {a:1, b:2, c:3}; for (var prop in obj) { console.log("obj." + prop + " = " + obj[prop]); } // Output: // "obj.a = 1" // "obj.b = 2" // "obj.c = 3"
下面的函数说明了hasOwnProperty()
的用法:继承的属性不显示。
var triangle = {a: 1, b: 2, c: 3}; function ColoredTriangle() { this.color = 'red'; } ColoredTriangle.prototype = triangle; var obj = new ColoredTriangle(); for (var prop in obj) { if (obj.hasOwnProperty(prop)) { console.log(`obj.${prop} = ${obj[prop]}`); } } // Output: // "obj.color = red"
摘自https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...in
3.for...of
在可迭代对象(包括 Array
,Map
,Set
,String
,TypedArray
,arguments 对象等等)上建立一个迭代循环,调用自定义迭代钩子,并为每一个不一样属性的值执行语句。
for (variable of iterable) { //statements }
variable
iterable
Array
let iterable = [10, 20, 30]; for (let value of iterable) { value += 1; console.log(value); } // 11 // 21 // 31
若是你不想修改语句块中的变量 , 也可使用const
代替let
。
let iterable = [10, 20, 30]; for (const value of iterable) { console.log(value); } // 10 // 20 // 30
String
let iterable = "boo"; for (let value of iterable) { console.log(value); } // "b" // "o" // "o"
TypedArray
let iterable = new Uint8Array([0x00, 0xff]); for (let value of iterable) { console.log(value); } // 0 // 255
Map
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]); for (let entry of iterable) { console.log(entry); } // ["a", 1] // ["b", 2] // ["c", 3] for (let [key, value] of iterable) { console.log(value); } // 1 // 2 // 3
Set
let iterable = new Set([1, 1, 2, 2, 3, 3]); for (let value of iterable) { console.log(value); } // 1 // 2 // 3
arguments
对象(function() { for (let argument of arguments) { console.log(argument); } })(1, 2, 3); // 1 // 2 // 3
迭代 DOM 元素集合,好比一个NodeList
对象:下面的例子演示给每个 article 标签内的 p 标签添加一个 "read
" 类。
//注意:这只能在实现了NodeList.prototype[Symbol.iterator]的平台上运行 let articleParagraphs = document.querySelectorAll("article > p"); for (let paragraph of articleParagraphs) { paragraph.classList.add("read"); }
对于for...of
的循环,能够由break
, throw
或return
终止。在这些状况下,迭代器关闭。
function* foo(){ yield 1; yield 2; yield 3; }; for (let o of foo()) { console.log(o); break; // closes iterator, triggers return }
你还能够迭代一个生成器:
function* fibonacci() { // 一个生成器函数 let [prev, curr] = [0, 1]; for (;;) { // while (true) { [prev, curr] = [curr, prev + curr]; yield curr; } } for (let n of fibonacci()) { console.log(n); // 当n大于1000时跳出循环 if (n >= 1000) break; }
生成器不该该重用,即便for...of
循环的提早终止,例如经过break
关键字。在退出循环后,生成器关闭,并尝试再次迭代,不会产生任何进一步的结果。
var gen = (function *(){ yield 1; yield 2; yield 3; })(); for (let o of gen) { console.log(o); break;//关闭生成器 } //生成器不该该重用,如下没有意义! for (let o of gen) { console.log(o); }
你还能够迭代显式实现可迭代协议的对象:
var iterable = { [Symbol.iterator]() { return { i: 0, next() { if (this.i < 3) { return { value: this.i++, done: false }; } return { value: undefined, done: true }; } }; } }; for (var value of iterable) { console.log(value); } // 0 // 1 // 2
摘自https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of