For each...in / For...in / For...of 的解释与例子

时间:2022-05-13 16:38:07

1、For each...in

for each...in 语句在对象属性的所有值上迭代指定的变量。对于每个不同的属性,执行一个指定的语句。

语法:

for each (variable in object) {
statement
}

variable:

变量,以迭代属性值,可以选择用var关键字声明。这个变量是函数的局部变量,而不是循环的局部变量。

object:

对象,该对象迭代属性。

statement:

为每个属性执行的语句。要在循环中执行多个语句,使用block语句({…)来对这些语句进行分组。

描述:

一些内置属性没有迭代。这些方法包括对象的所有内置方法,例如String的indexOf方法。然而,所有用户定义的属性都被迭代。
 
警告:不要在数组中使用这样的循环。只在对象上使用。
 
下面的代码片段迭代对象的属性,计算它们的和:
var sum = 0;
var obj = {prop1: 5, prop2: 13, prop3: 8}; for each (var item in obj) {
sum += item;
} console.log(sum); // logs "26", which is 5+13+8

2、For...in

for...in 语句遍历对象的所有非符号可枚举属性。

语法:

for (variable in object) { ...
}

variable:

在每次迭代中都为变量分配不同的属性名。

object:

对象,其非符号可枚举属性被迭代。

描述:

一个 for...in 循环只迭代可枚举的非符号属性。从数组和对象等内置构造函数创建的对象从对象继承了不可枚举的属性。原型和字符串。原型,例如String的indexOf()方法或Object的toString()方法。循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型继承的那些属性(靠近原型链中的对象的属性将覆盖原型的属性)。

Deleted, added, or modified properties:

一个for...in循环以任意顺序迭代对象的属性(请参阅delete操作符,以了解为什么不能依赖于看起来的迭代顺序,至少在跨浏览器设置中是这样)。

如果一个属性在一次迭代中被修改,然后在稍后的时间访问,它在循环中的值就是它在以后的时间的值。在访问之前被删除的属性以后将不会被访问。添加到正在进行迭代的对象中的属性可以被访问,也可以从迭代中省略。

通常,最好不要添加、修改或删除属性。

Array iteration and for...in:

注意:for…in不应该用于遍历索引顺序很重要的数组。

数组索引只是具有整数名称的可枚举属性,否则与一般对象属性相同。不能保证for…in将以任何特定顺序返回索引。for…循环语句将返回所有可枚举的属性,包括具有非整数名称的属性和继承的属性。

因为迭代的顺序与实现相关,所以在数组上迭代可能不会以一致的顺序访问元素。因此,最好使用带有数值索引的for循环。

只迭代自己的属性:

如果您只想考虑附加到对象本身的属性,而不是它的原型,那么使用getOwnPropertyNames()或执行hasOwnProperty()检查(也可以使用propertyIsEnumerable)。或者,如果您知道不会有任何外部代码干扰,您可以使用check方法扩展内置原型。

例子:

下面的函数将对象作为其参数。然后它遍历对象的所有可枚举的非符号属性,并返回一个属性名称及其值的字符串。var obj = {a: 1, b: 2, c: 3};

for (const 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 (const prop in obj) {
if (obj.hasOwnProperty(prop)) {
console.log(`obj.${prop} = ${obj[prop]}`);
}
} // Output:
// "obj.color = red"

3、For...of

for...of 语句创建一个循环遍历可迭代对象(包括内置的字符串、数组,例如类数组参数或NodeList对象、TypedArray、Map和Set以及用户定义的迭代),调用一个定制的迭代钩子,并用语句执行对象的每个不同属性的值。

语法:

for (variable of iterable) {
statement
}

variable:

在每次迭代中,将不同属性的值赋给变量。

iterable:

对象,其可迭代属性被迭代。

例子:

迭代数组

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

遍历字符串:

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

迭代映射:

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

迭代一个集合:

let iterable = new Set([1, 1, 2, 2, 3, 3]);

for (let value of iterable) {
console.log(value);
}
// 1
// 2
// 3

迭代参数对象:

(function() {
for (let argument of arguments) {
console.log(argument);
}
})(1, 2, 3); // 1
// 2
// 3

查看更多例子请访问:https://devdocs.io/javascript/statements/for...of