跟我學(xué)習(xí)javascript的for循環(huán)和for...in循環(huán)
大家都知道在JavaScript中提供了兩種方式迭代對(duì)象:
- for 循環(huán);
- for..in循環(huán);
一、for循環(huán)
不足:
在于每次循環(huán)的時(shí)候數(shù)組的長(zhǎng)度都要去獲??;
終止條件要明確;
在for循環(huán)中,你可以循環(huán)取得數(shù)組或是數(shù)組類似對(duì)象的值,譬如arguments和HTMLCollection對(duì)象。通常的循環(huán)形式如下:
// 次佳的循環(huán) for (var i = 0; i < myarray.length; i++) { // 使用myarray[i]做點(diǎn)什么 }
這種形式的循環(huán)的不足在于每次循環(huán)的時(shí)候數(shù)組的長(zhǎng)度都要去獲取下。這回降低你的代碼性能,尤其當(dāng)myarray不是數(shù)組,而是一個(gè)HTMLCollection對(duì)象的時(shí)候。
HTMLCollections指的是DOM方法返回的對(duì)象,例如:
document.getElementsByName()
document.getElementsByClassName()
document.getElementsByTagName()
還有其他一些HTMLCollections,這些是在DOM標(biāo)準(zhǔn)之前引進(jìn)并且現(xiàn)在還在使用的。有:
document.images: 頁(yè)面上所有的圖片元素
document.links : 所有a標(biāo)簽元素
document.forms : 所有表單
document.forms[0].elements : 頁(yè)面上第一個(gè)表單中的所有域
集合的麻煩在于它們實(shí)時(shí)查詢基本文檔(HTML頁(yè)面)。這意味著每次你訪問(wèn)任何集合的長(zhǎng)度,你要實(shí)時(shí)查詢DOM,而DOM操作一般都是比較昂貴的。
這就是為什么當(dāng)你循環(huán)獲取值時(shí),緩存數(shù)組(或集合)的長(zhǎng)度是比較好的形式,正如下面代碼顯示的:
for (var i = 0, max = myarray.length; i < max; i++) { // 使用myarray[i]做點(diǎn)什么 }
這樣,在這個(gè)循環(huán)過(guò)程中,你只檢索了一次長(zhǎng)度值。
在所有瀏覽器下,循環(huán)獲取內(nèi)容時(shí)緩存HTMLCollections的長(zhǎng)度是更快的,2倍(Safari3)到190倍(IE7)之間。//此數(shù)據(jù)貌似很老
注意到,當(dāng)你明確想要修改循環(huán)中的集合的時(shí)候(例如,添加更多的DOM元素),你可能更喜歡長(zhǎng)度更新而不是常量。
伴隨著單var形式,你可以把變量從循環(huán)中提出來(lái),就像下面這樣:
function looper() { var i = 0, max, myarray = []; // ... for (i = 0, max = myarray.length; i < max; i++) { // 使用myarray[i]做點(diǎn)什么 } }
這種形式具有一致性的好處,因?yàn)槟銏?jiān)持了單一var形式。不足在于當(dāng)重構(gòu)代碼的時(shí)候,復(fù)制和粘貼整個(gè)循環(huán)有點(diǎn)困難。例如,你從一個(gè)函數(shù)復(fù)制了一個(gè)循環(huán)到另一個(gè)函數(shù),你不得不去確定你能夠把i和max引入新的函數(shù)(如果在這里沒(méi)有用的話,很有可能你要從原函數(shù)中把它們刪掉)。
最后一個(gè)需要對(duì)循環(huán)進(jìn)行調(diào)整的是使用下面表達(dá)式之一來(lái)替換i++。
i = i + 1 i += 1
JSLint提示您這樣做,原因是++和–-促進(jìn)了“過(guò)分棘手(excessive trickiness)”。如果你直接無(wú)視它,JSLint的plusplus選項(xiàng)會(huì)是false(默認(rèn)是default)。
兩種變化的形式:
- 少了一個(gè)變量(無(wú)max)
- 向下數(shù)到0,通常更快,因?yàn)楹?做比較要比和數(shù)組長(zhǎng)度或是其他不是0的東西作比較更有效率01
//第一種變化的形式: var i, myarray = []; for (i = myarray.length; i–-;) { // 使用myarray[i]做點(diǎn)什么 } //第二種使用while循環(huán): var myarray = [], i = myarray.length; while (i–-) { // 使用myarray[i]做點(diǎn)什么 }
這些小的改進(jìn)只體現(xiàn)在性能上,此外JSLint會(huì)對(duì)使用i–-加以抱怨。
二、for …in 循環(huán)—也被稱為“枚舉”
for …in 循環(huán)經(jīng)常用來(lái)迭代對(duì)象的屬性或數(shù)組的每個(gè)元素,for…in循環(huán)中的循環(huán)計(jì)數(shù)器是字符串,而不是數(shù)字。它包含當(dāng)前屬性的名稱或當(dāng)前數(shù)組元素的索引。 下面直接上幾個(gè)例子:
當(dāng)遍歷一個(gè)對(duì)象的時(shí)候,變量 i 也就是循環(huán)計(jì)數(shù)器 為 對(duì)象的屬性名 :
//使用for..in循環(huán)遍歷對(duì)象屬性 varperson={ name: "Admin", age: 21, address:"shandong" }; for(var i in person){ console.log(i); }
執(zhí)行結(jié)果為:
name
age
address
當(dāng)遍歷一個(gè)數(shù)組的時(shí)候,變量 i 也就是循環(huán)計(jì)數(shù)器 為 當(dāng)前數(shù)組元素的索引 :
//使用for..in循環(huán)遍歷數(shù)組 vararray = ["admin","manager","db"] for(vari in array){ console.log(i); }
執(zhí)行結(jié)果:
0
1
2
但是,現(xiàn)在看來(lái)for .. in循環(huán)還挺好用啊,不過(guò),別高興太早,看看下面的例子:
var array =["admin","manager","db"]; //給Array的原型添加一個(gè)name屬性 Array.prototype.name= "zhangsan"; for(var i in array){ alert(array[i]); }
運(yùn)行結(jié)果:
admin
manager
db
zhangsan
咦,奇觀了,怎么平白無(wú)故的冒出來(lái)一個(gè)zhangsan
現(xiàn)在,再看看使用 for循環(huán)會(huì)怎樣?
vararray = ["admin","manager","db"]; //給Array的原型添加一個(gè)name屬性 Array.prototype.name = "zhangsan"; for(var i =0 ; i<array.length; i++){ alert(array[i]); };
運(yùn)行結(jié)果:
admin
manager
db
哦, 現(xiàn)在明白了,for..in循環(huán)會(huì)把某個(gè)類型的原型(prototype)中方法與屬性給遍歷出來(lái),所以這可能會(huì)導(dǎo)致代碼中出現(xiàn)意外的錯(cuò)誤。為了避免這個(gè)問(wèn)題,我們可以使用對(duì)象的hasOwnProperty()方法來(lái)避免這個(gè)問(wèn)題,如果對(duì)象的屬性或方法是非繼承的,那么hasOwnProperty() 方法返回true。即這里的檢查不涉及從其他對(duì)象繼承的屬性和方法,只會(huì)檢查在特定對(duì)象自身中直接創(chuàng)建的屬性。
vararray = ["admin","manager","db"]; Array.prototype.name= "zhangshan"; for(var i in array){ //如果不是該對(duì)象自身直接創(chuàng)建的屬性(也就是該屬//性是原型中的屬性),則跳過(guò)顯示 if(array.hasOwnProperty(i)){ alert(array[i]); } }
運(yùn)行結(jié)果:
admin
manager
db
另外一種使用hasOwnProperty()的形式是取消Object.prototype上的方法。像這樣:
// 對(duì)象 var man = { hands: 2, legs: 2, heads: 1 }; for (var i in man) { if (Object.prototype.hasOwnProperty.call(man, i)) { // 過(guò)濾 console.log(i, ":", man[i]); } }
其好處在于在man對(duì)象重新定義hasOwnProperty情況下避免命名沖突。也避免了長(zhǎng)屬性查找對(duì)象的所有方法,你可以使用局部變量“緩存”它。
var i, hasOwn = Object.prototype.hasOwnProperty; for (i in man) { if (hasOwn.call(man, i)) { // 過(guò)濾 console.log(i, ":", man[i]); } }
嚴(yán)格來(lái)說(shuō),不使用hasOwnProperty()并不是一個(gè)錯(cuò)誤。根據(jù)任務(wù)以及你對(duì)代碼的自信程度,你可以跳過(guò)它以提高些許的循環(huán)速度。但是當(dāng)你對(duì)當(dāng)前對(duì)象內(nèi)容(和其原型鏈)不確定的時(shí)候,添加hasOwnProperty()更加保險(xiǎn)些。
格式化的變化(通不過(guò)JSLint)會(huì)直接忽略掉花括號(hào),把if語(yǔ)句放到同一行上。其優(yōu)點(diǎn)在于循環(huán)語(yǔ)句讀起來(lái)就像一個(gè)完整的想法(每個(gè)元素都有一個(gè)自己的屬性”X”,使用”X”干點(diǎn)什么):
// 警告: 通不過(guò)JSLint檢測(cè) var i, hasOwn = Object.prototype.hasOwnProperty; for (i in man) if (hasOwn.call(man, i)) { // 過(guò)濾 console.log(i, ":", man[i]); }
以上就是介紹了JavaScript提供的兩種方式迭代對(duì)象:for循環(huán)和for...in循環(huán),希望這篇文章對(duì)大家的學(xué)習(xí)有所幫助。
- 講解JavaScript中for...in語(yǔ)句的使用方法
- JS數(shù)組的遍歷方式for循環(huán)與for...in
- JavaScript For...In 使用方法
- Javascript技巧之不要用for in語(yǔ)句對(duì)數(shù)組進(jìn)行遍歷
- js數(shù)組循環(huán)遍歷數(shù)組內(nèi)所有元素的方法
- JQuery遍歷json數(shù)組的3種方法
- jQuery 遍歷json數(shù)組的實(shí)現(xiàn)代碼
- jquery遍歷篩選數(shù)組的幾種方法和遍歷解析json對(duì)象
- javascript數(shù)組遍歷for與for in區(qū)別詳解
- JS for...in 遍歷語(yǔ)句用法實(shí)例分析
相關(guān)文章
原生js實(shí)現(xiàn)中獎(jiǎng)信息無(wú)間隙滾動(dòng)效果
本文主要分享了原生js實(shí)現(xiàn)中獎(jiǎng)信息無(wú)間隙滾動(dòng)效果的示例代碼。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-01-01javascript中with()方法的語(yǔ)法格式及使用
有了 With 語(yǔ)句,在存取對(duì)象屬性和方法時(shí)就不用重復(fù)指定參考對(duì)象,下面為大家介紹下With 語(yǔ)句的語(yǔ)法格式及使用2014-08-08解決layer.confirm快速點(diǎn)擊會(huì)重復(fù)觸發(fā)事件的問(wèn)題
今天小編就為大家分享一篇解決layer.confirm快速點(diǎn)擊會(huì)重復(fù)觸發(fā)事件的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09JS獲取屏幕高度的簡(jiǎn)單實(shí)現(xiàn)代碼
下面小編就為大家?guī)?lái)一篇JS獲取屏幕高度的實(shí)現(xiàn)代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-05-05javascript之水平橫向滾動(dòng)歌詞同步的應(yīng)用
javascript之水平橫向滾動(dòng)歌詞同步的應(yīng)用...2007-05-05JavaScript中數(shù)組雙重去重的方法總結(jié)
這篇文章主要為大家學(xué)習(xí)介紹了JavaScript中數(shù)組雙重去重的幾個(gè)常用方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-07-07