为什么1 == 1 == 1返回true,"1"=="1"=="1"返回true,"a"=="a"=="a"返回false?

chr*_*ong 115 javascript

function a() { return (1 == 1 == 1); }
function b() { return ("1" == "1" == "1"); }
function c() { return ("a" == "a" == "a"); }
Run Code Online (Sandbox Code Playgroud)

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

为什么会这样?

Jon*_*Jon 185

因为您将第一个相等的(布尔)结果与(非布尔)第三个值进行比较.

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

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

function a() { return (true == 1); }
function b() { return (true == "1"); }
function c() { return (true == "a"); }
Run Code Online (Sandbox Code Playgroud)

这些比较按照这些规则工作(强调我的):

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

所以发生的事情c是将"a"其转换为数字(给定NaN)并严格比较结果以true转换为数字(给定1).

由于1 === NaNIS false,第三函数返回false.很容易理解前两个函数返回的原因true.

  • 还值得一提的是,使用严格相等(`===`)运算符可以防止"1"的这种意外行为 (27认同)
  • @KonradGadzina:严格等于将使所有三个函数返回`false`. (12认同)
  • @Flater:不.我上面引用的段落非常清楚究竟发生了什么("如果任一操作数是一个数字*或一个布尔值*" - 左侧操作数*是*boolean).你也很容易看出你的断言是错误的:`1 == 1 =="true"`=>`false`. (5认同)

Von*_*ion 26

因为 1 == true

"a" != true

所以基本上会发生什么

1 == 1,"1" == "1"并且"a" == "a"都被评估为true然后与下一个值进行比较.

字符串在被比较之前"1"被转换为数字(1)true,因此也被认为是等于true.

现在,"为什么?!?!" 问题的解释是,Javascript的根源在于C语言系列.其中除0之外的任何数字都被认为是有效的true布尔值.: - /

  • JavaScript肯定不会**它的根源在C语言系列*.它源于LISP方言,如Scheme,并受到Self的启发.它只使用C的语法,但不使用它的语义.恕我直言,这是对JavaScript最普遍和最错误的误解之一.为了强调这一点,请查看Douglas Crockford的文章[JavaScript:The World's Most Misunderstood Programming Language](http://javascript.crockford.com/javascript.html). (5认同)
  • 条件中的@MasonWheeler分配不是错误或缺陷. (5认同)
  • @GoloRoden:别傻了.如果JavaScript没有C的语义,那么JS中不存在许多经典的C语义错误,例如`if(x = 5)`......但它们确实存在,就像在C中一样.IT肯定没有*所有*C的语义,但它的行为更像C,而不像任何Lisp. (3认同)
  • @MilesRoul:试着告诉......好吧......*每个被它咬过的人.* (3认同)
  • @funkybro作为专业人士并不意味着事故不可能发生.我已经编程C超过10年了,最近我发现自己在C`开关`语句中忘记了`break;`... (2认同)

La-*_*eja 6

因为1和"1"都转换为true,因为数字."a"不是这种情况.因此:

("1" == "1" == "1") 
Run Code Online (Sandbox Code Playgroud)

评估为

(("1" == "1") == "1") 
Run Code Online (Sandbox Code Playgroud)

评估为

(true == "1")
Run Code Online (Sandbox Code Playgroud)

同样的,

("1" == 1 == "1") 
Run Code Online (Sandbox Code Playgroud)

也是如此,或其任何组合.实际上,转换为布尔值时的任何非零数字都是真的.

然而,"a"并未评估为真.


nom*_*men 5

这是因为JavaScript是一种弱类型的语言.这意味着它不足以表达类型,并且实际上隐含地强制值属于它们没有语义关系的类型.因此,(1 == 1)== 1求值为true,因为(1 == 1)正确计算为true,因此JavaScript计算(true)= 1.特别是,它将1转换为布尔值(或者为真一个数字 - 我忘了哪个,但结果实际上是一样的).

关键是JavaScript正在一种类型的价值转变为背后的另一种价值.

你的问题显示了为什么这是一个问题:('a'=='a')=='a'是假的,因为('a'=='a')是真的,而JavaScript最终比较(true)= ='a'.由于没有合理的方法将布尔值转换为字母(或将字母转换为布尔值),因此该语句为false.当然,这会破坏(==)的引用透明度.