javascript的类型转换和运算

杰克船长在此 2017-06-18 07:30:27
js世界里,貌似很好用try。。。catch。。。,也不推荐大量的使用。我想大概原因:
- js 里任何类型和数值之间的算数运算,逻辑运算都不会抛异常或者错误。例如 1/0 == Infinity, 0/0 = NaN, [ ] + 1 = '1' 等等
- try。。。catch。。。会在catch里转换到一个新的作用域,catch里面调用本函数或者函数外的对象时,增加了一层作用域的查找,降低了运行效率
- 如果有未知的风险,可以try。。。cache。。。,但是如果你的代码里有大量的try。。。catch。。。,其实说明需要加强coding质量或者重构了。

这里讨论一下js里在运算的时候,如何类型转换(一般是隐式转换)

1. 加法运算
1) 1 + ‘-1‘ //返回 ‘1-1',相加时,只要有一个时字符串,另外一个也会先转换为字符串,结果就是字符串的链接
2) [ ] + 1 // 返回‘1’ 解释:object(或者说引用类型)先转化为基本类型。转化过程:先看对象的valueOf()方法是否返回基本类型,这里[ ]的valueOf返回数组本身,它是object类型,不是基本类型。那么再看toString方法。[ ]的toString返回空字符。再加 1,参考第一条规则,返回字符串‘1’
3) [ ] + { } //返回[object Object] 解释:参与运算的对象先转换为基本类型。参考规则2, 空数组转为空字符串。{ }转换时,先看{}.valueOf (你也可理解为Object.prototype.valueOf.call({}) ,因为 {}就是object类型,var obj = { }和var obj = new Object()效果一样,但推荐前者,即字面量的方式)。 对象的valueOf返回本身,故而还是对象。所以就调用toString。空对象{}.toString() = ‘[object Object]'。这样结果变成 '' + '[object Object]' = '[object Object]'
4) 1 + null //返回1. 因为已经是基本类型,而且没有字符串,所以会基于number类型运算。 null转为0, 结果是 1 + 0 =1
5) 1 + undefined //返回NaN, undefined 转为NaN, 1+ NaN = NaN
6) false + null // 都是基本类型而且没有字符串,所以基于数字类型相加。 false 转为0, null也为0. 结果0 + 0 = 0

2. 加法以外的算数运算
如果有对象类型(包括数组),先转为基本类型。转换过程也是先看valueOf是否返回基本类型,如果不是就调用toString的值(这里假定toString都返回string。除非谁闲着没事,非得给一对象的toString返回对象类型?)
和加法运算不同的是,转换为基本类型后,所有的基本类型再转为number类型,最终以number类型进行运算。

1)1 - '-1' //‘-1’转为number的-1, 结果1 - (-1) = 2
2)[ ] - 1 //[ ]先转为基本类型,是空字符。空字符再转为number 为0 ,结果是0 - 1 = -1
3)[ ] / { } //空数组转为基本类型是空字符,空对象转为基本类型是[object Object],二者再分别转为数字类型是 0 和 NaN,最终结果为0/NaN = NaN
4) 1 / null //都已经为基本类型,所以只要把null转为number类型的0, 然后1 / 0 = Infinity
5) 1 * undefined //都已经为基本类型,所以只要把undefined转为number类型的NaN, 然后1 * NaN = NaN

3 . 逻辑运算
1) 1 && null // null. 因为1 是真值,则返回第二个值, 即null
2) null && undefined // 返回null,因为null是falsy,则返回第一个。
3) 0 || {} //返回 {}. 因为0 是falsy,返回第二个。
4) 1 || null //返回1, 因为1是真值,返回第一个

4. 位运算
~n = -( n+1)
例如~25 = -26
这里是带符号的取反。如果是无符号的取反,结果就不一样了,有兴趣的可以在C语言里试试 ~25u
~null = -1 // null转为0, ~0 =-1
~undefined //SyntaxError: Invalid or unexpected token //undfined转为NaN ~NaN出错

~~23.5 = 23
~~-23.5 = -23
但 Math.floor(-23.5) = -24
故而一般用~~取整数位

5. If 运算
if(-1) 和if (-1 == true) 是不一样的。前者是真假判断,-1是truthy。 后者类似算术运算,先转为number, true 转为 1, 故而 -1 == 1 不成立的

这里总结了js类型转换和运行的基本规律,希望是可以满足基本的项目需要了。
...全文
162 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
杰克船长在此 2017-06-18
  • 打赏
  • 举报
回复
js确实是让人挠头的语言,尤其本帖中提到的类型转换和运算。我猜想可能是js产生的时候,web方兴未艾,web工程师的编程功底还没有很规范(至少不像今天这么多资料书籍和培训机构等等),所以js做了大量的不同类型之间的兼容和转换,保证不抛异常或者尽量少抛。但是现在前端和后端一样的庞大了,显然js的这样那样的技法往往会使初级不太熟练的工程师掉入陷阱。故而出现了typescript这类,一个目的是也是帮助初级工程师写出还可以的代码(当然另外一个目的估计是降低后端开发者写前端代码的门槛和思维转变)从这角度解读,ts基本是满足工程和公司的需要,如果做学术研究和深入js学习,肯定是原生的js (es5/6)
杰克船长在此 2017-06-18
  • 打赏
  • 举报
回复
附录: - Js类型 undefined null number Infinity 0 -0 -Infinity NaN string object //字面量 {} function Array // 字面量 [] Date Error RegExp (字面量 / /) symbol //(es6) number类型转换规则举例; '12' => 12 '12abc‘ => NaN null => 0 undefined => NaN false => 0 true => 1 {} => 值类型‘’=> 0 boolean类型转换规则举例 0/-0/NaN => false null/undefined => false '' => false ' ' => true object => true [] => true //注意但是 [] == true却是返回false,因为==会基于算术运算做类型转化 [] => ''=>0, true=>1

87,994

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧