Javascript 为什么1==1==1返回true;1“==&引用;1“==&引用;1“;返回true,以及;a「==&引用;a「==&引用;a「;返回错误?

Javascript 为什么1==1==1返回true;1“==&引用;1“==&引用;1“;返回true,以及;a「==&引用;a「==&引用;a「;返回错误?,javascript,Javascript,我在Chrome的控制台中测试了上述代码,出于某种原因,a()返回true,b()返回true,c()返回false 为什么会这样?因为1==true 但是“a”!=正确 所以基本上是这样的 1==1,“1”==“1”和“a”==“a”都被评估为真,然后与下一个值进行比较 字符串“1”在与true进行比较之前被转换为一个数字(1),因此也被认为等于true 现在,“为什么?!?!”的问题可以用Javascript源于C语言家族这一事实来解释。其中除0以外的任何数字都被视为有效的trueboole

我在Chrome的控制台中测试了上述代码,出于某种原因,
a()返回true,
b()返回true,
c()返回false


为什么会这样?

因为
1==true

但是
“a”!=正确

所以基本上是这样的

1==1
“1”==“1”
“a”==“a”
都被评估为
,然后与下一个值进行比较

字符串
“1”
在与
true
进行比较之前被转换为一个数字(
1
),因此也被认为等于
true


现在,“为什么?!?!”的问题可以用Javascript源于C语言家族这一事实来解释。其中除0以外的任何数字都被视为有效的
true
boolean.:-/

因为您正在比较第一个等式的(布尔)结果与(非布尔)第三个值

在代码中,
1==1==1
相当于
(1==1)==1
相当于
true==1

这意味着这三种方法可以更简单地写成:

function a() { return (1 == 1 == 1); }
function b() { return ("1" == "1" == "1"); }
function c() { return ("a" == "a" == "a"); }
这些比较根据(我的重点)进行:

如果两个操作数的类型不同,JavaScript将转换 然后应用严格比较。如果任一操作数为 如果是数字或布尔值,则操作数将转换为数字 可能的;否则,如果任一操作数为字符串,则字符串操作数为 如果可能,转换为数字。如果两个操作数都是对象,则 JavaScript比较操作数相同时的内部引用 引用内存中的同一对象

因此,在
c
中发生的情况是
将a
转换为一个数字(给出),结果是
true
转换为一个数字(给出
1

由于
1===NaN
false
,因此第三个函数返回
false
。很容易理解为什么前两个函数将返回
true

,因为1和“1”都转换为true,作为数字。“a”的情况并非如此。因此:

function a() { return (true == 1); }
function b() { return (true == "1"); }
function c() { return (true == "a"); }
评估为

("1" == "1" == "1") 
(("1" == "1") == "1") 
评估结果是

("1" == "1" == "1") 
(("1" == "1") == "1") 
同样地

(true == "1")
也为真,或其任何组合。事实上,当转换为布尔值时,任何非零数字都是真的


然而,“a”的计算结果不是真的。

确实是
(1==1)==1
。然后它将是
true==1
,但不是在
a==a

中,因为JavaScript是一种弱类型语言。这意味着它的表达能力不足以讨论类型,事实上,它隐式地强制值属于它们没有语义关系的类型。所以,(1==1)==1计算为true,因为(1==1)正确计算为true,所以JavaScript计算为(true)=1。特别是,它将1转换为布尔值(或将真值转换为数字——我忘记了,但结果实际上是相同的)

关键是JavaScript正在背后将一种类型的值转换为另一种类型的值


您的问题说明了这是一个问题的原因:('a'='a')='a'为false,因为('a'='a')为true,JavaScript最终比较(true)='a'。因为只有没有合理的方法将布尔值转换为字母(或将字母转换为布尔值),所以该语句是错误的。当然,这会破坏(=)的引用透明度。

布尔值作为位处理,每个位代表真或假(1代表真,0代表假)

所以1代表真,0代表假

1==1==1将类似于(1==1)==1,true==1,true

而'a'='a'='a'将是('a'='a')='a',true=='a',false


奖金:0==1==0,1==0==0和0==0==1返回true

提示:X==Y==Z被计算为((X==Y)==Z)。奇怪的是,
true==“1”
计算为
true
。相关:为什么(0<5<3)返回true?和的可能重复。@Cupcake:真诚地说,我认为这里的主要问题是,就JS而言,数学上看似正确的等式实际上是错误的,而不是例如
true==1
是正确的。换句话说,aha时刻并没有意识到类型在起作用,而是所有这些类型都在将某些东西与
true
进行比较。我肯定这其中有一个缺点,但在我看来,这并不是你提供的。同样值得一提的是,使用严格相等(
===
)操作符将防止
“1”
@KonradGadzina出现这种意外行为:严格相等将使所有三个函数返回
false
。你是对的。我在这里看到了太多的
true
,我都忘了^^@Jon:
所以在c中发生的是“a”被转换成一个数字(给出NaN)
两个操作数都不是数字。我认为转换的结果是
“true”==“a”
,而不是
1==NaN
@Flater:No。我上面引用的这段话非常清楚地说明了到底发生了什么(“如果任何一个操作数是数字或布尔值”——左侧的操作数是布尔值)。也很容易看出您的断言是错误的:
1==1==“true”
=>
false
。JavaScript肯定不源于C语言家族。它源于Scheme等LISP方言,也受到Self的启发。它只使用C的语法,而不使用它的语义。我认为这是对JavaScript最普遍也是最错误的误解之一。为了强调这一点,请看一下道格拉斯·克罗克福德的文章。@GoloRoden:别傻了。如果JavaScript没有C的语义,那么JS中就不会存在一些经典的C语义错误,比如
If(x=5)
。。。但是t