偶然看到过一篇文章,将的是javascript对{} 的处理!开头的几个运算把我看的有点迷茫!好了,废话少说,直接上图

不知大家之前有没有了解过,可能自己的能力有限,对于这样的结果,我觉得有点难以理解,so搜素了一些资料,主要的知识点有2处:
1,对于{},javascript有2种不同的解析;
2,四则运算里面一些小的知识点;
好了,我们一点点的来解释下:
1.{},大家通常想到的是什么呢?代码块?对象?是的,这2中理解都是正确的!
{
str:'test'
}
这里我们通常理解为对象直接量;
{
var str='test';
}
这里我们理解为这是一段代码块,我们可以这样理解
if(1){
var str='test';
}
说到这里,大家是否有疑问,编译器是如何处理的呢?
ECMA处理的方式倒是十分的简单:如果一段代码以 '{' 开头的我们就可以理解为代码块!
那么我们上面的理解是不是就有问题了
{
str:'test'
}
那既然都是语句块,那为什么 {str:'test'} 却没有语法错误?
有些文章是这样说的:
其实在这里,str 被解析器理解为了 标签。标签 是用来配合 break 和 continue 语句作定向跳转的。
这里我不是很理解,还要请教各位了
接着说答案:
{}+[] {}开头是当做代码块处理的,所以返回值是0; []+{} {}不是开头是当做直接对象量处理的,结合下面的解释,很容易得出结论 "[object Object]"
下面说第二点:四则运算
首先举个几个栗子:
![]()
这个很简单,应该和我们想的一样的!但是如果加的不是数字,结果会怎么样呢?
![]()
对于上面的结果,不知大家有没有疑惑呢?对为什么a+b='101';而a-b=9 呢,大家注意下旁边的备注类型,"101" 是string,9 是nummber;这是因为"+"也是有二义性的,可以看做是运算符,也可以看到连接符。
只要+两方只要有一方带有字符串,那么就是当做连接符看待;
那么”-“减号又是怎么处理的呢?减号在执行之前,先把自身变成数字,再运算,所以10-1=9,乘除已是如此(这里字符串自身转换成数字,是内部方法,并非parseInt或者parseFloat);
大致规则如下:
"123" ==> 123
" 123" ==> 123
" 123 " ==> 123
"a12" ==> NaN
"1 2" ==> NaN
"1,2" ==> NaN
"1b2" ==> NaN
"12c" ==> NaN
"1.234" ==> 1.234
" 1.234" ==> 1.234
" .234" ==> 0.234
那么除了字符串,其他基本类型,比如undefined,null,boolean,这些是如何运算的呢?记住下面的几个规则就好了
true ==> 1
false ==> 0
null ==> 0
undefined==>NAN
下面来个例子,可否算出结果
var a=[10,11];
var b=1;
console.log(a+b);
console.log(a-b);
console.log(a>b);
console.log(a<b);
你知道结果了吗?好吧,a是array,不是基本数据类型,那么结果是怎么得出的呢?
首先,由于a不是基本数据类型,那么javascript 会对它执行四则或者比较的时候,会预先执行一个叫ToPrimitive的步骤,就是先把数组或者对象转成一个基本类型。
转换的步骤是这样的:
先执行对象的valueOf函数,如果返回一个基本的数据类型,那么直接用这个基本数据类型去做运算;
如果返回的数据仍然不是想要的数据类型,那么在执行toString()方法,如果返回的是基本数据类型,就直接用此数据做运算;
如果都不是,那么就会抛出一个 Cannot convert object to primitive value 的类型错误。
上面的明白了,我们回头去看刚才的例子
![]()
我们最后得到的最后的结果是"10,11"+1,那么结果我们就容易理解了
![]()
看了这么多的例子,这个结果呢
var a={a:1,b:2,c:3};
var b=1;
console.log(a+b);
console.log(a-b);
console.log(a>b);
console.log(a<b);
![]()
哈哈,是不是很好理解了!
来个稍微让你迷惑的例子
var a={a:1,b:2,c:3,valueOf:function(){return 5}};
var b=1;
console.log(a+b);
console.log(a-b);
console.log(a>b);
console.log(a<b);
实际上还是需要执行ToPrimitive这个步骤,只不过这个时候是要把DefaultValue指定为String,所以它转换成字符串是这么 一个顺序:先查看toString(),如果返回基本类型,那么就用这个返回值,如果不是,则查看valueOf(),如果返回基本类型,那么就用它,否 则报typeerror的错误。
和上面讲的四则的ToPrimitive顺序是反着的,大家要注意一下。
总结一下:
- 数组和对象做四则或比较运算,会先查看其valueOf的返回值。
- 返回值不是基本类型(undefined,null,true,false,Number,String)的时候,查看其toString()的值。
- toString的返回值不是基本类型则报错,是则使用返回的值来运算。
- 字符串或者其它非数字的基本类型执行预算的时候会预转为数字,规则在上面写了。
- 如果含有一个字符串,那么加号(+)的意义不再是四则加,而是连字符。
- NaN是个特殊的数字,很多的时候字符串会变成它来进行运算,这个时候得到的结果是无意义的。
- 大小比较和减法类似,如果a-b是个大于0的数字,那么a就大于b,反之亦然。
如有不对之处,还请各位指出!





浙公网安备 33010602011771号