+ -
当前位置:首页 → 问答吧 → 从一道js笔试题到==运算符的简析

从一道js笔试题到==运算符的简析

时间:2010-05-05

来源:互联网

在cssrain整理的一个试题集中有这么一道题:
引用:
<SCRIPT LANGUAGE="JavaScript">
var a = 0;
var b = -1;
var c = 1;
function assert (aVar) {
if (aVar==true)     alert(true);
else     alert(false);
}
assert(a) ;
assert(b) ;
assert(c) ;
</SCRIPT>

<SCRIPT LANGUAGE="JavaScript"> var a = 0; var b = -1; var c = 1; function assert (aVar) { if (aVar==true) alert(true); else alert(false); } assert(a) ; assert(b) ; assert(c) ; </SCRIPT>
 提示:您可以先修改部分代码再运行
按照我的理解,任何非0的数值的布尔值都应该为true。

可是这道题的正确输出为:false false true。

(-1==true)的值为false。

再来看下面这个例子:
引用:
<SCRIPT LANGUAGE="JavaScript">
var a = 0;
var b = -1;
var c = 1;
function assert (aVar) {
if (aVar)     alert(true);
else     alert(false);
}
assert(a) ;
assert(b) ;
assert(c) ;
</SCRIPT>

<SCRIPT LANGUAGE="JavaScript"> var a = 0; var b = -1; var c = 1; function assert (aVar) { if (aVar) alert(true); else alert(false); } assert(a) ; assert(b) ; assert(c) ; </SCRIPT>
 提示:您可以先修改部分代码再运行
运行结果依次为:false,true,true。

在这里,我们发现,if(aVar) 和 if(aVar == true)的结果并不相同。

cssrain在答案中的解释是:
引用:
if(aVar) 和  if (aVar==true) 对负数有截然不同的答案。
真的是负数的原因吗?看下面这个例子:
<SCRIPT LANGUAGE="JavaScript"> alert(2==true); </SCRIPT>
 提示:您可以先修改部分代码再运行
为什么正数2返回的也是false呢。我们将数字转换为boolean值看看。
<SCRIPT LANGUAGE="JavaScript"> alert("2的布尔值为"+Boolean(2)); alert("0的布尔值为"+Boolean(0)); alert("-1的布尔值为"+Boolean(-1)); </SCRIPT>
 提示:您可以先修改部分代码再运行
这里非0数值的布尔值的确都是true,也就是说所有的问题都集中在2==true中的==运算符上。基本可以确定,==一定不是把数字转换为布尔值再进行比较。

看看ECMA-262(第80页)中怎么说的:
引用:
6.If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
7.If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
也就是说,布尔值会被首先转换为数字,然后进行比较。true的数字值为1,false为0。所以2和-1都不能和true相等。

进一步看下面这个例子:
引用:
<SCRIPT LANGUAGE="JavaScript">
var a = "undefined";
var b = "false";
var c = "";
function assert (aVar) {
if (aVar==true)     alert(true);
else     alert(false);
}
assert(a);
assert(b);
assert(c);
</SCRIPT>

<SCRIPT LANGUAGE="JavaScript"> var a = "undefined"; var b = "false"; var c = ""; function assert (aVar) { if (aVar==true) alert(true); else alert(false); } assert(a); assert(b); assert(c); </SCRIPT>
 提示:您可以先修改部分代码再运行
按照前面的思路,true会被转换为1,所以三个语句都会返回false。运行一下,发现的确如此。

下面将if(aVar==true)改为if(aVar)。
<SCRIPT LANGUAGE="JavaScript"> var a = "undefined"; var b = "false"; var c = ""; function assert (aVar) { if (aVar) alert(true); else alert(false); } assert(a); assert(b); assert(c); </SCRIPT>
 提示:您可以先修改部分代码再运行
这时的运行结果是true,true,false。因为Boolean("undefined")、Boolean("false")、Boolean("")的结果为true,true,false。非空字符串转换为布尔值true。

最后还有一个例子,解释当==两边为字符串和数字时的比较规律。
<SCRIPT LANGUAGE="JavaScript"> var a = "1"; var b = "001"; var c = ""; function assert (aVar) { if (aVar==true) alert(true); else alert(false); } assert(a); assert(b); assert(c); </SCRIPT>
 提示:您可以先修改部分代码再运行
发现没,这个"001"==true是为true的。

因为true先被转换为1了。然后参考ECMA的规则:
引用:
4.If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
5.If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
字符串要被转换为数字,Number("001")的值也为1,所以结果为true。

[ 本帖最后由 afc163 于 2010-5-5 14:51 编辑 ]

作者: afc163   发布时间: 2010-05-05

膜拜楼主!长见识
大凡数据比较 都是低级变高级,简单的变复杂的进行比较,比如 整形和浮点型。
而boolean与整形比较时,估计是因为boolean较低级的原因(猜测)。
以前还真没注意过这方面的问题,感谢楼主。。。。

作者: yf1983321   发布时间: 2010-05-05

很透彻,支持!

作者: 3235183   发布时间: 2010-05-05

看不太懂,看到頭痛了。先做個記號,有時間來研究一下

作者: 泥巴巴   发布时间: 2010-05-05

支持一个  楼主学习的比较透彻

作者: redky   发布时间: 2010-05-05

看了一下,看来基本功还得加强呀。

作者: EraIT   发布时间: 2010-05-05

佩服楼主呀 基础的东西往往容易忽略啊

作者: nba2008   发布时间: 2010-05-05

受教了

作者: gevilhost   发布时间: 2010-05-05

我以前看过一个叫 自动的数据类型转换。估计就是这个问题啦。
不过我要说的是。
我个人觉得在写程序的时候不能这样写。
我们明明知道两个数据类型不一样。还要用==来比较。说明是自己范了错误。
而非其他原因。

作者: idche   发布时间: 2010-05-06

受益非浅 谢谢楼主

所谓语言 也就是按照一定规则 而执行的
如果 运行 结果出忽意料 不是语言本身的问题 而是如何安排的问题

作者: 暗翼飘雪   发布时间: 2010-05-06

今天还真了解了一下,学习呢。

作者: bmcsy   发布时间: 2010-05-06

受教了。。

作者: atrl   发布时间: 2010-05-10

1. 和布尔值进行比较值,先将布尔值转化为Number类型,再比较
2. 数字和字符串比较时,先将字符串转化为Number类型,再比较

ps: 快捷获取布尔值, !!-1 == true
<script type="text/javascript"> alert(Boolean(-1) == true); alert(!!-1 == true); </script>
 提示:您可以先修改部分代码再运行

作者: colinivy   发布时间: 2010-05-10

我觉得楼主把这个事搞麻烦了,==就是比较只有1能得到真,而if(var)是不为假的都是真,这个应该是c/c++的习惯吧…………

作者: radioplayer   发布时间: 2010-05-10

留名先,值得研究

作者: sky94yu   发布时间: 2010-05-10

這個好像搞簡單的事情搞麻煩了.

作者: skybot   发布时间: 2010-05-10

谢谢,学到了知识和方法!

作者: alibaba963   发布时间: 2010-05-24

可能一些程序想复杂了会有点过。

作者: EvenChen   发布时间: 2010-05-24

受益匪浅
有时候这些东西很容易就想当然,但却没能把握住其本质,基础还需加强啊

作者: mchunt   发布时间: 2010-05-29

这个题的问题在于==

如果一个运算数是布尔值,那么需要转化为数字 t:1  f:0
复制内容到剪贴板
代码:
<SCRIPT LANGUAGE="JavaScript">
var b = -1;
function assert (aVar) {
if (aVar==true) {//这里实际在判断  -1==1 ?  而不是 Boolean(aVer)==true
    alert(true);
}else{
     alert(false);
}
assert(b) ;
</SCRIPT>
[ 本帖最后由 jaoooo 于 2010-5-31 11:44 编辑 ]

作者: jaoooo   发布时间: 2010-05-31

呵呵 此帖很好  了解了 == 号的一些不同

作者: AyumiHamasaki   发布时间: 2010-06-08