js js中的for in 你讓我情何以堪

2021-10-04 15:29:33 字數 3079 閱讀 8663

最近在寫乙個小demo,碼前端的時候發現乙個js中很深的坑:

因為前端收到伺服器端傳來的資料是一串用「,」隔開的字串,在處理的時候直接用string.spilt()方法給斷成了乙個字串陣列,以便食用;所以在取陣列元素的時候想到了用for-in去遍歷。

然鵝!

然鵝!然鵝!

我還是太年輕了!完全不知道自己已經陷入了乙個巨大(zhi zhang)的陷阱!本來完美無缺(bu shi hen lan)的**突然變得焦躁起來,大家似乎都對我有不同的意見,爭先恐後的抱起了八阿哥。嗚嗚嗚,不說了,浪費半天時間……

上**!

var arr =

["please"

,"dont"

,"cast"

,"my"

,"type"];

for(

var a in arr)

原**比較繁瑣,上面是示例**,大概就是這麼個操作。

然後就一直報錯啊,提示資訊如下:

uncaught typeerror: cannot set property 『value』 of null at :2:38

到這基本上就知道是因為dom元素沒有被拿到了,就在迴圈體裡面的第一行加了句console.log(document.getelementbyid(a)),打出來是null沒錯,但想來想去還是不明白為什麼(壓根就沒懷疑for-in這奇葩的語句)。

折騰了半天沒辦法,只好再前置了一句console.log(a)想著試一試。誒???為什麼輸出的是些奇怪的東西?

var arr =

["please"

,"dont"

,"cast"

,"my"

,"type"];

for(

var a in arr)//0

1234

shuffle

這是把arr的索引給遍歷出來了嗎?再檢視一下a的型別:

var arr =

["please"

,"dont"

,"cast"

,"my"

,"type"];

for(

var a in arr)

6 string

這什麼鬼?難道for-in是用來遍歷物件的索引的?

驗證一下吧:

//

>

var ob =

< undefined

> ob

<1:

"aa"2:

"bb"3:

"cc"__proto__: object

>

for(

var o in ob)

>

1>

2>

3> undefined

//>

var oc =

< undefined

> oc

<

a1:"aaa"a2:

"bbb"a3:

"ccc"__proto__: object

>

for(

var o in oc)

> a1

> a2

> a3

< undefined

看來,對於「物件」,for-in語句遍歷出來的是屬性沒錯了。

!!!但是,對於陣列,不要用for-in去遍歷它的索引,因為會出現莫名其妙的東西,比如上面遍歷陣列的**,最後乙個遍歷出的是shuffle,這個是陣列原型鏈中的乙個屬性,在這裡被莫名其妙的搞出來了。

1.常規的for(var i=0;i2.for-in:for(var item in list)

但是個人更喜歡使用第一種迴圈,而不喜歡幾乎從來不使用for-in這種寫法,原因如下:

1.第一種寫法能夠很好的控制迴圈何時結束,以及對應的索引;而第二種迴圈無法控制

2.第二種寫法在某種情況下,可能會導致一些奇怪的bug

以上是在jsbin中編輯的**,在第一段**中,對js的陣列array新增了乙個新的方法(prototype 屬性使您有能力向物件新增屬性和方法),為了在某些時候能夠方便使用。此時,如果用for-in迴圈出陣列arr的內容,會發現在本來想要得到的0,1,2,3的後面會多乙個function(),這應該不是我們想要得到的結果。

注意:for…in迴圈會把某個型別的原型(prototype)中方法與屬性給遍歷出來,所以這可能會導致****現意外的錯誤

上面只是簡單的遍歷乙個陣列,可能出現的問題還不夠明顯,如下所示

如果我們遍歷的陣列中存放的是業務物件,此時會發現,最後一次輸出的是空,在被迴圈的陣列中不存在這個名稱為空的人員,此時出現的錯誤就導致某些業務無法正常使用或顯示。

對於使用for-in可能匯出的bug,有兩種方式避免

1.在迴圈陣列集合時,不使用for-in,統一使用for(var i=0;i2.在for-in迴圈中增加乙個hasownproperty的判斷;

hasownproperty函式用於指示乙個物件自身(不包括原型鏈)是否具有指定名稱的屬性。如果有,返回true,否則返回false

該方法屬於object物件,由於所有的物件都"繼承"了object的物件例項,因此幾乎所有的例項物件都可以使用該方法。

上述的兩種方式,個人覺得第一種方式更好,因為是從根源上避免問題的發生,對於第二種方式,完全是為了解決問題而增加額外的處理完全沒有這個必要。

CSDN 你的「敬業精神」讓我折服

題目定義的有些廣泛,在正文當中,重點討論csdn的乙個欄目 blog csdn的blog欄目組工作人員,你們對完美主義的追求精神讓我折服。是你們不斷的公升級blog系統,為廣大的blogger提供最優秀的blog寫作平台。csdn的blog欄目組工作人員,你們的無私奉獻精神讓我為之折服。在當今 利益...

新網的客服讓我怎麼說你!

24小時熱,如果不在工作時間內,累死你也不會有人接 有次我的 轉讓資訊 網打不開了,正趕上週六,我從早上六點連續打到九點也沒人接,對方提醒一直忙請等候!最後打到九點半終於有人接了,我不知道激動還是憤怒,不知道說什麼了,一句話也說不出!週六休息,可以原諒啊,可你的 別打出什麼 24小時 啊,還有一次,...

嫁我是你一生的賭注,我怎麼忍心讓你輸

嫁我是你一生的賭注,我怎麼忍心讓你輸 有這麼乙個故事 兩個人每天面對面上班。她有時候會看著他走神兒。他有張好看而略微頹廢的臉,看得多了,他會注意到她,便總是衝著她笑。她低下頭,臉突然就紅了。很快,周圍的同事也窺測出她的心事來。頻繁開起他倆的玩笑。一來二去,他和她竟真成了主戀人。他們都到了結婚的年齡。...