2010-05-26 2 views
104

Мне пришлось написать процедуру, которая увеличивает значение переменной на 1, если ее тип равен number и присваивает 0 переменной, если нет, где переменная изначально null или undefined.Почему `null> = 0 && null <= 0`, но не` null == 0`?

Первая реализация была v >= 0 ? v += 1 : v = 0, потому что я думал, что что-то не число сделает арифметическое выражение ложным, но это было неправильно, так как null >= 0 оценивается как true. Затем я узнал, что 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 оценивается в ложь. Это делает кажущееся тавтологическое выражение (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

+0

Оператор PHP '==' действительно работает специальным образом. –

+0

Если вам нужно было начинать считать с 1 вместо 0, существует очень простой способ увеличить счетчики, которые изначально либо «null», либо «undefined»: 'c = - ~ c // Результаты в 1 для null/undefined; увеличивается, если уже номер –

ответ

160

Ваш реальный вопрос, кажется, быть:

Почему:

null >= 0; // true 

Но:

null == 0; // false 

Что происходит на самом деле является то, что Больший чем или равно Оператор (>=), выполняет принуждение типа (ToPrimitive), с подсказкой тип Number, на самом деле все реляционные операторы имеют такое поведение.

null обрабатывают особым образом по Равно Оператор (==). В кратком, это только принуждает к undefined:

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

Ценности таких как false, '', '0' и [] подлежат числовое типа принуждения, все они принуждают к нулю.

Вы можете увидеть внутренние детали этого процесса в The Abstract Equality Comparison Algorithm и The Abstract Relational Comparison Algorithm.

В Резюме:

  • Relational сравнения: если оба значения не типа String, 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 объясните мне –

+0

мне ответ не дает * ответ * - 'null обрабатывается особым образом Оператор равенства (==). Вкратце, он только принуждает к неопределенности: '- и что? Можете ли вы объяснить, почему «null> = 0'? :) –

+0

@bharathmuppa @ андрей-Дейнеко: Остальные ответ CMS находится здесь: [Реферат Relational алгоритм сравнения] (http://www.ecma-international.org/ecma-262/5.1/#sec -11.8.5) , который объясняет в пункте 3. что, если оба значения не являются строковыми, для обоих вызывается ToNumber. Это то же самое, что добавление '+' спереди, которое для нулевых когерентностей равно '0'. Равенство только вызывает ToNumber для строк, чисел и булевых. –

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 пытается stringify объект (то есть нуль) следующие шаги (ECMAScript 2015):

  1. Если PreferredType не был принят, пусть hint быть «по умолчанию ».
  2. Else if PreferredType is hint String, let hint be "string".
  3. Else PreferredType is hint Номер, пусть hint будет «номером».
  4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
  5. ReturnIfAbrupt(exoticToPrim).
  6. Если exoticToPrim не является неопределенным, то
    a) Пусть результат будет Call(exoticToPrim, input, «hint»).
    б) ReturnIfAbrupt(result).
    c) Если Type(result) не объект, верните результат.
    d) Выбросить исключение типаError.
  7. Если «hint» является «стандартным», пусть hint будет «числом».
  8. OrdinaryToPrimitive(input,hint).

Допустимые значения для подсказок: «по умолчанию», «число» и «строка». Объекты Date уникальны среди встроенных объектов ECMAScript в том смысле, что они рассматривают значение по умолчанию как эквивалентное «string». Все другие встроенные объекты ECMAScript относятся к «по умолчанию» как эквивалентные «числу». (ECMAScript 20.3.4.45)

Так что я думаю, что null превращается в 0.

Смежные вопросы