循环允许我们循环遍历数组或对象中的项目,并执行诸如打印、修改它们或执行其他类型的任务或动作之类的事情。JavaScript 中有不同种类的循环,其中一种是 for...in 循环。
在本文中,我们将了解 for...in JavaScript 提供的循环。我们将看看for...in
循环在 JavaScript 中是如何使用的、它的语法、它是如何工作的示例、何时使用它、何时不使用它,以及我们可以使用哪些其他类型的循环。
为什么使用循环 {#whyuseloops}
在 JavaScript 中,就像在其他编程语言中一样,我们使用循环来读取或访问集合中的项目。集合可以是数组或对象。每次遍历集合中的项称为一次迭代。
有两种方法可以访问集合中的项目。第一种方法是通过它在集合中的键,它是数组中的索引或对象中的属性。第二种方式是通过项目本身,而不需要密钥。
for...in 循环的定义 {#definitionoftheforinloop}
JavaScript for...in
循环遍历或迭代集合的键。使用这些键,您可以访问它在集合中表示的项目。
项目的集合可以是数组、对象,甚至是字符串。
for...in 循环的语法 {#syntaxoftheforinloop}
循环具有以下for...in
语法或结构:
for (let key in value) {
//do something here
}
在这个代码块中,value
是我们正在迭代的项目的集合。它可以是对象、数组、字符串等。key
将是 中每个项目的键value
,在每次迭代时更改为列表中的下一个键。
请注意,我们使用let
orconst
来声明key
。
对对象使用 for...in 循环 {#usingtheforinloopwithobjects}
在 JavaScript 中使用for...in
循环迭代对象时,迭代的键或属性(在上面的代码段中由key
变量表示)是对象自己的属性。
由于对象可能通过原型链继承项目,其中包括对象的默认方法和属性以及我们可能定义的对象原型,因此我们应该使用hasOwnProperty。
for...in 循环对象示例 {#aforinloopobjectexample}
在以下示例中,我们将循环以下变量obj
:
const obj = {
1: "JavaScript",
3: "PHP",
2: "Python",
4: "Java"
};
在循环中,我们正在渲染<div>
元素中的属性和值。
<div id="loopResults"> </div>
//js
const div = document.getElementById('loopResults');
const obj = {
"a": "JavaScript",
1: "PHP",
"b": "Python",
2: "Java"
};
for (let key in obj) {
div.innerHTML += key + ": " + obj[key] + "<br/>";
}
输出结果:
1: PHP
2: Java
a: JavaScript
b: Python
请注意,键的迭代顺序是升序的(即,从数字顺序开始,然后是字母顺序)。但是,这个输出顺序与初始化对象时创建的项目的索引顺序不同。
对数组使用 for...in 循环 {#usingaforinloopwitharrays}
在 JavaScript 中使用for...in
循环迭代数组时,key
在这种情况下将是元素的索引。但是,索引可能会以随机顺序迭代。
因此,如果我们上面展示value
的循环语法结构中的变量for...in
是一个包含五个项目的数组,则key
不能保证为 0 到 4。某些索引可能在其他索引之前。本文稍后将解释有关何时可能发生这种情况的详细信息。
For...in 循环数组示例 {#forinlooparrayexample}
在下面的示例中,我们正在循环以下变量arr
:
const arr = ["Javascript", "PHP", "Python", "Java"];
在循环中,我们渲染每个数组元素的索引和值。
<div id="loopResult"></div>
//js
const div = document.getElementById("loopResult");
const arr = ["Javascript", "PHP", "Python", "Java"];
for (let key in arr) {
div.innerHTML += key + ": " + arr[key] + "<br>";
}
对字符串使用 for...in 循环 {#usingaforinloopwithstrings}
您可以使用 JavaScript for...in
循环遍历字符串。但是,不建议这样做,因为您将循环遍历字符的索引而不是字符本身。
for...in 循环字符串示例 {#aforinloopstringexample}
在下面的示例中,我们正在循环以下变量str
:
const str = "Hello, World!";
在循环内部,我们渲染每个字符的键或索引,以及该索引处的字符。
<div id="result"></div>
//js
const result = document.getElementById("result");
const str = "Hello, World!";
for (let key in str) {
result.innerHTML += key + ": " + str.charAt(key) + '<br />';
}
何时使用 for...in 循环 {#whentouseaforinloop}
让我们看看 JavaScript for...in
循环最适合的情况。
使用 JavaScript for...in 循环迭代对象 {#iteratingobjectswithajavascriptforinloop}
因为for...in
循环只迭代对象的可枚举属性------它们是对象自己的属性,而不是像toString
对象原型中的属性------所以使用for...in
循环来迭代对象是很好的。循环提供了一种for...in
简单的方法来迭代对象的属性并最终迭代其值。
使用 for...in 循环进行调试 {#debuggingwithaforinloop}
for...in
JavaScript循环的另一个很好的用例是调试。例如,您可能希望将对象的属性及其值打印到控制台或 HTML 元素。在这种情况下,for...in
循环是一个不错的选择。
使用for...in
循环调试对象及其值时,应始终牢记迭代不是有序的,这意味着循环迭代的项目顺序可以是随机的。因此,访问的属性的顺序可能与预期不同。
何时不使用 JavaScript for...in 循环 {#whennottouseajavascriptforinloop}
现在让我们看看for...in
循环不是最佳选择的情况。
数组的有序迭代 {#orderlyiteratingofarrays}
由于使用for...in
循环时无法保证迭代中的索引顺序,因此如果需要维护顺序,建议不要对数组进行迭代。
如果您希望支持像 IE 这样的浏览器,这一点尤其重要,它按照项目的创建顺序而不是索引的顺序进行迭代。这与当前现代浏览器的工作方式不同,后者根据索引按升序迭代数组。
因此,例如,如果您有一个包含四个项目的数组,并且您将一个项目插入到位置 3,在现代浏览器中,for...in
循环仍将按从 0 到 4 的顺序迭代数组。在 IE 中,当使用for...in
循环时,它将迭代最初在数组中的四个项目,然后到达在位置三添加的项目。
在迭代时进行更改 {#makingchangeswhileiterating}
对属性的任何添加、删除或修改都不能保证有序迭代。for...in
应避免在循环中更改属性。这主要是由于其无序的性质。
因此,如果您在迭代中到达之前删除了一个项目,那么在整个循环中根本不会访问该项目。
同样,如果您对属性进行更改,也不能保证该项目不会再次被重新访问。因此,如果一个属性被更改,它可能会在循环中被访问两次而不是一次。
此外,如果在迭代过程中添加了一个属性,那么在迭代过程中它可能会被访问,也可能根本不会被访问。
由于这些情况,最好避免在for...in
循环中对对象进行任何更改、删除或添加。
for...in
这是在循环中添加元素的示例。我们可以看到第一个循环的结果,然后在第一个循环中进行添加后的第二个循环。
<h2>Before</h2>
<div id="loopResultsBefore"></div>
<h2>After</h2>
<div id="loopResultsAfter"></div>
//js
const beforeDiv = document.getElementById('loopResultsBefore');
const afterDiv = document.getElementById('loopResultsAfter');
const obj = {
"a": "JavaScript",
1: "PHP",
"b": "Python",
2: "Java"
};
for (let key in obj) {
beforeDiv.innerHTML += key + ": " + obj[key] + "<br />";
if (!isNaN(key)) {
obj[key - 1] = obj[key];
}
}
for (let key in obj) {
afterDiv.innerHTML += key + ": " + obj[key] + "<br />";
}
输出结果:
Before
1: PHP
2: Java
a: JavaScript
b: Python
After
0: PHP
1: Java
2: Java
a: JavaScript
b: Python
正如您在上面的示例中看到的,添加的元素没有被迭代。
替代循环类型 {#alternativelooptypes}
因此,在for...in
循环不是最佳选择的情况下,您应该改用什么?让我们来看看。
对数组使用 for 循环 {#usingaforloopwitharrays}
使用for
循环永远不会错!JavaScript for
循环是循环数组元素的最基本工具之一。该for
循环允许您在迭代数组时完全控制索引。
这意味着在使用for
循环时,您可以前后移动、更改数组中的项、添加项等等,同时仍保持数组的顺序。
以下语句创建了一个循环,该循环遍历数组并将其值打印到控制台。
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
用于数组和对象的 forEach 方法 {#foreachmethodforarraysandobjects}
JavaScript 中的forEach是数组原型上的一个方法,它允许我们在回调函数中迭代数组的元素及其索引。
回调函数是您传递给另一个方法或函数以作为该方法或函数执行的一部分执行的函数。在forEach
中,这意味着每次迭代都会执行回调函数,接收迭代中的当前项作为参数。
例如,以下语句迭代变量arr
并使用以下命令在控制台中打印其值forEach
:
arr.forEach((value) => console.log(value));
您还可以访问数组的索引:
arr.forEach((value, index) => console.log(value, index));
JavaScript forEach
循环也可用于通过使用Object.keys()来迭代对象,将要迭代的对象传递给它,这将返回对象自身属性的数组:
Object.keys(obj).forEach((key) => console.log(obj[key]));
或者,forEach
如果您不需要使用Object.values()访问属性,则可以直接遍历属性的值:
Object.values(obj).forEach((value) => console.log(value));
请注意,Object.values()
以与 相同的顺序返回项目for...in
。
结论 {#conclusion}
通过使用 JavaScript for...in
循环,我们可以遍历对象的键或属性。它在迭代对象属性或调试时很有用,但在迭代数组或对对象进行更改时应避免使用。我希望你发现上面的例子和解释很有用。