3

我是 JavaScript 新手,目前正在学习所谓的for... in循环。

在 JavaScript 中编码时是否真的使用了这些循环?

我可以看到所有其他类型的循环是如何有用的——但不是这个。

请有人对此有所了解,并在可能的情况下包括一个真实的例子。

4

5 回答 5

7

在 Javascript 中,只有 Array 对象可以通过正常for(;;)循环进行迭代。for..in用于枚举非数组对象:

for (var i in obj) {
    if (obj.hasOwnProperty(i)) { // if you don't want to access prototype properties
        alert(i);
        alert(obj[i]);
    }
}
于 2011-11-04T14:18:47.103 回答
0

我认为只要您了解对象可以容纳的不仅仅是简单的变量,就可以了。考虑这个从 w3schools.com 修改的例子来说明这一点:

<script type="text/javascript">

//This is probably as you expect:
var person={fname:"John",lname:"Doe",age:25}; 

//This is probably unexpected and unwanted, but is valid and will be an output of the for...in loop:
person.f = function(){
 alert("Hi");
};

//Use typeof() function to check that the data type is what you expect:
for (x in person){
   document.write(typeof(person[x]) + " ");
}

</script>

这打印:

字符串字符串数字函数

为了回答您关于循环类型之间差异的具体问题,for() 循环适用于具有长度属性的数组类型。foreach() 循环可以很好地迭代对象集合,而 foreach ...in 循环可以很好地用于对象的键(不声称这些是任何循环类型的专有用途)。

于 2011-11-04T14:28:48.577 回答
0

两者都for in服务for于特定目的。让我们看一些。

如果你有一个对象

var obj = { one: 1, two: 2 }; 

然后你可以使用循环迭代它的属性,for in

for( var i in obj ) console.log( obj[i] );  //use obj.hasOwnProperty(i) to exclude prototype properties 

请注意,如果您尝试obj通过 for 循环进行迭代,它将无法正常工作,因为它将使用数字索引来访问键并且会给出未定义的即obj[0]未定义。除了简单的写入之外,获取对象的长度会更复杂obj.length。当然,如果您有数字属性,您将能够使用for循环,for in它更适合对象迭代。

如果你有一个数组

 var array = [1,2] 

从技术上讲,您可以同时使用两者,但建议您为此使用 for 循环。这就是为什么

  1. 不保证元素顺序。
  2. 原型属性也将被迭代,这可能会导致不必要的副作用。

为了说明第二点,让我们扩展 Array.

Array.prototype.print_array = function(){ console.log(this) }; 

我们刚刚添加到 Array 的这个函数将被所有 Array 对象继承,因此,通过for in

for( var i in array ) console.log( array[i] ); 

会产生

1
2
function (){ console.log(this) } // the prototype property was iterated over also

并使用for

for( var i =0; i < array.length; i++) console.log( array[i] ); 

会产生预期的结果。

1
2

因此,对于对象迭代使用for in并且对于数组迭代使用for

于 2011-11-04T15:00:51.740 回答
0

它通常用于遍历某物的集合。例如,由于每个 JavaScript 对象都可以被视为属性的集合,因此您可以以这种方式枚举属性。

//let's loop throug all properties of a "document" 
//we don't know what these will be
var txtProps = "";
for (var prop in window.document) {
   txtProps += prop + "\n";
}
alert(txtProps);//pops out a message showing a looong list of all properties
于 2011-11-04T14:22:33.717 回答
0

要理解这一点,您首先需要了解 JavaScript 的对象模型。

正如您将注意到的,在使用数组时,for...in循环并不是那么有用,因为for (;;)循环更容易完成这项工作。

但是数组只是一种具有数字属性的 JavaScript 对象,for (;;)循环只处理数字属性。使用该符号的原因myArray[0]是您可以将此方括号符号用于任何属性名称。所以myObject['myProperty']是一样的myObject.myProperty。这是for...in变得有用的地方:

for (var i in myObject) {
    alert(myObject[i]);
}

因此,如果我们设置的唯一属性是myProperty, theni将等于"myProperty"(请注意,它是一个字符串,这使得它比变量名更具动态性)。

不过,这里有一个巨大的 BUT。对象有一个叫做原型的东西,这些原型有自己的属性和方法。如果我执行以下操作:

for (var i in myArray) {
    alert(i + ': ' + myArray[i]);
}

...我不仅会收到数值(1、2、3 等)的警报。我还会收到数组的属性(例如length)及其方法(例如join. 这些属性实际上属于 Array 对象的原型,可以通过以下操作过滤掉原型属性:

for (var i in myArray) {
    if (myArray.hasOwnProperty(i)) {
        alert(i + ': ' + myArray[i]);
    }
}

现在我将再次收到数值警报,这意味着这(几乎)与for (var i = 0;; i < myArray.length; i++). 当我们可以使用该符号时,为什么我要告诉你这个?因为所有对象都有原型,而不仅仅是数组。并且每个对象都来自该Object对象,因此如果有人定义Object.prototype.myProperty = "some string value"了,那么它将始终显示在for...in您在页面其余部分使用的任何循环中。幸运的是,该hasOwnProperty方法本身属于Object.prototype,因此您可以(并且应该)始终在for...in循环中使用它。

所以这是一个成熟的for...in例子:

// This is just one way of defining an object. We could also use a constructor function, or `new Object()`
var myObject = {
    aProperty : "my first property value",
    anotherProperty : "second property value"
    4 : "numeric property names work too, you know"
}

for (var i in myObject) {
    if (myObject.hasOwnProperty(i)) {
       document.write(i + ': ' + myObject[i] + '<br />\n'); 
    }
}

输出:

aProperty: my first property value
anotherProperty: secondPropertyValue
4: numeric property names work too, you know

希望这能解释一切。

于 2011-11-04T14:55:13.357 回答