让我们获得技术。我将用ECMAScript Standard 262中的引号来解释逻辑。
表达式[] ? 1 : 2
很简单:
11.12 条件运算符 (? : )
- 令 lref 为评估 LogicalORExpression 的结果。
- 如果ToBoolean(GetValue(lref))为真,则
- 令 trueRef 为评估第一个 AssignmentExpression 的结果。
- 返回 GetValue(trueRef)。
- 别的
- 设 falseRef 为计算第二个 AssignmentExpression 的结果。
- 返回 GetValue(falseRef)
9.2 ToBoolean
- 未定义:假
- 空:假
- 布尔值:结果等于输入参数(无转换)。
- 数字:如果参数为 +0、0 或 NaN,则结果为假;否则结果为真。
- String:如果参数为空字符串(长度为零),则结果为假;否则结果为真。
- 对象:真
所以这是真的。
现在来看看使用双等号运算符时会发生什么。也许这将有助于解释为什么你不应该这样做。
== 的行为在第 11.9.3 节:抽象相等比较算法中进行了解释。
对于 x == y 其中 x = [] 和 y = false,会发生这种情况:
11.9.3:抽象等式比较算法
如果 Type(y) 为 Boolean,则返回比较结果 x == ToNumber(y)
9.3 ToNumber
如果参数为
false ,则结果为+0。
现在我们有 [] == 0
11.9.3:抽象等式比较算法
如果 Type(x) 是 Object 并且 Type(y) 是 String 或 Number,则返回比较结果ToPrimitive(x) == y。
9.1 ToPrimitive
返回对象的默认值。通过调用对象的[[DefaultValue]] 内部方法检索对象的默认值,并传递可选提示 PreferredType。本规范为 8.12.8 中的所有原生 ECMAScript 对象定义了 [[DefaultValue]] 内部方法的行为。
8.12.8 默认值:
当 O 的 [[DefaultValue]] 内部方法在没有提示的情况下被调用时,它的行为就好像提示是Number
- 令 valueOf 为使用参数“valueOf”调用对象 O 的 [[Get]] 内部方法的结果。
- 如果 IsCallable(valueOf) 为真,则
- 令 val 为调用 valueOf 的 [[Call]] 内部方法的结果,其中 O 作为 this 值和一个空参数列表。
- 如果 val 是原始值,则返回 val
- 令 toString 为使用参数“toString”调用对象 O 的 [[Get]] 内部方法的结果。
- 如果 IsCallable(toString) 为真,则
- 令 str 为调用toString的 [[Call]] 内部方法的结果,其中 O 作为 this 值和一个空参数列表。
- 如果 str 是原始值,则返回 str。
我假设这首先尝试 valueOf 然后拒绝它,因为结果与您开始使用的数组相同。然后它在 Array 上调用 toString,这似乎被普遍实现为一个逗号分隔的值列表。对于像这样的空数组,这会导致空字符串。
现在我们有 '' == 0
11.9.3:抽象等式比较算法
如果 Type(x) 是 String 且 Type(y) 是 Number,则返回比较结果ToNumber(x) == y
9.3.1 ToNumber 应用于字符串类型
为空或仅包含空格的 StringNumericLiteral 将转换为+0。
现在我们有 0 == 0
11.9.3:抽象等式比较算法
如果 x 与 y 的数值相同,则返回 true
惊人的。这是真的。到达这里的方式相当复杂。