

字符串拼接引发的BUG | Fundebug博客
source link: https://blog.fundebug.com/2017/11/20/bug-fix-concatenated-string-trun-into-numbers/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

字符串拼接引发的BUG
译者按: bug 虽小,却是个磨人的小妖精!
本文采用意译,版权归原作者所有
这是一篇很简短的博客,记录了我今天早上花了一个小时才解掉的一个 bug。
在已有的网站页面,我们已经有一段 JavaScript 代码用于构建字符串并把它插入到 DOM 中,如下所示:
function GetTemplate(url, html) {
// 省掉部分细节代码
// ...
var template =
'<div class="something"><a href="' +
url +
'" target="_blank"><strong>Details: </strong><span>' +
html +
"</span></a></div>";
return template;
}
请忽略这段代码的粗糙。接下来,我们的需求很简单:如果summary
存在,那么在<strong>
标签前面添加一个额外的<span>
标签将该值显示出来。是不是很简单?我们来试一试。
我快速实现了如下代码:
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 href="https://thewebsite.com" target="blank">
<span class="summary">The summary</span>NaNThis is the inner message</span></a>
</div>
发现问题了吗?如果没发现,我们接着往下看。
你的线上代码真的没有 BUG 吗?欢迎免费使用Fundebug!我们可以帮助您第一时间发现 BUG!
字符串拼接 vs 加法
仔细查看生成的 HTML 代码,你会发现NaN
出现在</span>
标记的后面,然而<strong>
标签不见了。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 += +"<strong>Details: </strong><span>" + html + "</span></a></div>";
如果你还是没看出来,那么我们换个写法:
template += +"<strong>Details: </strong><span>" + html + "</span></a></div>";
我用了string += +string
这样的写法,也就是说:由于写代码的时候拷贝黏贴,不小心整了一个多余的+
号?所以,相当于使用了一元运算+
。根据一元运算符(+
)的官方解释:+c
会显示地将c
转换为 Number 类型。
这就是我的代码出现 bug 的根源:一元运算符+
号尝试将<strong>Details: </strong><span>
转换为数字,但是失败了返回NaN
。然后NaN
又转换为字符串拼接起来。当我把这个额外的+
删掉后,代码就正确运行了。
另外值得一提的是,我使用了gulp-uglify
来压缩我的 JavaScript 代码。在构建过程中,一元运算(+'<strong>Details: </strong><span>'
)已经在压缩后的代码中存储为NaN
了。Gulp
已经识别出代码错误。
从这一次 Debug 的经历吸取了一个教训:不要马马虎虎的拷贝黏贴代码!而且我立即想到如果有一个小的gulp
插件可以识别并提醒压缩代码中有莫名其妙的NaN
的话,也可以适当避免问题。
> parseInt('<strong>Details: </strong><span>')
NaN
> +'<strong>Details: </strong><span>'
NaN
Recommend
-
61
字符串的拆分1、splitlines 以行切分字符串,可以指定是否保留行标志,0和1代表的是布尔值2、split &am...
-
60
忘了在哪看到一位编程大牛调侃,他说程序员每天就做两件事,其中之一就是处理字符串。相信不少同学会有同感。 几乎任何一种编程语言,都把字符串列为最基础和不可或缺的数据类型。而拼接字符串是必备的一种技能。今天,我跟大家...
-
61
-
70
-
56
二哥,我今年大二,看你分享的《阿里巴巴 Java 开发手册》上有一段内容说:“循环体内,拼接字符串最好使用 StringBuilder 的 append 方法,而不是 + 号操作符。”到底为什么啊,我平常一直就用的‘+’号操作符啊!二哥有空的时候能否写一篇文章
-
21
上一篇文章 跨表更新,看到自己写的SQL像个憨憨 写了关于跨表个更新的内容。一年过的很快,文中后来的两位员工 馮大 和 馮二 也要面对无...
-
23
Benchmark 性能测试: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48...
-
6
GROUP_CONCAT适用于拼接多条数据相同列,需要使用分割符的字符串查询结果.默认使用逗号作为分隔符语法: 必须配合GROUP BY一起使用GROUP_CONCAT(字段)...
-
7
catalog这篇文章没有目录关注本站公众号获取最新福利
-
2
原文链接:Go语言如何高效的进行字符串拼接(6种方式进行对比分析)...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK