Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么(条件==!条件)在JavaScript中为true?_Javascript - Fatal编程技术网

为什么(条件==!条件)在JavaScript中为true?

为什么(条件==!条件)在JavaScript中为true?,javascript,Javascript,到底为什么这里的条件是真的 var condition = new Boolean(false); if (condition == !condition) alert("The more you know..."); 细分: var condition = new Boolean(false); 这实际上是一个对象,并且条件。valueOf()==false !{}计算结果为false,因为{}为true(已解释) 因此,检查是condition.valueOf()==false,

到底为什么这里的条件是真的

var condition = new Boolean(false);
if (condition == !condition)
    alert("The more you know...");
细分:

var condition = new Boolean(false);
这实际上是一个对象,并且
条件。valueOf()==false

!{}
计算结果为false,因为
{}
为true(已解释)


因此,检查是condition.valueOf()==false,这是真的

只要阅读规范中的逻辑布局,就真的很有帮助,请参阅

首先:

var x = new Boolean(false);
var y = !x;
然后

因为布尔对象不是布尔对象,而是日常对象,
ToBoolean(x)

第1轮:步骤7

如果类型(y)为布尔值,则返回比较结果x== 汤姆伯(y)

第二轮:步骤9

如果类型(x)是Object,类型(y)是String或Number,则返回 比较结果ToPrimitive(x)=y

第三轮:步骤6

如果类型(x)是布尔值,则返回比较结果到数字(x) ==y

最后:步骤1

如果类型(x)与类型(y)相同,则

步骤1c

如果类型(x)为数字,则

步骤1 C iii

如果x与y的数值相同,则返回true

我从中学到的一件事是,忘记直觉,遵循步骤

由于对象是真实的,因此它们的否定是
false
,因此算法中的内容是:

Boolean(false) == false
如果你一步一步走,你会得到:

Boolean(false) == 0  // Step 7
false == 0           // Step 9
0 == 0               // Step 6
true

您正在将对象(LHS)与布尔值
false
(RHS)进行比较


=
运算符根据ECMAScript定义的抽象相等比较算法执行类型强制。11.9.3抽象等式比较算法

与您的代码相关的是该算法的以下要点(其中x是LHS,y是RHS)

7)如果类型(y)是布尔值,则返回比较结果x==ToNumber(y)

请注意,它实际上首先尝试将布尔值转换为数字。
false
布尔值转换为数字
0
,因此现在我们有了这个:

[object Boolean] == 0
如您所见,它递归地进入相同的算法,因为
==
。现在我们将一个对象与一个数字进行比较,下面的一点适用:

9)如果类型(x)是对象,类型(y)是字符串或数字, 返回比较结果ToPrimitive(x)==y

所以在这里,它现在试图将对象强制为其原始值。从9.1 TopPrimitive开始,在对象上调用时:

对象返回对象的默认值。通过调用对象的[[DefaultValue]]内部方法并传递可选提示PreferredType,可以检索对象的默认值。[[DefaultValue]]内部方法的行为由本规范为8.12.8中的所有本机ECMAScript对象定义

因此,您可以看到它需要对象的
[[DefaultValue]]
。这将我们带到8.12.8[[DefaultValue]],在这里它需要一个“提示”。因为它没有收到“提示”,所以它的行为就好像提示是“Number”

当在没有提示的情况下调用O的[[DefaultValue]]内部方法时,它的行为就好像提示是Number

这就引出了以下行为:

使用提示号调用O的[[DefaultValue]]内部方法时,将执行以下步骤:

  • 让valueOf作为调用对象O的[[Get]]内部方法(参数为“valueOf”)的结果

  • 如果IsCallable(valueOf)为真

    a。让val作为调用valueOf的[[Call]]内部方法的结果,其中O作为this值和一个空参数列表

    b。如果val是基本值,则返回val

  • 因此它调用对象上的
    .valueOf()
    方法,将我们带到15.6.4.3 Boolean.prototype.valueOf()

  • 设B为该值的最大值

  • 如果类型(B)是布尔型的,那么让B为B

  • 否则,如果类型(B)是Object,并且B的[[Class]]内部属性的值是“Boolean”,则将B设为B的[[PrimitiveValue]]内部属性的值

  • 否则将抛出TypeError异常

  • 返回b

  • 因此,您可以从步骤3中看到,它将返回对象的
    [[PrimitiveValue]]
    。这就引出了15.6.2.1新的布尔值(value)

    新构造的布尔对象的[[PrimitiveValue]]内部属性设置为ToBoolean(值)

    因此您可以看到,您最终将获得最初传递给构造函数的值的
    ToBoolean
    值,该值为
    false
    。它的
    ToBoolean
    值显然是
    false
    ,因此现在您的比较如下:

    false == 0
    
    由于类型仍然不匹配,因此将转到原始算法中的第6点:

    6)如果类型(x)是布尔值,则返回比较结果tonNumber(x)=y

    现在它想把布尔值
    false
    转换成一个数字。这与上面所做的类似。值
    false
    转换为值
    0
    ,因此现在我们有:

    0 == 0
    
    最后,我们有一个类型匹配的比较,通过比较值,它的行为与严格的
    ==
    对应项相同。显然,
    0
    等于
    0
    ,所以我们得到了
    true



    故事的寓意。。。这是在JavaScript中询问“为什么”时得到的结果。

    @Blender
    new Boolean(false)。valueOf()
    为false
    。valueOf()
    返回基础原语,它不是对象
    (新布尔值(false))==false
    。从文档
    中,新构造的布尔对象的[[PrimitiveValue]]内部属性设置为ToBoolean(value)。
    。那么
    Boolean(false) == 0  // Step 7
    false == 0           // Step 9
    0 == 0               // Step 6
    true
    
    [object Boolean] == false
    
    [object Boolean] == 0
    
    false == 0
    
    0 == 0