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