2011-11-04 56 views
3

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

在JavaScript中编码时,实际上是否使用这些循环?

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

有人对此有所了解,请尽可能包含真实生活中的示例。

回答

7

仅在Javascript中可以使用正常的for(;;)循环迭代Array对象。该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]); 
    } 
} 
+0

同意约hasOwnProperty(),但你也可能要检查的typeof(),以确保功能类型等别你最终会输出。 –

+0

@MickSear完全取决于你对对象做什么。例如,如果你使用遍历来“克隆”对象,那么你并不在乎。无论如何,我只是添加了它,因为这是他可能遇到的问题,与问题本身并没有真正的关系。 – deviousdodo

+0

就像一个笔记:我的答案只是关于一般的做法,我忽略了一些技巧。 'arguments'是'只有数组对象可以被迭代'的一个例外,当然''for'循环只是偶尔用于遍历数组,但我认为这些事情对于这个问题本身并不重要。 – deviousdodo

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 
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> 

此打印:

串串数字功能

要获得关于环路类型,则对之间的差异具体问题()循环适用于具有length属性的数组类型。 foreach()循环可以很好地用于迭代对象集合,而foreach ... in循环对于对象的键(对于任何类型的循环都不会声称这些是唯一用途)很适用。

0

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

正如你所指出的,当使用数组时,for...in循环并不是那么有用,因为for (;;)循环更容易完成这项工作。

但是数组只是一种具有数字属性的JavaScript对象,并且for (;;)循环仅处理数字属性。符号myArray[0]的原因是,您可以对任何属性名称使用此方括号表示法。因此myObject['myProperty']myObject.myProperty相同。这是for...in变成有用:

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

因此,如果我们想设置的唯一属性是myProperty,然后i将等于"myProperty"(注意,这是一个字符串,这使得它不仅仅是作为一个变量名更动态) 。

虽然这里有一个巨大的但是。对象有一些叫做原型的东西,这些原型有自己的属性和方法。如果我做到以下几点:

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 

希望这可以解释这一切。

0

for infor都用于特定目的。让我们看看一些。

如果你有一个对象

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) }; 

,我们只是添加到阵列该功能将所有的数组对象继承,因此,通过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