JavaScript加性操作符引发的常见错误——弱类型天然错误

             很多初学写JS的伙伴,经常会遇到这样的问题:程序设计逻辑通顺,书写正确,但就是无法按预期的设想输出。我在初学写JS程序的时候经常被缠绕进这种BUG之中,往往这样的错误是由于语言基础不过关引起的。

              例如在一个reducer当中有如下代码片段,根据用户输入的num值输出一个rgb函数的字符串调整容器颜色:

              let num = action.num

              let  RGB=(r,g,b)=>{

              return 'rgb'+'('+100-0.34*r+','+100+g+','+100-b+')'

              }

             console.log( RBG(num,num,num))

              调试时发现,例如num=50,输出结果为:

             rgb(50,10050,50)

             令人非常困惑,为何第二个参数会变为10050,应该是一个字符串连接的结果,而第一、第三个参数则可以正常数值计算呢?

            

             原来,首先在接收到的num时类型就是字符串,但我误以为是数字(在reducer之中action返回一个对象,键值对当中都是字符串)。而JavaScript在设计时,加性操作符'+‘的计算逻辑是这样:当操作符两端有一个(str1)是字符串时,则对另一方调用str2.toString()转为字符串后再调用str1.concat(str2)

             形成一个新的连接字符串,即str1+str2。所以就得到了上文代码之中的'10050'。

            

             但是‘-’的逻辑又不一样:当操作符两端有一个(num1)是数字时,则对另一方调用Number(num2)转为数字后再使两个数字相减,即num1-num2,得到了上文代码之中

             的''50'。

             综上,调用程序应该改成:RBG(parseInt(num),parseInt(num),parseInt(num)),使用parseInt()转换num的类型,使计算结果全部是数字类型。

            

            

             顺带发现另一个BUG:更新完对象后,有一定几率无法保存这个rgb结果,但是有时候可以特别是当num=0或100的时候100%可以。

             经过2个小时的追踪,发现可能是因为RGB函数之中第一个参数100-0.34*r的问题,当r变化时这个算式的结果如果是一个小数,rgb()函数参数只能接受0-255范围内的参数,如果输入小数参数会使函数的输出结果不可预料。

             解决办法:对第一个参数整体再进行类型转换

             let  RGB=(r,g,b)=>{

              return 'rgb'+'('+parseInt(100-0.34*r)+','+100+g+','+100-b+')'

              }

            


             总结,js的加性操作符中‘+’具有得到字符串为结果的倾向,而‘-’具有得到数字为结果的倾向,与我们日常数学之中的逻辑不一样,

             并且,在调用一些常见函数时(本例是rgb(r,g,b)函数),一定要严密控制输入参数的规格,到底是整数,小数,参数有没有可能经过计算变为小数或无理数?

  很多BUG都来自于这里,这是弱类型语言的一个特点。


               修正后的正确完整代码:

               let num = action.num

               let  RGB=(r,g,b)=>{

               return 'rgb'+'('+parseInt(100-0.34*r)+','+100+g+','+100-b+')'

              }

              RBG(parseInt(num),parseInt(num),parseInt(num))

              console.log( RBG(num,num,num))

猜你喜欢

转载自blog.csdn.net/weixin_40564006/article/details/78200148
今日推荐