为了账号安全,请及时绑定邮箱和手机立即绑定

js数据类型隐式转换

js数据类型隐式转换

繁华开满天机 2019-03-12 17:13:31
一直没搞懂js的数据类型隐式转换,像下面在控制台输出的例子,不知道是根据什么规则进行转换的:
查看完整描述

5 回答

?
largeQ

TA贡献2039条经验 获得超7个赞

首先对题主放截图不放代码的行为表示强烈谴责!!!


然后摆结果,有歧义的备注//歧义了:


let d1 = false + []; //false

let d2 = [] + false; //false

let d3 = false + {}; //false[object Object]

let d4 = {} + false; //[object Object]false//歧义

let d5 = [] + {}; //[object Object]

let d6 = {} + []; //[object Object]//歧义

let d7 = ({} + []); //[object Object]

let d8 = ([] + {}); //[object Object]


console.log(d1);

console.log(d2);

console.log(d3);

console.log(d4);

console.log(d5);

console.log(d6);

console.log(d7);

console.log(d8);

上面的结果解释起来就一句话,高程:


如果有一个操作数是对象、数值或布尔值,则调用它们的toString()方法取得相应的字符串值,然后再应用前面关于字符串的规则

如果要分析的话,加上下面的就可以了:


[].toString();//""

false.toString();//"false"

let o={};

o.toString();//"[object Object]"

现在再来说,和题主的截图有两个 0 不一致的地方;


首先题主截图没问题,我测试了,我上面的结果也没问题,也测试了;但是在平常应用中,应该遇不到那种情况,比方说 {}+[]


如果你用来赋值,不会得到 0;;

如果你用来判断 if(),也不会得到 0;;

甚至,function f(){ return {}+[];} f() 执行也不会得到 0;

然后我们来说原因,经过上面的例子,你怕也知道了为什么会不一致了;


赋值=、if()、return 后面跟的都是表达式,上述歧义的括号版本,返回的就是预期内的数据,因为括号里放的也是表达式;


{} + false//0

{} + []//0

({} + [])//[object Object]

([] + {})//[object Object]

那么当浏览器在遇到 { 时,是把它当表达式还是语句来解析呢?测试下就知道了:


https://img1.sycdn.imooc.com//5c8ca0f40001122902590075.jpg


很明显是当成语句来解析的,如果当成一个空对象的表达式来解析,那么空对象是有 toString 方法的,再不济,也应该是返回 undefined(非严格模式,浏览器端);在这种表达式和语句有歧义的地方,一般加个 () 就可以将语句转为表达式,所以,下图是不报错的,并且返回正确:


https://img1.sycdn.imooc.com//5c8ca0f700014ea602400071.jpg


那么继续,既然是 { 当成语句来解析,那么{}+[]实际相当于语句{}后面跟了一条无关紧要的表达式而已+[],也就是这样:


{}

+[];

所以题主在控制台执行{}+[],实际上是返回了最后一条语句的结果+[],为什么这个结果是 0 呢?


这是一元加操作符,高程上这么说:


在对非数值应用一元加操作符时,该操作符会像Number()转型函数一样对这个值执行转换

https://img1.sycdn.imooc.com//5c8ca10000019fc001010046.jpg


所以:{}+[]=>{};+[]; 最终返回 Number([]);


同理:{} + false=>{};+false;,最终返回 Number(false);


完。

JavaScript高级程序设计-第3版-中


查看完整回答
反对 回复 2019-03-16
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

1.复杂对象隐式转换应该是调用toString方法了,空数组toString就是空字符串,空对象toString就是"[object, Object]"。
2.那个花括号写在最前面会单独是当一个块级作用域(es6)来解析了(控制台直接输入{}.toString()是会报错的,就是当作块级作用域了,没有那个方法),由此就相当于 + []了,+号就把它转成number了
3.加括号的话很好理解呀,提高优先级,看成一个整体,就不会把花括号单独解析了

个人见解,不对之处请大神包容指正,谢谢!!


查看完整回答
反对 回复 2019-03-16
?
炎炎设计

TA贡献1808条经验 获得超4个赞

可以参考文章js隐式装箱ToPrimitive


查看完整回答
反对 回复 2019-03-16
  • 5 回答
  • 0 关注
  • 594 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信