譯者按: bug雖小,卻是個磨人的小妖精晾捏!
為了保證可讀性蒿涎,本文采用意譯而非直譯。另外惦辛,本文版權(quán)歸原作者所有劳秋,翻譯僅用于學(xué)習(xí)。
這是一篇很簡短的博客胖齐,記錄了我今天早上花了一個小時才解掉的一個bug玻淑。
準(zhǔn)備工作
在已有的網(wǎng)站頁面,我們已經(jīng)有一段JavaScript代碼用于構(gòu)建字符串并把它插入到DOM中呀伙,如下所示:
function GetTemplate(url, html)
{
// 省掉部分細節(jié)代碼
// ...
var template = '<div class="something"><a href="'
+ url
+ '" target="_blank"><strong>Details: </strong><span>'
+ html
+ '</span></a></div>';
return template;
}
請忽略這段代碼的粗糙补履。接下來,我們的需求很簡單:如果summary
存在区匠,那么在<strong>
標(biāo)簽前面添加一個額外的<span>
標(biāo)簽將該值顯示出來干像。是不是很簡單?我們來試一試驰弄。
首次嘗試
我快速實現(xiàn)了如下代碼:
function GetTemplate(url, html, summary) {
// other details removed
var template = '<div class="something"><a href="'
+ url
+ '" target="_blank">';
if(summary) {
template += '<span class="summary">'
+ summary
+ '</span>';
}
template +=
+'<strong>Details: </strong><span>'
+ html
+ '</span></a></div>';
return template;
}
看上去一切OK麻汰,沒有問題。F5
刷新頁面戚篙,看起來不大對:
你知道哪里出問題了嗎五鲫?
由上面的代碼生成的HTML長這樣:
<div class="something"><a target="blank">
<span class="summary">The summary</span>NaNThis is the inner message</span></a>
</div>
發(fā)現(xiàn)問題了嗎?如果沒發(fā)現(xiàn)岔擂,我們接著往下看位喂。
你的線上代碼真的沒有BUG嗎?歡迎免費使用Fundebug!我們可以幫助您第一時間發(fā)現(xiàn)BUG!
字符串拼接 vs 加法
仔細查看生成的HTML代碼乱灵,你會發(fā)現(xiàn)NaN
出現(xiàn)在</span>
標(biāo)記的后面塑崖,然而<strong>
標(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 +=
+'<strong>Details: </strong><span>'
+ html
+ '</span></a></div>';
如果你還是沒看出來,那么我們換個寫法:
template += +'<strong>Details: </strong><span>' + html + '</span></a></div>';
我用了string += +string
這樣的寫法声功,也就是說:由于寫代碼的時候拷貝黏貼烦却,不小心整了一個多余的+
號?所以先巴,相當(dāng)于使用了一元運算+
其爵。根據(jù)一元運算符(+
)的官方解釋:+c
會顯示地將c
轉(zhuǎn)換為Number類型。
這就是我的代碼出現(xiàn)bug的根源:一元運算符+
號嘗試將<strong>Details: </strong><span>
轉(zhuǎn)換為數(shù)字伸蚯,但是失敗了返回NaN
摩渺。然后NaN
又轉(zhuǎn)換為字符串拼接起來。當(dāng)我把這個額外的+
刪掉后剂邮,代碼就正確運行了摇幻。
額外建議
另外值得一提的是,我使用了gulp-uglify
來壓縮我的JavaScript代碼挥萌。在構(gòu)建過程中绰姻,一元運算(+'<strong>Details: </strong><span>'
)已經(jīng)在壓縮后的代碼中存儲為NaN
了。Gulp
已經(jīng)識別出代碼錯誤引瀑。
從這一次Debug的經(jīng)歷吸取了一個教訓(xùn):不要馬馬虎虎的拷貝黏貼代碼狂芋!而且我立即想到如果有一個小的gulp
插件可以識別并提醒壓縮代碼中有莫名其妙的NaN
的話,也可以適當(dāng)避免問題憨栽。
補充
> parseInt('<strong>Details: </strong><span>')
NaN
> +'<strong>Details: </strong><span>'
NaN
版權(quán)聲明:
轉(zhuǎn)載時請注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/11/20/bug-fix-concatenated-string-trun-into-numbers/