Иногда в коде можно встретить что-то вроде такого:
if (counter == null) {
//какой-то код
}
Может показаться, что null — это название переменной, но на самом деле это специальное значение, которое означает, что переменная есть, но в переменной ничего нет. Кроме этого, есть ещё одно интересное состояние переменной — undefined
, которое означает, что переменная не определена. Давайте разберёмся, в чём разница и для чего это всё нужно.
Минутка информатики. Если копать совсем глубоко, то в переменной не всегда лежат именно те данные, которые мы туда отправили.
Чаще всего при объявлении переменной компьютер выделяет сколько-то байтов в памяти, в которые можно записать любое помещающееся значение. Но это работает только для простых переменных — чисел и символов (которые внутри тоже числа). Если нам нужна строка, которая состоит из множества символов, или массив, то в переменной хранится не значение, а только ссылка на область памяти, в которой лежат наши данные. В этих случаях переменная — это карта, которая объяснит компьютеру, где найти всё остальное.
Зная это, будет проще разобраться, почему компьютер иногда вместо конкретного значения переменной записывает в неё null или undefined.
Что такое undefined
Когда мы только создаём переменную без явного указания типа и ничего в неё не кладём, то компьютер многого не знает:
- он не знает, что в ней может оказаться;
- не в курсе, сколько памяти надо будет выделить;
- не понимает, по каким правилам с этой переменной нужно работать дальше.
Чтобы пометить себе, что пока ничего не ясно, компьютер помечает эту переменную как undefined
, что означает «неопределённость»:
В тех языках, где переменные не обязательно объявлять заранее, например в Python, интерпретатор тоже выведет подобное сообщение. Отличие будет в том, что здесь это приведёт к ошибке, так как компьютер даже не знает, что у него есть такая переменная.
Представьте, что вы занимаетесь уборкой и вам говорят: «Возьми мешок». Что это значит? Пока неясно: это мешок для мусора или вещей; какого объёма; полный или пустой. Просто «мешок». Если представить, что мешок — это переменная, то undefined
мешок — это как раз «просто некий мешок, без уточнения».
Чаще всего в языках с сильной динамической типизацией у переменной не может быть значения undefined
, потому что переменная в них появляется в момент её объявления и присваивания сразу какого-то значения. Но само понятие undefined
тоже там используется — оно означает, что компьютер вообще ничего не знает про эту переменную.
Зачем нужен undefined
Чаще всего это используется для проверки состояния переменной — есть ли в ней хоть что-то. Например, если в ней что-то есть, то с этим можно работать дальше, а если нет — вывести сообщение о том, что переменная пустая. Это полезно для отладки кода или для проверки входящих в нашу программу данных и вывода информативных ошибок.
Что такое null
В отличие от undefined, когда компьютер не знает, что лежит в переменной, null — это как раз одно из значений переменной. Оно означает, что переменная — пустая, при этом компьютер точно знает, как с ней можно работать.
Допустим, мы хотим обратиться к элементу на странице по его id. Для этого мы сначала заводим переменную element, и на старте она будет определяться как undefined. После этого мы присваиваем этой переменной ссылку на нужный элемент, но если этого элемента на странице нет, то произойдёт такое:
- Скрипт попытается найти элемент на странице.
- После того как он убедится, что элемента нет, он вернёт null — это значит, что на странице ничего такого нет.
- Это значение null отправится в переменную element, и у неё появится определённое значение null.
Если вспомнить наш мешок во время уборки:
— undefined — это когда вы ничего не знаете про мешок — даже то, есть ли этот мешок в принципе или его нужно пойти и где-то купить;
— null — это когда вы знаете, что мешок есть, он определённого размера и формы, но он точно пустой и даже ещё не раскрытый;
В некоторых языках, например Python, вместо null используют None — это тоже значение переменной, которое означает, что в переменной ничего нет, но сама переменная определена верно.
Undefined и null — это одно и то же?
Нет, и в этом легко убедиться, используя строгое сравнение. Дело в том, что при обычном сравнении компьютер смотрит, есть что-то в переменной или нет, при этом ему неважно, работали мы с ней раньше или нет. А при строгом сравнении компьютер смотрит ещё и на тип данных — в этом случае сразу видно, что у undefined никакого типа данных нет:
А что такое ноль?
А ноль — это самая «жирная» пустота из всех вышеперечисленных. Ноль — это полноценное значение численной переменной (например, integer, то есть целого числа).
Представьте, что вы пишете программу, которая обрабатывает прогнозы погоды. Эти данные она получает с погодного сервера. И с этого сервера прилетала переменная temperature. Сравните:
Если temperature === undefined, то, похоже, с сервера не прилетело никакой переменной с температурой. Программа завела переменную для приёма данных, но дальше ничего не произошло. Мы даже не знаем, какого типа данные нам прилетят. А то и вовсе нет никакой переменной.
Если temperature === null, то мы знаем, в каком формате прилетит температура, но сами данные ещё не прилетели.
Если temperature === 0, то температура — ноль градусов (предположим, по Цельсию). Ноль градусов — это вполне себе значение, с которым можно работать — например нарисовать снежинку.
Возвращаясь к метафоре с мешком: ноль — это когда нам объяснили, какой именно нужен мешок, мы его взяли и запихнули в него ноль, который занял всё место. Зачем? Видимо, так надо.