摘要:你的線上代碼真的沒有嗎歡迎免費使用我們可以幫助您第一時間發現字符串拼接加法仔細查看生成的代碼,你會發現出現在標記的后面,然而標簽不見了。在中,根據左右兩邊變量的類型的不同,符號可以用于數字相加或則字符串拼接。然后又轉換為字符串拼接起來。
譯者按: bug雖小,卻是個磨人的小妖精!
原文: Fixing a bug: when concatenated strings turn into numbers in JavaScript
譯者: Fundebug
為了保證可讀性,本文采用意譯而非直譯。另外,本文版權歸原作者所有,翻譯僅用于學習。
這是一篇很簡短的博客,記錄了我今天早上花了一個小時才解掉的一個bug。
準備工作在已有的網站頁面,我們已經有一段JavaScript代碼用于構建字符串并把它插入到DOM中,如下所示:
function GetTemplate(url, html) { // 省掉部分細節代碼 // ... var template = ""; return template; }
請忽略這段代碼的粗糙。接下來,我們的需求很簡單:如果summary存在,那么在標簽前面添加一個額外的標簽將該值顯示出來。是不是很簡單?我們來試一試。
首次嘗試我快速實現了如下代碼:
function GetTemplate(url, html, summary) { // other details removed var template = ""; return template; }
看上去一切OK,沒有問題。F5刷新頁面,看起來不大對:
你知道哪里出問題了嗎?
由上面的代碼生成的HTML長這樣:
發現問題了嗎?如果沒發現,我們接著往下看。
你的線上代碼真的沒有BUG嗎?歡迎免費使用Fundebug!我們可以幫助您第一時間發現BUG!
字符串拼接 vs 加法仔細查看生成的HTML代碼,你會發現NaN出現在標記的后面,然而標簽不見了。NaN是一個很好的線索,表明這里有類型轉換發生,并且是轉換為Number類型,但是我當時一直沒有找到發生轉換的原因!
接下來,我們先溫習一下JavaScript基礎知識。在JavaScript中,根據+左右兩邊變量的類型的不同,+符號可以用于數字相加或則字符串拼接。
console.log("value:" + 3); // "value:3" console.log(3 + 1); // 4 console.log("value:" + 3 + "+" + 1); // "value:3+1" console.log("value:" + 3 + 1); // "value:31" console.log("value:" + (3 + 1)); // "value:4" console.log(3 + " is the value"); // "3 is the value"
在上面的這些例子中,如果+的任何一邊是字符串,那么另一邊一定會轉換為字符串。否則,將看做是數字相加。
因此,NaN預示著一定是字符串被誤用為數字了。但我并沒有使用parseInt()函數做類型轉換,所以邏輯上說不通啊!
問題原因最終,我逐步縮小出錯區域,發現是如下代碼出錯:
template +=
+"Details: "
+ html
+ "
如果你還是沒看出來,那么我們換個寫法:
template += +"Details: " + html + "
我用了string += +string這樣的寫法,也就是說:由于寫代碼的時候拷貝黏貼,不小心整了一個多余的+號?所以,相當于使用了一元運算+。根據一元運算符(+)的官方解釋:+c會顯示地將c轉換為Number類型。
這就是我的代碼出現bug的根源:一元運算符+號嘗試將Details: 轉換為數字,但是失敗了返回NaN。然后NaN又轉換為字符串拼接起來。當我把這個額外的+刪掉后,代碼就正確運行了。
額外建議另外值得一提的是,我使用了gulp-uglify來壓縮我的JavaScript代碼。在構建過程中,一元運算(+"Details: ")已經在壓縮后的代碼中存儲為NaN了。Gulp已經識別出代碼錯誤。
從這一次Debug的經歷吸取了一個教訓:不要馬馬虎虎的拷貝黏貼代碼!而且我立即想到如果有一個小的gulp插件可以識別并提醒壓縮代碼中有莫名其妙的NaN的話,也可以適當避免問題。
補充> parseInt("Details: ")
NaN
> +"Details: "
NaN
版權聲明:
轉載時請注明作者Fundebug以及本文地址:
https://blog.fundebug.com/201...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90224.html
摘要:因為加法的優先級比條件運算符高,所以先運算加號,是字符串拼接,結果是非空字符串,在中字符串的布爾類型為。知識點三目運算為真執行為假執行運算優先級在中布爾類型只有以下種情況為假,其他都為真。 一、測試題 原題:以下代碼的輸出是? var val = false; alert(val is + val ? true : false); 解析: 1. 此題考察的知識點: 三目運算、**運...
摘要:前段時間重構一個頁面,頁面中存在通過第三方代碼插入的動態廣告正常的產品需求,上線后發現第三方的廣告資源存在重復請求的問題。所以,同一個請求會觸發兩次的原因頁面加載時渲染元素會觸發第一次請求,執行代碼導致重新渲染觸發第二次請求。 前段時間重構一個頁面,頁面中存在通過第三方JavaScript代碼插入的動態廣告(正常的產品需求),上線后發現第三方的廣告資源存在重復請求的問題。由于控制廣告插...
摘要:前段時間重構一個頁面,頁面中存在通過第三方代碼插入的動態廣告正常的產品需求,上線后發現第三方的廣告資源存在重復請求的問題。所以,同一個請求會觸發兩次的原因頁面加載時渲染元素會觸發第一次請求,執行代碼導致重新渲染觸發第二次請求。 前段時間重構一個頁面,頁面中存在通過第三方JavaScript代碼插入的動態廣告(正常的產品需求),上線后發現第三方的廣告資源存在重復請求的問題。由于控制廣告插...
摘要:當前的部分代碼狀態超時再縮小了范圍以后,進一步進行排查。函數是一個很簡單的一次性函數,在第一次被觸發時調用函數。因為上述使用的是,而非,所以在獲取的時候,肯定為空,那么這就意味著會繼續調用函數。 有時候,所見并不是所得,有些包,你需要去翻他的源碼才知道為什么會這樣。 背景 今天調試一個程序,用到了一個很久之前的NPM包,名為formstream,用來將form表單數據轉換為流的形式進行...
閱讀 3965·2021-10-09 09:43
閱讀 2878·2021-10-08 10:05
閱讀 2737·2021-09-08 10:44
閱讀 887·2019-08-30 15:52
閱讀 2815·2019-08-26 17:01
閱讀 3021·2019-08-26 13:54
閱讀 1655·2019-08-26 10:48
閱讀 814·2019-08-23 14:41