一个求布尔值引起的问题

一个求布尔值引起的问题

JavaScript森林里的ToFishes同学问的问题:

ToFishes(446187399) 16:30:47
var str = ” “;//这里有两个空格
alert(str==false);
if(str) {
alert(1);
};

各位,这里会是什么结果?想,不要测试啊

这实际不是很难的问题,但是很多人都回答错了!为什么?因为我们都习惯了知其然,不知其所以然,一般的效果都会做,遇到这样的运算的时候就蒙了,那个str的值是不是false?.我们先来运行一下下:

<script type="text/javascript">
var str = "  ";//这里有两个空格
alert(str==false);
if(str) {
    alert(1);
};
</script>

提示:你可以先修改部分代码再运行。

看了结果如果你也很疑惑,实际上,这个疑惑来自你对运算符不了解,str并不像你看到的那样==false.接下来看看到底是为什么?
我们先来看if条件语句,if在判断表达式的时候,做了一个操作就是将表达式求值后转化为布尔型(ToBoolean)然后进行判断,而这个ToBoolean对表达式值的操作有一套规则,当表达式值为以下情况时的返回结果:

1.Undefined:返回false
2.Null:返回false
3.Boolean:直接判断
4.Number:为+0, −0,or NaN返回false,否则是true.
5.String:如果字符串为空返回false(它的length为0),否则为true.
6.Object:true

我们很容易看出例子中if语句的运行结果.而比较符”==”的比较算法是相当的复杂,不过也很容易可以得到我们想要的答案,顺便提一下,在了解完”==”的比较算法后,强烈建议再看看”===”的算法,这样有助于深刻理解他们的区别,也能够清楚什么时候该用”==”或”===”.好了我们来看下”==”的比较算法:
假设我们有这样的比较:x==y:

1. 如果Type(x)与Type(y)不同, 转到步骤14.
2. 如果Type(x)是Undefined, 返回 true.
3. 如果Type(x)是Null,返回true.
4. 如果Type(x)不是Number, 转到步骤11.
5. 如果x是NaN,返回false.
6. 如果y是NaN,返回false.
7. 如果x和y的数值相同,返回true.
8. 如果x是+0并且y是-0,返回true.
9. 如果x是-0并且y是+0,返回true.
10.返回false.
11.如果Type(x)是String,如果x和y的字符序列相同(相同长度并且对应位置的字符相同)返回true.否则返回false.
12.如果Type(x)是Boolean,如果x和y都为true或都为false返回true.否则返回false.
13.如果x和y引用了相同的一个对象或组合在一起的一组对象(查看ecma262-13.1.2).否则false.
14.如果x是null并且y是undefined,返回true.
15.如果x是undefined并且y是null,返回true.
16.如果Type(x)是Number并且Type(y)是String,返回x==ToNumber(y)的比较结果.
17.如果Type(x)是String并且Type(y)是Number,返回ToNumber(x)==y的比较结果.
18.如果Type(x)是Boolean,返回ToNumber(x)==y的比较结果.
19.如果Type(y)是Boolean,返回x == ToNumber(y)的比较结果.
20.如果Type(x)是String或Number或Type(y)是Object,返回x==ToPrimitive(y)的比较结果.
21.如果Type(x)是Object并且Type(y)是String或Number,返回ToPrimitive(x)==y的比较结果.
22.返回false.

我们看到例子中的情况是符合步骤19的,此时false会被ToNumber(y)转换为+0,然后算法进行了递归,接下来的比较是string和number的对比,步骤跳到了第17,x又被ToNumber(x)转换为+0(字符串转数字的过程是相当的复杂,我也没办法说明了,但是其中有一个重要的规则,决定了这个例子的答案,就是当字符串只包含空格[white space]时,结果会转换为+0).再次递归,最终的结果跳到了步骤7,返回true.
这个问题的最终答案和得到这个答案的过程都描述完毕了,对于文章中提到的转换细节请查阅ecma262文档,每次有什么问题,我就会看看ecma262手册,真的很有帮助,建议大家有时间就看看.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.