2010-05-26 120 views
104

我必须编写一个例程,如果其类型为number,则将变量值增加1,如果不是,则将0赋值给变量,其中变量最初为nullundefined为什么`null> = 0 && null <= 0`但不是`null == 0`?

第一个实现是v >= 0 ? v += 1 : v = 0,因为我认为任何不是数字都会使算术表达式为false,但由于null >= 0的计算结果为true,因此它是错误的。然后我学会了null的行为如同0,下面的表达式都被评估为true。

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

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

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

+3

他正在谈的JavaScript。你的例子是在PHP中。在PHP中,运算符==以特殊方式比较值。你可以做一些非常疯狂的比较,比如“10”==“1e1”(这是真的)。如果使用operator ===,则会得到完全不同的结果,因为它会检查类型是否与值相匹配。查看此链接:http://www.php.net/manual/en/language.operators.comparison.php – Pijusn 2012-04-06 05:59:12

+0

PHP'=='运算符确实以“特殊”方式工作。 – 2014-03-19 03:26:01

+0

如果您的要求是从1开始计数而不是0,那么增加最初为'null'或'undefined'的计数器的方法非常简单:c = - 〜c //结果为1 for null/undefined;如果已经有一个数字,则增加' – 2017-09-12 16:24:37

回答

160

你真正的问题似乎是:

为什么:

null >= 0; // true 

但是:

null == 0; // false 

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

nullEquals Operator==)以特殊方式处理。在简短的,它只胁迫undefined

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

值,如false'''0',并且[]受到数值类型转换,所有的人都强迫为零。

您可以在The Abstract Equality Comparison AlgorithmThe Abstract Relational Comparison Algorithm中看到此过程的内部细节。

总结:

  • 关系比较:如果两个值不键入字符串,ToNumber上调用两者。这与在前面添加+相同,对于0为空胁迫。

  • 平等比较:只在字符串,数字和布尔值上调用ToNumber

+1

嗨CMS,根据您的解释null原始为0,所以0> = 0返回true,==返回false.but按照ecma算法如果Type(x)是Object且Type(y)是String或Number , 返回比较的结果ToPrimitive(x)== y.then在这个它应该返回true.please解释我 – 2016-06-07 06:34:53

+0

给我答案不提供*答案* - null null以特殊方式处理等于运算符(==)。简而言之,它只会强制未定义:' - 什么?你能解释一下,为什么'null> = 0'? :) – 2016-06-26 14:01:34

+0

@bharathmuppa @ andrey-deineko: CMS的答案的其余部分在这里: [抽象关系比较算法](http://www.ecma-international.org/ecma-262/5.1/#sec -11.8.5) 它在第3点中解释,如果两个值都不是字符串类型,则同时调用ToNumber。这与在前面添加一个'+'相同,对于'0'为空胁迫。 平等仅在字符串,数字和布尔值上调用ToNumber。 – 2016-08-23 15:32:04

7

我想延长的问题,进一步提高问题的可见性:

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

它只是没有任何意义。像人类语言一样,这些东西需要通过内心学习。

0

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

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 ! 
3

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

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

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

"" >= 0也是如此

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

typeof null returns "object"

当类型是JavaScript的尝试字符串化的对象的对象(即,空)采取 以下步骤(ECMAScript 2015):

  1. 如果PreferredType未通过,让hint是“默认”。
  2. 否则,如果PreferredTypehint字符串,则让hint为“字符串”。
  3. 其他PreferredTypehint数字,让hint为“数字”。
  4. exoticToPrimGetMethod(input, @@toPrimitive)
  5. ReturnIfAbrupt(exoticToPrim)
  6. 如果exoticToPrim未定义,则
    a)令结果为Call(exoticToPrim, input, «hint»)
    b)ReturnIfAbrupt(result)
    c)如果Type(result)不是Object,则返回结果。
    d)抛出TypeError异常。
  7. 如果hint为“默认”,则让hint为“number”。
  8. 退货OrdinaryToPrimitive(input,hint)

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

所以我觉得null转换为0