Что выведет следующий код null undefined

Все о null в JavaScript

Как вы уже, наверное, знаете в языке JavaScript реализовано две большие группы типов данных: примитивы (строки, логические значения, числа, символы) и объекты.

Объекты — это сложные структуры данных. Самым простым объектом в JavaScript является объект представляющий собой набор ключей и соответствующих им значений:

Но бывают ситуации, когда объект по разным причинам (отсутствие или некорректные значения аргументов функции и т.д.) не может быть создан. Для таких случаев JavaScript предоставляет специальное значение null , которое указывает на его отсутствие.

В этой статье вы узнаете все о null в JavaScript: о его использовании, как можно определить его присутствие, а также о разнице между null и undefined , и почему использование null создает трудности в сопровождении кода.

1. Концепция null

Спецификация JavaScript говорит следующее о null :

null — примитивное значение, которое представляет намеренное отсутствие какого-либо значения типа объект.

Таким образом, если вы замечаете, что значение null было присвоено переменной или возвращается функцией, то этим значением, в общем случае, должен быть объект, но по какой-то причине он не был создан.

Например, функция greetObject() создает объекты, но также она может возвращать null , если объект не может быть создан:

И так, при вызове функции со строковым аргументом greetObject(‘Eric’) , как и ожидалось, функция возвращает объект < message: 'Hello, Eric!' >.

Однако при вызове функции без аргументов greetObject() функция возвращается null . Возврат в качестве значения null кажется разумным, так как параметр who по сути не имеет значения, и поэтому объект с информацией о приветствии не может быть создан.

1.1 Аналогия null из реального мира

Думая об аналогии с реальным миром, вы можете представить себе переменную как коробку. Точно так же, как переменная может содержать объект, коробка может содержать некоторые предметы, например, чайник.

Но допустим, что вы получаете коробку, открываете ее… а там ничего! Кто-то ошибся и отправил вам пустой ящик. Коробка ничего не содержит или, иначе говоря, содержит значение null .

2. Проверка значения переменной на null

Хороший способ проверить содержит ли значение какой-либо переменной null — использовать оператор строгого равенства :

Соответственно инструкция missingObject === null оценивается как true , так как переменная missingObject содержит значение null .

Если переменная содержит ненулевое значение, например, объект, то инструкция existingObject === null оценивается как false .

2.1 null — это ложное значение (false)

null наряду с false , 0 , » , undefined , NaN , оцениваются условными операторами как ложные значения false . Если в выражениях с условными операторами встречается одно из этих значений, то JavaScript оценивает его как false .

2.2 Тип null

Оператор typeof value определяет тип значения. Например, результатом выполения инструкции typeof 15 является ‘number’ , а результатом выполнения typeof < prop: 'Value' >будет ‘object’ .

Интересно, каков будет результат следующей инструкции кода: type null ?

Хм… как можно определить тип отсутствующего объекта как ‘object’ ? Оказывается, typeof null это тоже ‘object’ , что является следствием ошибки в ранней реализации языка JavaScript.

Не используйте оператор typeof для определения значения типа null . И как упоминалось ранее, используйте для этого оператор строгого равенства myVar === null .

Если вы хотите проверить, содержит ли переменная объект с помощью оператора typeof , то необходимо также предусмотреть проверку на присутствие значения null :

3. Ловушка null

Значение типа null может неожиданно появиться, в тех случаях, когда вы ожидаете объект. И далее, если вы попытаетесь получить значение какого-либо свойства объекта из значения null , то интерпретатор JavaScript выдаст ошибку.

Давайте снова воспользуемся функцией greetObject() и попробуем получить доступ к свойству message у возвращенного объекта:

Поскольку переменная who является пустой строкой, то функция возвращает в качестве значения null . При доступе к свойству message у null соответственно получаем ошибку типа TypeError.

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

4. Альтернативы использованию null

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

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

При написании кода я стараюсь не возвращать в функциях null , а вместо этого:

  • возвращать вместо null объект по умолчанию;
  • генерировать вместо возврата null исключение соответствующего типа.

Давайте вернемся к функции greetObject() , возвращающей объект с информацией о приветствии. Вместо возврата null в случае отсутствия при ее вызове значения аргумента, мы можем вернуть объект по умолчанию следующим образом:

Либо возбуждать исключение с выводом соответствующего сообщения об ошибке:

Рассмотренные практики написания кода позволяют вам не использовать null вообще, и избежать проблем с отладкой и сопровождением вашего кода в будущем.

5. null vs undefined

undefined — соответствует значению неинициализированной переменной или свойства объекта.

Например, если вы объявляете переменную без присвоения начального значения, то результатом операции доступа к ее значению переменной будет undefined :

Основное различие между null и undefined заключается в том, что значение null интерпретируется как отсутствие в качестве значения некоторого объекта, а — undefined как неинициализированное состояние переменной или возвращаемого значения.

Использование оператора строгого равенства позволяет === позволяет различать значения null и undefined :

В то время как оператор нестрогого равенства == определяет, что null и undefined эквивалентны:

Использование оператора нестрого равенства для проверки, содержит ли переменная null или undefined приведет к получению следующего результата:

6. Заключение

null — специальное значение, реализованное в языке JavaScript, которое соответствует отсутствию объекта, который ожидается в качестве значения переменной или должен возвращаться функцией.

Оператор строгого равенства позволяет определить содержится ли в переменной null : variable === null .

Оператор typoef полезен для определения типа переменной (число, строка, логическое значение). Однако его использование вводит в заблуждение в случае появления значения null , так как результатом выполнения инструкции typeof null будет ‘object’ .

Значения null и undefined в какой-то степени эквивалентны, тем не менее, null представляют собой отсутствующее значение типа объект, а undefined неинициализированное состояние переменной или значения возвращаемого функцией.

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

А какое условие вы используете для проверки на null ?

Источник

undefined

undefined возвращается, если переменная была объявлена, но значение переменной не было установлено.
Например:

В логе мы видим undefined :

undefined также может возникнуть, если свойство объекта не существует.

или функция имеет отсутствующий параметр:

undefined — примитивный тип данных в Javascript:

Проверить тип можно с помощью ключевого слова typeof :

undefined может быть задан явно:

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

Схожие черты

Давайте посмотрим на их сходства.

И то, и другое — это ложные (false) значения.

null и undefined типы всегда преобразуется в значение false . Они относятся к числу ложных значений в JS:

  • null
  • undefined
  • false
  • 0
  • Пустая строка -> «»
  • NaN

Если они находятся в условии оператора if-else , оператор else всегда будет выполняться:

Вышеприведенное выведет Нет.

также выведет Нет.

Оба являются примитивными значениями

В Javascript есть сложные и примитивные типы данных, null и undefined — среди примитивных типов данных:

  • null
  • undefined
  • Symbol
  • String
  • Number
  • Boolean

Примитивные типы данных обрабатываются по значению.

Различия

null и undefined означают нет значения , но имееют разные значения в определении типа:

Вы ожидали, что тип null вернет «null«? Правда? Это ошибка в JS существует уже на протяжении почти двух десятилетий, но дело в том, что она не может быть исправлена. Потому, что тысячи сайтов зависят от такого неправильного поведения, исправление которого приведет к их поломке.

null — это назначаемое значение, т.е. должно быть явно назначено программистом. Если переменная не назначена, она становится undefined :

в отличие от undefined , которые могут быть явно назначены или не назначены:

Тесты для null

Как мы уже видели, undefined преобразовывается в » undefined «, а null преобразовывается в » object «.

Мы можем легко проверить на undefined:

Для null, мы не можем этого сделать:

typeof null возвращает » object «, и у нас может возникнуть соблазн переписать все вышеперечисленное следующим образом:

Но многие сложные типы данных возвращают объекты, тип может быть проверен через typeof :

Таким образом, он не сработает, потому что массив или объект может быть значением test . Теперь, как правильно проверить на null, поскольку null — это значение false , мы объединим его проверку с проверкой на тип.

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

Сравнение равенств

Не строгое сравнение:

  • Если x равен null, а y undefined, возвращается true.
  • Если x undefined, а y равен null, возвращается true.

Строгое сравнение:

Сравнение x === y , где x и y являются значениями, дает true или false. Такое сравнение выполняется следующим образом:

  1. Если тип(x) отличается от типа(y), то возвращается false.
  2. Если тип(x) равно Number, то:
    • Если x — NaN, возвращается false
    • Если y — NaN, то возвращайтся false.
    • Если x равно значению того же числа, что и y, то возвращается true
    • Если x равно +0, а y равно -0, то возвращается true
    • Если x равно -0, а y равно +0, то возвращается true

Здесь будет false , потому что типы являются object и undefined , видно, что они разные, поэтому возвращается false .

будет false. Почему? Потому, что null => object не тот же тип, что и undefined => undefined.

Поймите, оператор !== спрашивает, не строго ли совпадает x c y ? Итак, в нашем случае да (true) объект x (null => object) не является строго равным y (undefined => undefined).

Тут проверяется, не совпадает ли x с y . В данном случае нет (возвращает false ), так как они равны, потому что Javascript возвращает true, если x является либо null , либо undefined и y является либо null , либо undefined .

Передача null и undefined в качестве аргумента функции

Мы должны быть осторожны при объявлении значения аргумента по умолчанию таким образом:

Эта функция просто возвращает переданное ей имя, видим, что имя аргумента имеет значение по умолчанию test_name , аргумент будет принимать test_name в качестве значения, когда функция вызывается без параметров:

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

А что будет, если мы перейдем в функцию null ? Как вы думаете, он будет выводить test_name , потому что null означает отсутствие значения, или он будет записывать null, потому что null — это значение? Посмотрим:

Ничего себе! Вывелось null . Должно быть, потому что null — это object . Я бы сказал, пустой объект, но все же представляющий собой отсутствие значения.

Если вы пытаетесь проверить на null аргумент, помните, так лучше не делать:

или вы можете делегировать функции проверку на null:

вы можете использовать функцию isNull в любом месте вашей программы:

Заключение

Я думаю, мы четко видим различия и сходства между null и undefined . Так что когда в следующий раз вы увидите эту ошибку, вы будете знать, что делать.

Источник

Настоящее и будущее безопасной работы с null и undefined в JavaScript

Автору материала, перевод которого мы сегодня публикуем, недавно попался один вопрос на StackOverflow, который заставил его задуматься об обработке значений null и undefined в JavaScript. Здесь он приводит анализ текущей ситуации, показывает некоторые приёмы безопасной работы с null и undefined , а также, говоря о будущем, рассматривает оператор ?. .

Основные сведения

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

Null — это ещё одно примитивное значение, которое представляет собой отсутствие значения. Например, если переменной присвоено значение null , это можно трактовать как то, что на данном этапе работы программы эта переменная существует, но у неё пока нет ни типа, ни значения.

Посмотрим, что произойдёт, если выполнить такой код:

Он выдаст следующую ошибку:

Похожее можно видеть и при попытках работы с переменными, имеющими значение null .

Проверка на null и undefined

Как избежать подобных явлений? К счастью для нас, JavaScript поддерживает вычисление логических выражений по сокращённой схеме (short-circuit evaluation). Это означает, что для того, чтобы избежать вышеописанной ошибки TypeError , можно написать следующий код:

Но что если нужно пойти глубже, например, добраться до чего-то вроде obj.prop1.prop2.prop3 ? В подобной ситуации можно попытаться решить задачу, выполнив множество проверок:

Хотя это и работает, смотрятся такие конструкции не очень-то хорошо.

А что если нам нужно выводить некое стандартное значение, если в подобной цепочке встречается undefined или null ? Это возможно, но тогда кода придётся писать ещё больше:

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

Другие языки

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

В Java есть api Optional :

▍Kotlin

В Kotlin (он, как и Java, использует JVM) существуют операторы elvis ( ?: ) и safe-call ( ?. ).

И, наконец, в C# есть операторы null-condition ( ?. ), и null-coalescing ( ?? ).

Как работать с undefined в JS?

После рассмотрения возможностей по работе с неопределёнными значениями в других языках, я задался вопросом о том, есть ли возможность безопасно работать с undefined в JavaScript и при этом не писать километры кода. Поэтому я приступил к экспериментам с регулярными выражениями. Мне хотелось создать функцию, которая позволила бы безопасно получать доступ к свойствам объектов.

После того, как я создал эту функцию, я узнал о методе lodash._get , который имеет такую же сигнатуру:

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

Будущее безопасной работы с null и undefined в JavaScript

Сейчас в комитете TC39 имеется предложение, которое позволяет пользоваться следующими конструкциями:

По мне, так выглядит это очень аккуратно. Однако это предложение пока находится на достаточно ранней стадии согласования, то есть, его потенциальное появление в языке может занять некоторое время. Но, несмотря на это, существует плагин для babel, который позволяет уже сегодня пользоваться подобными конструкциями.

Итоги

Значения вроде null и undefined присутствуют в программировании уже очень давно, и ничто не указывает на то, что они в скором времени исчезнут. Вероятно, концепция значения null является самой нелюбимой в программировании, однако у нас есть средства для обеспечения безопасной работы с подобными значениями. В том, что касается работы с null и undefined в JavaScript, можно воспользоваться несколькими подходами рассмотренными выше. В частности, вот код функций, предложенных автором этого материала. Если вас заинтересовал оператор ?. , появление которого ожидается в JS, взгляните на одну из наших предыдущих публикаций, в которой затрагивается этот вопрос.

Уважаемые читатели! Какой из упомянутых в этом материале способов безопасной работы с null и undefined в JavaScript нравится вам больше всего?

Источник

Читайте также:  Чем чистить аквариумные декорации
Оцените статью