這幾天接到客戶回報說系統的購物車加總計算錯誤,霎時間囧了。立馬開啓網站進行測試,但無論我怎麼測試計算結果都是正確的,只好請同事也幫忙測試看看,換了好幾台手機、電腦與好幾種瀏覽器,但結果仍然是正確...


後來只好請教google大神,發現到原來問題是因為我是使用 javascript 的 for in 去計算加總的,而計算總和錯誤的這個問題也只會發生在特定的機子上(例如:iphone 6s plus 或 iphone 5s 或 ios 9.3.x 版本),但正好手中沒這些機子所以怎麼也測不出來。

不過,既然是有問題的話,還是要解決才行。

原本有問題的code:

var total = 0;

for (item in this.cart_data) {

      total = total + (parseFloat(this.cart_data[item].price) * parseInt(this.cart_data[item].qty));

}

改良的code:

var total = 0;

var cart_data = [{price:2,qty:2},{price:5,qty:4}];

var c = [];

c = cart_data.map(function(x){

           return parseFloat(x.price) * parseInt(x.qty);

});

total = c.reduce((a,b)=>{return a+b});


上網查了一番後,得到的答案是將 for in 改成 map搭配reduce的寫法就可以解決了!至於為什麼 for in 會出現這種錯誤,據說是因為for in 不會自動檢查hasOwnProperty,導致原型中的某些屬性也被遍歷了,造成計算總和時出現錯誤。


在網路上還找到一篇文章,是用for in 加上hasOwnProperty檢查的寫法,但沒有實際測試過,不確定是否有效... 


var total = 0;

for (item in this.cart_data) {

     if (this.cart_data.hasOwnProperty(key)){

       total = total + (parseFloat(this.cart_data[item].price) * parseInt(this.cart_data[item].qty));

    }  

}


從下面的參考文章中才知道,原來 for in 的寫法是最不好的啊...真是學了一課!


參考文章 : https://github.com/airbnb/javascript#iterators-and-generators


文章轉載或引用,請先告知並保留原文出處與連結!!(單純分享或非營利的只需保留原文出處,不用告知)

原文連結:
https://blog.aidec.tw/post/javascript-for-in-error