JavaScript にはオブジェクトを反復する 2 つの方法があることは誰もが知っています:
1. for ループ
不十分:
配列の長さはループされるたびに取得する必要があります。
終了条件を明確にする必要があります。
for ループでは、引数や HTMLCollection オブジェクトなどの配列または配列に似たオブジェクトの値をループできます。通常のループ形式は次のとおりです:
// 次佳的循环 for (var i = 0; i < myarray.length; i++) { // 使用myarray[i]做点什么 }
この形式のループの欠点は、ループするたびに配列の長さを取得する必要があることです。これにより、特に myarray が配列ではなく HTMLCollection オブジェクトである場合、コードのパフォーマンスが低下します。
HTMLCollections は、DOM メソッドによって返されるオブジェクトを指します。例:
document.getElementsByName()
document.getElementsByClassName()
document.getElementsByTagName()
DOM 標準より前に導入され、現在でも使用されている HTMLCollection は他にもあります。はい:
document.images: ページ上のすべての画像要素
document.links: すべてのタグ要素
document.forms : すべてのフォーム
document.forms[0].elements : ページの最初のフォームのすべてのフィールド
コレクションの問題は、基礎となるドキュメント (HTML ページ) をリアルタイムでクエリすることです。これは、コレクションの長さにアクセスするたびに、リアルタイムで DOM にクエリを実行する必要があり、DOM 操作は一般にコストがかかることを意味します。
次のコードに示すように、値をループするときに配列 (またはコレクション) の長さをキャッシュするのが良い形式であるのはこのためです。
for (var i = 0, max = myarray.length; i < max; i++) { // 使用myarray[i]做点什么 }
この方法では、このループ中に長さの値を 1 回だけ取得します。
コンテンツを取得するためのループ時の HTMLCollection の長さのキャッシュは、すべてのブラウザーで 2 倍 (Safari3) から 190 倍 (IE7) まで高速になります。 //このデータは非常に古いようです
ループ内のコレクションを明示的に変更する場合 (たとえば、DOM 要素を追加する場合)、定数ではなく長さの更新を好む場合があることに注意してください。
単一の var 形式を使用すると、次のようにループから変数を取り出すことができます:
function looper() { var i = 0, max, myarray = []; // ... for (i = 0, max = myarray.length; i < max; i++) { // 使用myarray[i]做点什么 } }
この形式には、単一の var 形式に固執するため、一貫性という利点があります。欠点は、コードをリファクタリングするときに、ループ全体をコピーして貼り付けるのが少し難しいことです。たとえば、ある関数から別の関数にループをコピーする場合、新しい関数に i と max を導入できることを確認する必要があります (ここで役に立たない場合は、元の関数からそれらを削除する必要がある可能性があります) ) 失う)。
ループの最後の調整は、i を以下の式のいずれかに置き換えることです。
i = i + 1 i += 1
JSLint がこれを行うように要求するのは、 -- 「過度の扱いやすさ」を助長するためです。これを無視すると、JSLint の plusplus オプションは false になります (デフォルトはdefault)。
2 つのバリエーション:
//第一种变化的形式: var i, myarray = []; for (i = myarray.length; i–-;) { // 使用myarray[i]做点什么 } //第二种使用while循环: var myarray = [], i = myarray.length; while (i–-) { // 使用myarray[i]做点什么 }
これらの小さな改善はパフォーマンスのためだけであり、さらに、JSLint は i-- の使用に関して不平を言います。
2. for…in ループ — 「列挙」とも呼ばれます
for…in ループは、オブジェクトのプロパティまたは配列の各要素を反復するためによく使用されます。for…in ループ内のループ カウンタは数値ではなく文字列です。これには、現在のプロパティの名前または現在の配列要素のインデックスが含まれます。 以下にいくつかの例を示します:
オブジェクトを走査する場合、ループカウンターである変数 i はオブジェクトの属性名です:
//使用for..in循环遍历对象属性 varperson={ name: "Admin", age: 21, address:"shandong" }; for(var i in person){ console.log(i); }
実行結果は次のとおりです:
名前
年齢
アドレス
配列を走査する場合、ループ カウンタである変数 i は、現在の配列要素のインデックスです:
//使用for..in循环遍历数组 vararray = ["admin","manager","db"] for(vari in array){ console.log(i); }
実行結果:
0
1
2
ただし、for.. in ループは非常に使いやすくなったように見えますが、すぐに次の例を見てください。
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循环,希望这篇文章对大家的学习有所帮助。