Как сделать проверку на null

Обновлено: 08.07.2024

Этот раздел содержит некоторые практические советы и примеры, которые могут быть использованы вами в вашей повседневной работе с NULL .

Проверка на NULL - если это имеет значение

Достаточно часто вам нет необходимости принимать специальные меры для полей или переменных, которые могут быть NULL . Например, если вы делаете так:

очевидно, что вы не хотите видеть клиентов, город которых не указан. Аналогично:

не будут включены люди с неизвестным возрастом, что так же верно и безопасно. Но:

выглядит менее обоснованным: если вы не знаете возраст человека, вы не можете явно лишить его права голоса. Хуже того:

не принесет ожидаемый результат, как и в предыдущем случае. Если кто-то с возрастом NULL имеет реальный возраст до 18, вы предоставите несовершеннолетнему право голоса!

Правильным подходом является явная проверка на NULL :

Замечание

else всегда ссылается на последний if в этом же блоке. Но чаще всего лучше предотвращать путаницу, помещая ключевые слова begin. end вокруг группы строк. Я не сделал этого здесь, чтобы сократить количество строк. И поэтому я был вынужден добавить это примечание. ;-)

Определение, одинаковы ли значения полей

Иногда вы хотите определить, являются ли значения двух полей или двух переменных одинаковыми, и вы будете считать их равными, если они оба NULL . Правильной проверкой для этого является следующая:

или, если вы хотите убрать возможное недопонимание:

Предупреждение. Если только одна из величин A и B является NULL , тестовое выражение станет NULL , а не false! Это нормально для оператора if , и мы даже можем добавить предложение else , которое будет выполнено, если A и B не равны (включая случай, когда одна из величин NULL , а другая - нет):

Однако откажитесь от идеи инвертирования выражения и использования его как проверки на неэквивалентность (как я это однажды сделал):

Приведенный выше код работает корректно, если оба A и B являются NULL или оба не являются NULL . Но в нем не выполняется предложение then , если только одна из частей (A или B) является NULL .

Если вы хотите выполнять что-либо, когда A и B отличаются, вы должны либо использовать корректное выражение, приведенное выше, и поместить пустой оператор в предложение then , или использовать это более длинное выражение для проверки:

Определение изменения значения поля

В триггерах часто бывает полезным знать, что значение определенного поля изменилось (включая переход от NULL к не- NULL значению и наоборот) или осталось тем же самым. Это не что иное, как особый случай использования проверки на (не)эквивалентность значений двух полей. Просто вместо A и B используйте New.ИмяПоля и Old.ИмяПоля:

Замещение NULL значением

Функция COALESCE

COALESCE возвращает первое не- NULL выражение из списка аргументов. Если все выражения являются NULL , она вернет NULL .

Вот как вы можете сконструировать полное имя человека с помощью COALESCE из первого, среднего и последнего имени, предполагая, что среднее имя может иметь значение NULL :

Или для создания наиболее информативного имени, насколько это возможно, из таблицы, которая содержит псевдонимы, и в предположении, что и псевдоним и первое имя могут быть NULL :

Firebird 1.0: функции *NVL

В СУБД Firebird 1.0 не существует функции COALESCE . Однако, вы можете использовать четыре UDF, которые предоставляют бОльшую часть функциональности функции COALESCE . Эти UDF расположены в библиотеке fbudf и называются

iNVL для целочисленных аргументво

i64NVL для агрументов типа bigint

dNVL для агрументов типа double precision

Функции *NVL получают два аргумента. По аналогии с COALESCE , они возвращают первый аргумент, если он не является NULL ; в противном случае они возвращают второй аргумент. Пожалуйста, обратите внимание, что это библиотека для Firebird 1.0 fbudf - и поэтому функции *NVL доступны только для Windows.

undefined а null все время прокрадываются в поток кода. Независимо от того, теряем ли мы ссылку из-за побочных эффектов, забываем назначить ссылочную переменную объекту в памяти или получаем пустой ответ от другого ресурса, базы данных или API – нам постоянно приходится иметь дело со значениями undefined и null в JavaScript.

В этом кратком руководстве мы рассмотрим, как проверить, есть ли переменная undefined или null в JavaScript.

Разница между undefined и null

undefined и null переменные часто идут рука об руку, а некоторые используют эти термины как синонимы. Хотя между ними есть разница:

  • undefined – это переменная, которая относится к чему-то, чего не существует, и переменная не определена как что-либо.
  • null – это переменная, которая определена, но не имеет значения.

Разница между ними, возможно, более ясна через код:

a undefined – он ни к чему не привязан, и нет четкого определения того, что это такое на самом деле. b будет определен как нулевое значение .

Было ли b это прямо определено null или определено как возвращаемое значение функции (которая просто возвращает null значение) не имеет значения – это определено как что-то .

С другой стороны, a это буквально ничего . Никакого задания не было, и совершенно неясно, что оно должно или могло бы быть.

На практике большая часть null и undefined значения возникают из человеческих ошибок при программировании, и эти два идут вместе в большинстве случаев. Проверяя одно – мы обычно проверяем и другое.

Проверка, является ли переменная неопределенной или нулевой

Есть два подхода, которые вы можете выбрать при проверке наличия переменной undefined или null в JavaScript.

Операторы == и ===

Есть разница между оператором свободного равенства ( == ) и оператором строгого равенства ( === ) в JavaScript. Свободное равенство может привести к неожиданным результатам и в этом контексте ведет себя иначе, чем оператор строгого равенства:

Примечание: это не следует рассматривать как доказательство того, что null и undefined являются одним и тем же. Оператор свободного равенства использует “разговорные” определения истинных / ложных значений. 0 , "" и [] оцениваются, поскольку false они обозначают отсутствие данных, хотя на самом деле они не равны логическому.

При этом – поскольку оператор свободного равенства рассматривает null и undefined как одно и то же – вы можете использовать его как сокращенную версию проверки для обоих:

Это проверит, a есть ли null или undefined . Так a как undefined это приводит к:

Хотя мы действительно не знаем, что это такое. Если бы мы использовали строгий оператор, который проверяет, a является ли он null , мы были бы неприятно удивлены, встретив undefined значение в console.log() операторе:

a на самом деле не является null , но есть undefined . В этом случае мы хотели бы проверить их отдельно, но при этом иметь возможность знать настоящую причину потока:

Здесь мы объединили их вместе с помощью исключающего ИЛИ – хотя вы также можете разделить их для разных операций восстановления, если хотите:

Примечание: стоит отметить, что если ссылка не существует, ReferenceError будет выброшено. Этого можно избежать, используя typeof оператор, хотя с точки зрения разработки кода это может быть не лучший выбор. Если вы используете несуществующую ссылочную переменную – молчаливое игнорирование этой проблемы с помощью использования typeof может привести к тихому отказу в дальнейшем.

typeof Оператор

typeof Оператор дополнительно может быть использован вместе с === оператором , чтобы проверить , если тип переменной равна 'undefined' или 'null' :

Однако стоит отметить, что если вы забросите несуществующую ссылочную переменную – typeof с радостью поработает с ней, рассматривая ее как undefined :

Этот код также приводит к:

С технической точки зрения, some_var является неопределенной переменной, так как она не имеет никакого назначения. С другой стороны, это может typeof незаметно привести к сбою и сигнализировать о том, что входящее значение может иметь проблему, вместо того, чтобы вызывать ошибку, которая дает понять, что вы имеете дело с несуществующей переменной.

Например – представьте , что вы сделали опечатку, и случайно ввели somevariable вместо someVariable в if предложении:

Здесь мы пытаемся проверить, someVariable есть ли это null или undefined . Однако из-за опечатки somevariable вместо этого проверяется, и результат:

В более сложном сценарии обнаружить эту опечатку будет сложнее, чем в этом. У нас был тихий провал, и мы можем потратить время на ложный след. С другой стороны, используя только == и === операторы здесь бы уже предупредил нас о несуществующей ссылочной переменной:

Этот код приводит к:

Примечание: это не означает, что typeof это по своей сути плохой выбор, но он также влечет за собой последствия.

Использование Lodash для проверки того, имеет ли переменная значение null , undefined или nil

Наконец, вы можете выбрать внешние библиотеки помимо встроенных операторов. Хотя импорт внешней библиотеки не оправдан только для выполнения этой проверки – в этом случае вам будет лучше просто использовать операторы.

Однако Lodash уже присутствует во многих проектах – это широко используемая библиотека, и когда она уже присутствует, нет потери эффективности при использовании нескольких методов, которые она предоставляет. В частности, Lodash предлагает несколько полезных методов, которые проверяют, имеет ли переменная значение null , undefined или nil .

Установить и импортировать Lodash

Вы можете импортировать Lodash через CDN:

Импортируйте его локально из .js файла:

Или установите через NPM:

Кроме того, его можно импортировать как модуль ES6 или импортировать с помощью require() синтаксиса:

Примечание: это соглашение называть экземпляр Lodash _ , подразумеваемое именем, хотя не обязательно.

Теперь мы можем использовать библиотеку , чтобы проверить , является ли переменная null , undefined или nil – где ноль обозначает оба предыдущих двух напастей. Его можно использовать как сокращенную версию для проверки обоих:

Заключение

В этом кратком руководстве мы рассмотрели , как проверить , если переменная равна нулю, undefined или null в JavaScript, используя == , === и typeof оператор, отметив плюсы и минусы каждого подхода. Наконец, мы кратко рассмотрели использование Lodash – популярной удобной служебной библиотеки для выполнения тех же проверок.

Если мы объявим переменную ссылочного типа и не присвоим её никакого значения, то по умолчанию такой переменной будет присвоено значение null , что будет фактически говорить о том, что переменной значение не присвоено. При этом, типы значений не могут принимать значение null , например, следующий код приведет к ошибке:

Оператор ??

При этом, мы не можем выполнить такую проверку:

Visual Studio сразу выдаст ошибку:

Здесь переменная x представляет тип значений ( int ) и не может принимать значение null , поэтому в качестве левого операнда в операции ?? она использоваться не может.

Оператор условного null

При работе с объектами, которые принимают значение null , довольно часто (особенно новички), могут столкнуться со следующей ошибкой: попытка обратиться к объекту вызывает ошибку, так как этот объект фактически равен null . Например, пусть у нас есть следующая система классов:

Здесь объект User содержит ссылку на объект Phone , который, в свою очередь, содержит ссылку на объект Company . Теоретически, мы можем получить из объекта User название компании, например:

Так как мы использовали конструктор по умолчанию, то свойство Phone не определено (имеет значение null ) и, соответственно, Company тоже равно null . Поэтому, если мы попытаемся получить значение Company , то столкнемся с исключением NullReferenceException . Чтобы избежать такой ошибки мы могли бы использовать условный оператор if для проверки на null свойств у User и Phone , например:

Выражение ?. — это оператор условного null. В коде выше последовательно проверяется равен ли объект user и вложенные объекты значению null и, если на каком-то этапе один из объектов окажется равным null , то companyName будет иметь значение по умолчанию, то есть null . Опять же, чтобы не получать в итоге на выходе null , можно объединить операторы ?? и ?. и написать проверку следующим образом:

Оператор ??=

Оператор ??= используется для присваивания значения правого операнда левому только в том случае, если левый операнд принимает значение null .

Оператор ??= не выполняет оценку своего операнда справа, если его операнд слева имеет значение, отличное от null . Например:

Так как объект numbers имел значение null , то, при использовании оператора ??= будет создан объект типа List и в список будет добавлено число 5 .

Итого

Сегодня мы узнали о значении null и как проводить проверки на null различных объектов ссылочного типа, а также узнали про относительно новый оператор ??= с помощью которого можно присваивать значение объектам ссылочного типа в том случае, если они равны null .

Однако, эта проверка не выполняется, если сам адрес или контакт или человек является нулем.

В настоящее время, одно решение я смог придумать это:

Там чище способ сделать это?

В общем, вы можете использовать дерево выражения и проверить с помощью метода расширения:

Ваш код может иметь больше проблем, чем нужно проверить на null ссылки. Как она стоит, вы, вероятно, нарушает закон Деметры]1.

Закон Деметры является одним из тех эвристик, как Дон'т себе твердить, что поможет вам легко написать код ремонтопригодны. Он говорит программисты ничего не слишком далеко, доступ в стороне от непосредственной области. Например, предположим, у меня есть этот код:

В DoAnAction метод нарушает закон Деметры. В одной функции, он обращается к BusinessCalcualtor , а BusinessData , и десятичное число . Это означает, что если какой-либо из следующих изменений, линии должны быть переработаны:

  • Тип возврата `BusinessCalculator.CalculateMoney () меняется.
  • Тип `BusinessData.Изменения деньги

Учитывая ситуацию было, эти изменения скорее всего произойдет. Если такой код пишется на протяжении всей кодовой базы, внесение таких изменений может стать очень дорого. Кроме того, это означает, что ваш BusinessController сочетается как BusinessCalculator и BusinessData типов.

Один из способов избежать такой ситуации является переписана на такой код:

Теперь, если вы делаете любой из вышеперечисленных изменений, вы только должны выполнить рефакторинг еще один кусок кода BusinessCalculator.Способ CalculateCents () . Вы've также исключены BusinessController 's в зависимости от BusinessData .

Ваш код страдает от подобной проблемы:

Если какие-либо из следующих изменений, вам придется рефакторить основной метод, который я написал или нулевой чек вы писали:

  • Тип IPerson.изменения контакт
  • Тип IContact.изменения адреса
  • Тип `IAddress.изменения города

Я думаю, вам следует рассмотреть более глубокий рефакторинг кода, чем просто переписывать проверку на null.

Что сказал, Я думаю, что бывают случаи, когда соблюдение закона Деметры является нецелесообразным. (Это, в конце концов, эвристики, а не жесткий и быстрый правило, даже если это'называется "Мои права.&и")

В частности, я думаю, что если:

  1. У вас есть некоторые классы, которые представляют собой хранящиеся в слое сохранение вашей программы, и
  2. Вы уверены, что вам не потребуется рефакторинг этих классов в будущем

игнорирование закона Деметры является приемлемым при общении конкретно с этими классами. Это потому, что они представляют данные, приложение работает, поэтому идущие от объекта одного на другой-это способ изучения информации в вашей программе. В моем примере выше, соединение, вызванное нарушение закона Деметры была куда более суровой: я тянулся всю дорогу из контроллера в верхней части моего стека с помощью бизнес-логики калькулятор в середине стека в данных класса, скорее всего, в настойчивости слоя.

Я привожу этот потенциал исключение из закона Деметры, потому что с такими названиями, как человек , контакт , и адрес , классы выглядят, как они могли бы быть данные-слой покос. Если это's в случае, и вы абсолютно уверены, что вы никогда не будете нуждаться, чтобы переработать их в будущем, вы могли бы быть в состоянии уйти с игнорированием закона Деметры в вашей конкретной ситуации.

В работе с любыми данными то и дело требуется как-то обозначить их отсутствие. Новички зачастую для этой цели используют значение false, которое, по сути, является не отсутствием данных, а определённым значением типа boolean. Для того, чтобы как-то помечать неопределённость или отсутствие данных, существует специальное значение null. Про false, null и прочее уже немало сказано и добавить что-то оригинальное крайне сложно. Но гораздо сложнее бывает найти баг, вызванный неочевидным поведением этих штуковин. Поэтому, вдохновлённый одним таким багом, самым элегантным в моём послужном списке, я решил написать маленькую шпаргалку на эту тему.

  • ей была присвоена константа NULL.
  • ей еще не было присвоено никакого значения.
  • она была удалена с помощью unset().

До этого момента всё кажется простым, но чтобы так оставалось и дальше, при работе с null нужно придерживаться определённых правил.

Математические операции с null

Во всех математических операциях null ведёт себя аналогично int(0):

Проверка переменной на null

Чтобы точно узнать, что переменная содержит null (то есть, ничего не содержит), нужно использовать либо специальную функцию is_null() либо тождественное сравнение ===, а любые другие способы не подойдут:

Проверка null if-выражениях, а так же в функциях empty() и isset()

Тут переменные с null ведут себя абсолютно предсказуемо, как и любые другие ложные значения (которые в if-выражениях приводятся к false). Но нужно помнить, что это не гарантирует нам, что в переменной находится именно null:

Сравнение двух null

В PHP как гибкое, так и тождественное сравнение двух null всегда возвращает false, в отличие от многих других платформ, где сравнение двух неизвестностей возвращает так же неизвестность (то есть, null).

Поведение null при нетождественном сравнении с приведением типов данных

PHP разрешает сравнивать null-ы не только между собой, но и с другими типами данных. При этом не стоит забывать, что гибкое сравнение в php не является транзитивным, то есть, если два значения равны третьему по отдельности, не гарантирует их равенство между собой. Согласно таблицам приведения типов, гибкое сравнение null при помощи оператора == с разными значениями возвращает разные результаты:

Сравнение с null с помощью >, =, PHP -> JavaScript) поведение null может меняться.

Исследование null в JavaScript (а вместе с ним и загадочного undefined) заслуживает отдельной статьи. Главное отличие состоит в том, что, не смотря на приведение типов, null в JavaScript ничему не равен, кроме самого null и этого самого undefined, хотя в if-выражениях и срабатывает аналогично false. А при сравнении с числами он выдаёт ещё более забавные результаты, чем в PHP.

NULL в MySQL, к примеру, действует гораздо более прямолинейно. Он просто при любых действиях с null (даже при сравнении двух null) возвращает null. С его точки зрения, при любых действиях с неизвестностью в результате получится какая-то другая неизвестность :)

Простое правило при работе null, которое помогает избегать проблем

Вообще-то, не стоило читать этот пост. Держать в голове все эти нюансы, которые разные платформы трактуют по-разному, - неблагодарное занятие. Для того, чтобы избежать проблем с null нужно запомнить всего лишь одно правило:

Читайте также: