Maison  >  Article  >  interface Web  >  Suivez-moi pour apprendre la boucle for et la boucle for...in des compétences javascript_javascript

Suivez-moi pour apprendre la boucle for et la boucle for...in des compétences javascript_javascript

WBOY
WBOYoriginal
2016-05-16 15:31:381041parcourir

Tout le monde sait que JavaScript propose deux manières d'itérer des objets :

  • pour la boucle
  • pour..en boucle

1. pour la boucle

Insuffisance :

La longueur du tableau doit être obtenue à chaque fois qu'il est bouclé
Les conditions de résiliation doivent être claires
Dans une boucle for, vous pouvez parcourir les valeurs d'un tableau ou d'objets de type tableau, tels que des arguments et des objets HTMLCollection. La forme habituelle de la boucle est la suivante :

// 次佳的循环
for (var i = 0; i < myarray.length; i++) {
 // 使用myarray[i]做点什么
}

L'inconvénient de cette forme de boucle est qu'il faut obtenir la longueur du tableau à chaque fois qu'il est bouclé. Cela réduira les performances de votre code, surtout lorsque myarray n'est pas un tableau, mais un objet HTMLCollection.

HTMLCollections fait référence aux objets renvoyés par les méthodes DOM, par exemple :

document.getElementsByName()
document.getElementsByClassName()
document.getElementsByTagName()

Il existe d'autres HTMLCollections qui ont été introduites avant la norme DOM et qui sont toujours utilisées aujourd'hui. Oui :

document.images : Tous les éléments d'image de la page
document.links : Tous les éléments d'une balise
document.forms : tous les formulaires
document.forms[0].elements : Tous les champs du premier formulaire de la page

Le problème avec les collections est qu'elles interrogent le document sous-jacent (page HTML) en temps réel. Cela signifie que chaque fois que vous accédez à la longueur d'une collection, vous devez interroger le DOM en temps réel, et les opérations DOM sont généralement coûteuses.

C'est pourquoi il est de bon ton de mettre en cache la longueur d'un tableau (ou d'une collection) lorsque vous effectuez une boucle sur des valeurs, comme indiqué dans le code suivant :

for (var i = 0, max = myarray.length; i < max; i++) {
 // 使用myarray[i]做点什么
}

De cette façon, vous ne récupérez la valeur de longueur qu'une seule fois au cours de cette boucle.

Mettre en cache la longueur des HTMLCollections lors de la boucle pour récupérer le contenu est plus rapide dans tous les navigateurs, entre 2x (Safari3) et 190x (IE7). //Ces données semblent très anciennes

Notez que lorsque vous souhaitez explicitement modifier la collection dans la boucle (par exemple, ajouter plus d'éléments DOM), vous préférerez peut-être les mises à jour de longueur plutôt que les constantes.

Avec la forme var unique, vous pouvez extraire la variable de la boucle, comme ceci :

function looper() {
 var i = 0,
  max,
  myarray = [];
 // ...
 for (i = 0, max = myarray.length; i < max; i++) {
  // 使用myarray[i]做点什么
 }
}

Ce formulaire présente l'avantage de la cohérence car vous vous en tenez à un seul formulaire var. L'inconvénient est que lors de la refactorisation du code, copier et coller la boucle entière est un peu difficile. Par exemple, si vous copiez une boucle d'une fonction à une autre, vous devez vous assurer que vous pouvez introduire i et max dans la nouvelle fonction (s'ils ne sont pas utiles ici, vous devrez très probablement les supprimer de la fonction d'origine ) Perdre).

Le dernier ajustement de la boucle consiste à remplacer i par l'une des expressions ci-dessous.

i = i + 1
i += 1

JSLint vous invite à le faire parce que et -- favorisent une « astuce excessive ». Si vous l'ignorez, l'option plusplus de JSLint sera fausse (la valeur par défaut est default).

Deux variantes :

  • Il manque une variable (pas de max)
  • Le compte à rebours jusqu'à 0 est généralement plus rapide car comparer à 0 est plus efficace que comparer à la longueur du tableau ou à tout autre élément qui n'est pas 01
//第一种变化的形式:

var i, myarray = [];
for (i = myarray.length; i–-;) {
 // 使用myarray[i]做点什么
}

//第二种使用while循环:

var myarray = [],
 i = myarray.length;
while (i–-) {
 // 使用myarray[i]做点什么
}

Ces petites améliorations concernent uniquement les performances, de plus JSLint se plaindra de l'utilisation de i--.

2. for…en boucle, également appelée «énumération»

La boucle for…in est souvent utilisée pour parcourir les propriétés d'un objet ou de chaque élément d'un tableau. Le compteur de boucle dans la boucle for…in est une chaîne, pas un nombre. Il contient le nom de la propriété actuelle ou l'index de l'élément actuel du tableau. Voici quelques exemples :

Lors du parcours d'un objet, la variable i, qui est le compteur de boucles, est le nom d'attribut de l'objet :

//使用for..in循环遍历对象属性 
varperson={ 
 name: "Admin", 
 age: 21, 
 address:"shandong" 
}; 
for(var i in person){ 
 console.log(i); 
} 

Le résultat de l'exécution est :

nom

âge

adresse

Lors du parcours d'un tableau, la variable i, qui est le compteur de boucles, est l'index de l'élément courant du tableau :

//使用for..in循环遍历数组 
vararray = ["admin","manager","db"] 
for(vari in array){ 
 console.log(i); 
} 

Résultat de l'exécution :

0

1

2

Cependant, il semble maintenant que la boucle for.. in soit assez facile à utiliser. Cependant, ne vous réjouissez pas trop tôt. Jetez un œil à l'exemple suivant :

.
var array =["admin","manager","db"]; 
//给Array的原型添加一个name属性 
Array.prototype.name= "zhangsan"; 
for(var i in array){ 
 alert(array[i]); 
} 

运行结果:

admin

manager

db

zhangsan
咦,奇观了,怎么平白无故的冒出来一个zhangsan
现在,再看看使用 for循环会怎样?

vararray = ["admin","manager","db"]; 
//给Array的原型添加一个name属性 
Array.prototype.name = "zhangsan"; 
for(var i =0 ; i<array.length; i++){ 
 alert(array[i]); 
}; 

运行结果:

admin

manager

db
哦, 现在明白了,for..in循环会把某个类型的原型(prototype)中方法与属性给遍历出来,所以这可能会导致代码中出现意外的错误。为了避免这个问题,我们可以使用对象的hasOwnProperty()方法来避免这个问题,如果对象的属性或方法是非继承的,那么hasOwnProperty() 方法返回true。即这里的检查不涉及从其他对象继承的属性和方法,只会检查在特定对象自身中直接创建的属性。

vararray = ["admin","manager","db"]; 
Array.prototype.name= "zhangshan"; 
for(var i in array){ 
//如果不是该对象自身直接创建的属性(也就是该属//性是原型中的属性),则跳过显示 
 if(array.hasOwnProperty(i)){ 
  alert(array[i]); 
  }
} 

运行结果:

admin

manager

db
另外一种使用hasOwnProperty()的形式是取消Object.prototype上的方法。像这样:

// 对象
var man = {
 hands: 2,
 legs: 2,
 heads: 1
};
for (var i in man) {
 if (Object.prototype.hasOwnProperty.call(man, i)) { // 过滤
  console.log(i, ":", man[i]);
 }
}

其好处在于在man对象重新定义hasOwnProperty情况下避免命名冲突。也避免了长属性查找对象的所有方法,你可以使用局部变量“缓存”它。

var i, hasOwn = Object.prototype.hasOwnProperty;
for (i in man) {
 if (hasOwn.call(man, i)) { // 过滤
  console.log(i, ":", man[i]);
 }
}

严格来说,不使用hasOwnProperty()并不是一个错误。根据任务以及你对代码的自信程度,你可以跳过它以提高些许的循环速度。但是当你对当前对象内容(和其原型链)不确定的时候,添加hasOwnProperty()更加保险些。

格式化的变化(通不过JSLint)会直接忽略掉花括号,把if语句放到同一行上。其优点在于循环语句读起来就像一个完整的想法(每个元素都有一个自己的属性”X”,使用”X”干点什么):

// 警告: 通不过JSLint检测
var i, hasOwn = Object.prototype.hasOwnProperty;
for (i in man) if (hasOwn.call(man, i)) { // 过滤
 console.log(i, ":", man[i]);
}

以上就是介绍了JavaScript提供的两种方式迭代对象:for循环和for...in循环,希望这篇文章对大家的学习有所帮助。

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn