我是 JavaScript 新手,目前正在学习所谓的for... in
循环。
在 JavaScript 中编码时是否真的使用了这些循环?
我可以看到所有其他类型的循环是如何有用的——但不是这个。
请有人对此有所了解,并在可能的情况下包括一个真实的例子。
我是 JavaScript 新手,目前正在学习所谓的for... in
循环。
在 JavaScript 中编码时是否真的使用了这些循环?
我可以看到所有其他类型的循环是如何有用的——但不是这个。
请有人对此有所了解,并在可能的情况下包括一个真实的例子。
在 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]);
}
}
我认为只要您了解对象可以容纳的不仅仅是简单的变量,就可以了。考虑这个从 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 循环可以很好地用于对象的键(不声称这些是任何循环类型的专有用途)。
两者都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 循环。这就是为什么
为了说明第二点,让我们扩展 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
它通常用于遍历某物的集合。例如,由于每个 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
要理解这一点,您首先需要了解 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
希望这能解释一切。