5 回答
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]
那么当浏览器在遇到 { 时,是把它当表达式还是语句来解析呢?测试下就知道了:
很明显是当成语句来解析的,如果当成一个空对象的表达式来解析,那么空对象是有 toString 方法的,再不济,也应该是返回 undefined(非严格模式,浏览器端);在这种表达式和语句有歧义的地方,一般加个 () 就可以将语句转为表达式,所以,下图是不报错的,并且返回正确:
那么继续,既然是 { 当成语句来解析,那么{}+[]实际相当于语句{}后面跟了一条无关紧要的表达式而已+[],也就是这样:
{}
+[];
所以题主在控制台执行{}+[],实际上是返回了最后一条语句的结果+[],为什么这个结果是 0 呢?
这是一元加操作符,高程上这么说:
在对非数值应用一元加操作符时,该操作符会像Number()转型函数一样对这个值执行转换
所以:{}+[]=>{};+[]; 最终返回 Number([]);
同理:{} + false=>{};+false;,最终返回 Number(false);
完。
TA贡献1744条经验 获得超4个赞
1.复杂对象隐式转换应该是调用toString方法了,空数组toString就是空字符串,空对象toString就是"[object, Object]"。
2.那个花括号写在最前面会单独是当一个块级作用域(es6)来解析了(控制台直接输入{}.toString()是会报错的,就是当作块级作用域了,没有那个方法),由此就相当于 + []了,+号就把它转成number了
3.加括号的话很好理解呀,提高优先级,看成一个整体,就不会把花括号单独解析了
个人见解,不对之处请大神包容指正,谢谢!!
添加回答
举报