Javascript 为什么 `null >= 0 && null <= 0` 而不是 `null == 0`?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2910495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:27:42  来源:igfitidea点击:

Why `null >= 0 && null <= 0` but not `null == 0`?

javascriptnullcomparisonequality

提问by C. Lee

I had to write a routine that increments the value of a variable by 1 if its type is numberand assigns 0 to the variable if not, where the variable is initially nullor undefined.

我必须编写一个例程,如果它的类型是number,则将变量的值增加 1,如果不是,则将 0 分配给变量,其中变量最初是nullundefined

The first implementation was v >= 0 ? v += 1 : v = 0because I thought anything not a number would make an arithmetic expression false, but it was wrong since null >= 0is evaluated to true. Then I learned nullbehaves like 0 and the following expressions are all evaluated to true.

第一个实现是v >= 0 ? v += 1 : v = 0因为我认为任何不是数字的东西都会使算术表达式为假,但它是错误的,因为它被null >= 0评估为真。然后我学到了null像 0 一样的行为,并且以下表达式都被评估为真。

  • null >= 0 && null <= 0
  • !(null < 0 || null > 0)
  • null + 1 === 1
  • 1 / null === Infinity
  • Math.pow(42, null) === 1
  • null >= 0 && null <= 0
  • !(null < 0 || null > 0)
  • null + 1 === 1
  • 1 / null === Infinity
  • Math.pow(42, null) === 1

Of course, nullis not 0. null == 0is evaluated to false. This makes the seemingly tautological expression (v >= 0 && v <= 0) === (v == 0)false.

当然null不是0。null == 0被评估为false。这使得看似同义反复的表达是(v >= 0 && v <= 0) === (v == 0)错误的。

Why is nulllike 0, although it is not actually 0?

为什么null像0,虽然它实际上不是0?

回答by CMS

Your real question seem to be:

你真正的问题似乎是:

Why:

为什么:

null >= 0; // true

But:

但:

null == 0; // false

What really happens is that the Greater-than-or-equal Operator(>=), performs type coercion (ToPrimitive), with a hinttype of Number, actually all the relational operators have this behavior.

真正发生的是大于或等于运算符( >=),执行类型强制 ( ToPrimitive),带有提示类型Number,实际上所有关系运算符都有这种行为。

nullis treated in a special way by the Equals Operator(==). In a brief, it only coercesto undefined:

null等号运算符( ==)以特殊方式处理。在简短的,它只强制转换undefined

null == null; // true
null == undefined; // true

Value such as false, '', '0', and []are subject to numeric type coercion, all of them coerce to zero.

值,例如false'''0',和[]被受数字类型强制,它们都强迫到零。

You can see the inner details of this process in the The Abstract Equality Comparison Algorithmand The Abstract Relational Comparison Algorithm.

您可以在抽象平等比较算法抽象关系比较算法中看到这个过程的内部细节。

In Summary:

总之:

  • Relational Comparison: if both values are not type String, ToNumberis called on both. This is the same as adding a +in front, which for null coerces to 0.

  • Equality Comparison: only calls ToNumberon Strings, Numbers, and Booleans.

  • 关系比较:如果两个值都不是 String 类型,ToNumber则在两者上调用。这与+在前面添加 a 相同,对于 null 强制为0

  • 相等比较:仅调用ToNumber字符串、数字和布尔值。

回答by estani

I'd like to extend the question to further improve visibility of the problem:

我想扩展问题以进一步提高问题的可见性:

null >= 0; //true
null <= 0; //true
null == 0; //false
null > 0;  //false
null < 0;  //false

It just makes no sense. Like human languages, these things need be learned by heart.

这没有任何意义。像人类语言一样,这些东西需要用心学习。

回答by Panos Kal.

JavaScript has both strict and type–converting comparisons

JavaScript 有严格比较和类型转换比较

null >= 0;is true but (null==0)||(null>0)is false

null >= 0;是真的但是 (null==0)||(null>0)是假的

null <= 0;is true but (null==0)||(null<0)is false

null <= 0;是真的但是(null==0)||(null<0)是假的

"" >= 0is also true

"" >= 0也是真的

For relational abstract comparisons (<= , >=), the operands are first converted to primitives, then to the same type, before comparison.

对于关系抽象比较 (<= , >=),在比较之前,操作数首先转换为原语,然后转换为相同的类型。

typeof null returns "object"

typeof null returns "object"

When type is object javascript tries to stringify the object (i.e null) the following steps are taken (ECMAScript 2015):

当类型是对象时,javascript 尝试对对象进行字符串化(即 null),将采取以下步骤(ECMAScript 2015):

  1. If PreferredTypewas not passed, let hintbe "default".
  2. Else if PreferredTypeis hintString, let hintbe "string".
  3. Else PreferredTypeis hintNumber, let hintbe "number".
  4. Let exoticToPrimbe GetMethod(input, @@toPrimitive).
  5. ReturnIfAbrupt(exoticToPrim).
  6. If exoticToPrimis not undefined, then
    a) Let result be Call(exoticToPrim, input, ?hint?).
    b) ReturnIfAbrupt(result).
    c) If Type(result)is not Object, return result.
    d) Throw a TypeError exception.
  7. If hintis "default", let hintbe "number".
  8. Return OrdinaryToPrimitive(input,hint).
  1. 如果PreferredType未通过,则hint设为“默认”。
  2. 否则,如果PreferredTypehint字符串,则hint设为“字符串”。
  3. 否则PreferredTypehint数字,让我们hint成为“数字”。
  4. 我们exoticToPrimGetMethod(input, @@toPrimitive)
  5. ReturnIfAbrupt(exoticToPrim).
  6. 如果exoticToPrim不是未定义,则
    a) 令结果为Call(exoticToPrim, input, ?hint?)
    乙)ReturnIfAbrupt(result)
    c) 如果Type(result)不是 Object,则返回结果。
    d) 抛出 TypeError 异常。
  7. 如果hint是“默认”,则hint设为“数字”。
  8. 返回OrdinaryToPrimitive(input,hint)

The allowed values for hint are "default", "number", and "string". Date objects, are unique among built-in ECMAScript object in that they treat "default" as being equivalent to "string". All other built-in ECMAScript objects treat "default" as being equivalent to "number". (ECMAScript 20.3.4.45)

提示的允许值为“default”、“number”和“string”。日期对象在内置的 ECMAScript 对象中是独一无二的,因为它们将“默认”视为等同于“字符串”。 所有其他内置 ECMAScript 对象将 "default" 视为等同于 "number"。( ECMAScript 20.3.4.45)

So I think nullconverts to 0.

所以我认为null转换为0。

回答by jon

I had the same problem !!. Currently my only solution is to separate.

我有同样的问题 !!。目前我唯一的解决办法是分开。

var a = null;
var b = undefined;

if (a===0||a>0){ } //return false  !work!
if (b===0||b>0){ } //return false  !work!

//but 
if (a>=0){ } //return true !

回答by s.hesam

console.log( null > 0 );  // (1) false
console.log( null == 0 ); // (2) false
console.log( null >= 0 ); // (3) true

Mathematically, that's strange. The last result states that "null is greater than or equal to zero", so in one of the comparisons above it must be true, but they are both false.

在数学上,这很奇怪。最后一个结果表明“null 大于或等于零”,因此在上面的比较之一中它必须为真,但它们都为假。

The reason is that an equality check ==and comparisons > < >= <=work differently. Comparisons convert null to a number, treating it as 0. That's why (3) null >= 0is trueand (1) null > 0is false.

原因是相等检查==和比较的> < >= <=工作方式不同。比较将 null 转换为数字,将其视为0. 这就是为什么 (3)null >= 0true和 (1)null > 0false

On the other hand, the equality check ==for undefinedand nullis defined such that, without any conversions, they equal each other and don't equal anything else. That's why (2) null == 0is false.

另一方面,==undefined和的相等性检查null被定义为,在没有任何转换的情况下,它们彼此相等并且不等于其他任何东西。这就是为什么 (2)null == 0false