null
Значение null представляет отсутствие какого-либо объектного значения. В JavaScript, null является примитивом, и в контексте логических операций, рассматривается как ложное (falsy).
Интерактивный пример
Синтаксис
null
Описание
Значение null записывается литералом null . Оно является самостоятельным, а не свойством глобального объекта (как undefined ). В API, null часто присутствует в местах где ожидается объект, но подходящего объекта нет.
// переменная foo не существует - она не была определена и никогда не инициализировалась: > foo 'ReferenceError: foo is not defined' // переменная foo существует, но она не имеет ни типа, ни значения: > var foo = null; foo 'null'
Отличия между null и undefined
null является определённым значением отсутствия объекта, тогда как undefined обозначает неопределённость. Например:
var element; // значение переменной element до её инициализации не определённо: undefined element = document.getElementById("not-exists"); // здесь при попытке получения несуществующего элемента, метод getElementById возвращает null // переменная element теперь инициализирована значением null, её значение определено
При проверке на null или undefined , помните о различии между операторами равенства (==) и идентичности (===): с первым, выполняется преобразование типов.
typeof null; // object (не "null" из соображений обратной совместимости) typeof undefined; // undefined null === undefined; // false null == undefined; // true
Спецификации
| Specification |
|---|
| ECMAScript Language Specification # sec-null-value |
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 7 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
- Product help
- Report an issue
Our communities
Developers
- Web Technologies
- Learn Web Development
- MDN Plus
- Hacks Blog
- Website Privacy Notice
- Cookies
- Legal
- Community Participation Guidelines
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2024 by individual mozilla.org contributors. Content available under a Creative Commons license.
Типы данных
Значение в JavaScript всегда относится к данным определённого типа. Например, это может быть строка или число.
Есть восемь основных типов данных в JavaScript. В этой главе мы рассмотрим их в общем, а в следующих главах поговорим подробнее о каждом.
Переменная в JavaScript может содержать любые данные. В один момент там может быть строка, а в другой – число:
// Не будет ошибкой let message = "hello"; message = 123456;
Языки программирования, в которых такое возможно, называются «динамически типизированными». Это значит, что типы данных есть, но переменные не привязаны ни к одному из них.
Число
let n = 123; n = 12.345;
Числовой тип данных ( number ) представляет как целочисленные значения, так и числа с плавающей точкой.
Существует множество операций для чисел, например, умножение * , деление / , сложение + , вычитание — и так далее.
Кроме обычных чисел, существуют так называемые «специальные числовые значения», которые относятся к этому типу данных: Infinity , -Infinity и NaN .
-
Infinity представляет собой математическую бесконечность ∞. Это особое значение, которое больше любого числа. Мы можем получить его в результате деления на ноль:
alert( 1 / 0 ); // Infinity
Или задать его явно:
alert( Infinity ); // Infinity
alert( "не число" / 2 ); // NaN, такое деление является ошибкой
Значение NaN «прилипчиво». Любая математическая операция с NaN возвращает NaN :
alert( NaN + 1 ); // NaN alert( 3 * NaN ); // NaN alert( "не число" / 2 - 1 ); // NaN
Математические операции – безопасны
Математические операции в JavaScript «безопасны». Мы можем делать что угодно: делить на ноль, обращаться с нечисловыми строками как с числами и т.д.
Скрипт никогда не остановится с фатальной ошибкой (не «умрёт»). В худшем случае мы получим NaN как результат выполнения.
Специальные числовые значения относятся к типу «число». Конечно, это не числа в привычном значении этого слова.
Подробнее о работе с числами мы поговорим в главе Числа.
BigInt
В JavaScript тип number не может безопасно работать с числами, большими, чем (2 53 -1) (т. е. 9007199254740991 ) или меньшими, чем -(2 53 -1) для отрицательных чисел.
Если говорить совсем точно, то, технически, тип number может хранить большие целые числа (до 1.7976931348623157 * 10 308 ), но за пределами безопасного диапазона целых чисел ±(2 53 -1) будет ошибка точности, так как не все цифры помещаются в фиксированную 64-битную память. Поэтому можно хранить «приблизительное» значение.
Например, эти два числа (прямо за пределами безопасного диапазона) совпадают:
console.log(9007199254740991 + 1); // 9007199254740992 console.log(9007199254740991 + 2); // 9007199254740992
То есть все нечетные целые числа, большие чем (2 53 -1) , вообще не могут храниться в типе number .
В большинстве случаев безопасного диапазона чисел от -(2 53 -1) до (2 53 -1) вполне достаточно, но иногда нам требуется весь диапазон действительно гигантских целых чисел без каких-либо ограничений или пропущенных значений внутри него. Например, в криптографии или при использовании метки времени («timestamp») с микросекундами.
Тип BigInt был добавлен в JavaScript, чтобы дать возможность работать с целыми числами произвольной длины.
Чтобы создать значение типа BigInt , необходимо добавить n в конец числового литерала:
// символ "n" в конце означает, что это BigInt const bigInt = 1234567890123456789012345678901234567890n;
Так как необходимость в использовании BigInt –чисел появляется достаточно редко, мы рассмотрим их в отдельной главе BigInt. Ознакомьтесь с ней, когда вам понадобятся настолько большие числа.
В данный момент BigInt поддерживается только в браузерах Firefox, Chrome, Edge и Safari, но не поддерживается в IE.
Строка
Строка ( string ) в JavaScript должна быть заключена в кавычки.
let str = "Привет"; let str2 = 'Одинарные кавычки тоже подойдут'; let phrase = `Обратные кавычки позволяют встраивать переменные $`;
В JavaScript существует три типа кавычек.
- Двойные кавычки: «Привет» .
- Одинарные кавычки: ‘Привет’ .
- Обратные кавычки: `Привет` .
Двойные или одинарные кавычки являются «простыми», между ними нет разницы в JavaScript.
Обратные же кавычки имеют расширенную функциональность. Они позволяют нам встраивать выражения в строку, заключая их в $ . Например:
let name = "Иван"; // Вставим переменную alert( `Привет, $!` ); // Привет, Иван! // Вставим выражение alert( `результат: $` ); // результат: 3
Выражение внутри $ вычисляется, и его результат становится частью строки. Мы можем положить туда всё, что угодно: переменную name , или выражение 1 + 2 , или что-то более сложное.
Обратите внимание, что это можно делать только в обратных кавычках. Другие кавычки не имеют такой функциональности встраивания!
alert( "результат: $" ); // результат: $ (двойные кавычки ничего не делают)
Мы рассмотрим строки более подробно в главе Строки.
Нет отдельного типа данных для одного символа.
В некоторых языках, например C и Java, для хранения одного символа, например «a» или «%» , существует отдельный тип. В языках C и Java это char .
В JavaScript подобного типа нет, есть только тип string . Строка может содержать ноль символов (быть пустой), один символ или множество.
Булевый (логический) тип
Булевый тип ( boolean ) может принимать только два значения: true (истина) и false (ложь).
Такой тип, как правило, используется для хранения значений да/нет: true значит «да, правильно», а false значит «нет, не правильно».
let nameFieldChecked = true; // да, поле отмечено let ageFieldChecked = false; // нет, поле не отмечено
Булевые значения также могут быть результатом сравнений:
let isGreater = 4 > 1; alert( isGreater ); // true (результатом сравнения будет "да")
Мы рассмотрим булевые значения более подробно в главе Логические операторы.
Значение «null»
Специальное значение null не относится ни к одному из типов, описанных выше.
Оно формирует отдельный тип, который содержит только значение null :
let age = null;
В JavaScript null не является «ссылкой на несуществующий объект» или «нулевым указателем», как в некоторых других языках.
Это просто специальное значение, которое представляет собой «ничего», «пусто» или «значение неизвестно».
В приведённом выше коде указано, что значение переменной age неизвестно.
Значение «undefined»
Специальное значение undefined также стоит особняком. Оно формирует тип из самого себя так же, как и null .
Оно означает, что «значение не было присвоено».
Если переменная объявлена, но ей не присвоено никакого значения, то её значением будет undefined :
let age; alert(age); // выведет "undefined"
Технически мы можем присвоить значение undefined любой переменной:
let age = 123; // изменяем значение на undefined age = undefined; alert(age); // "undefined"
…Но так делать не рекомендуется. Обычно null используется для присвоения переменной «пустого» или «неизвестного» значения, а undefined – для проверок, была ли переменная назначена.
Объекты и символы
Тип object (объект) – особенный.
Все остальные типы называются «примитивными», потому что их значениями могут быть только простые значения (будь то строка, или число, или что-то ещё). В объектах же хранят коллекции данных или более сложные структуры.
Объекты занимают важное место в языке и требуют особого внимания. Мы разберёмся с ними в главе Объекты после того, как узнаем больше о примитивах.
Тип symbol (символ) используется для создания уникальных идентификаторов в объектах. Мы упоминаем здесь о нём для полноты картины, изучим этот тип после объектов.
Оператор typeof
Оператор typeof возвращает тип аргумента. Это полезно, когда мы хотим обрабатывать значения различных типов по-разному или просто хотим сделать проверку.
У него есть две синтаксические формы:
// Обычный синтаксис typeof 5 // Выведет "number" // Синтаксис, напоминающий вызов функции (встречается реже) typeof(5) // Также выведет "number"
Если передается выражение, то нужно заключать его в скобки, т.к. typeof имеет более высокий приоритет, чем бинарные операторы:
typeof 50 + " Квартир"; // Выведет "number Квартир" typeof (50 + " Квартир"); // Выведет "string"
Другими словами, скобки необходимы для определения типа значения, которое получилось в результате выполнения выражения в них.
Вызов typeof x возвращает строку с именем типа:
typeof undefined // "undefined" typeof 0 // "number" typeof 10n // "bigint" typeof true // "boolean" typeof "foo" // "string" typeof Symbol("id") // "symbol" typeof Math // "object" (1) typeof null // "object" (2) typeof alert // "function" (3)
Последние три строки нуждаются в пояснении:
- Math — это встроенный объект, который предоставляет математические операции и константы. Мы рассмотрим его подробнее в главе Числа. Здесь он служит лишь примером объекта.
- Результатом вызова typeof null является «object» . Это официально признанная ошибка в typeof , ведущая начало с времён создания JavaScript и сохранённая для совместимости. Конечно, null не является объектом. Это специальное значение с отдельным типом.
- Вызов typeof alert возвращает «function» , потому что alert является функцией. Мы изучим функции в следующих главах, где заодно увидим, что в JavaScript нет специального типа «функция». Функции относятся к объектному типу. Но typeof обрабатывает их особым образом, возвращая «function» . Так тоже повелось от создания JavaScript. Формально это неверно, но может быть удобным на практике.
Итого
В JavaScript есть 8 основных типов данных.
- Семь из них называют «примитивными» типами данных:
- number для любых чисел: целочисленных или чисел с плавающей точкой; целочисленные значения ограничены диапазоном ±(2 53 -1) .
- bigint для целых чисел произвольной длины.
- string для строк. Строка может содержать ноль или больше символов, нет отдельного символьного типа.
- boolean для true / false .
- null для неизвестных значений – отдельный тип, имеющий одно значение null .
- undefined для неприсвоенных значений – отдельный тип, имеющий одно значение undefined .
- symbol для уникальных идентификаторов.
- object для более сложных структур данных.
Оператор typeof позволяет нам увидеть, какой тип данных сохранён в переменной.
- Имеет две формы: typeof x или typeof(x) .
- Возвращает строку с именем типа. Например, «string» .
- Для null возвращается «object» – это ошибка в языке, на самом деле это не объект.
В следующих главах мы сконцентрируемся на примитивных значениях, а когда познакомимся с ними, перейдём к объектам.
Исследование бездны null и undefined в JavaScript

Говоря о примитивных типах данных в JavaScript, большинство имеет в виду самые основные из них: String, Number, и Boolean. Эти примитивы достаточно предсказуемы, и работают так, как от них и ожидается. Однако, речь в данной статье пойдет об менее обыденных примитивных типах, Null и Undefined, о том, в чём они схожи, различны, и, вообще говоря, необычны.
Понимание null и undefined
В JavaScript null — это литерал и ключевое слово языка, которое представляет собой отсутствие какого-либо объекта. Другими словами, null указывает «в никуда». В свою очередь, хоть и похожий по смыслу undefined , олицетворяет отсутствие значения как такового. Оба абсолютно неизменны, не имеют свойств и методов и не способны их иметь. Фактически, попытка обратиться к какому-нибудь свойству, или присвоить его, приведёт к ошибке TypeError . Оба этих примитива, как намекают их имена, совершенно лишены значений.
Это самое отсутствие значения приводит к тому, что они считаются ложными, в том смысле, что они приводятся к false если используются в качестве условия, например, в конструкции if . А если сравнить null и undefined с другими ложными значениями при помощи оператора нестрогого сравнения ( == ), то окажется, что они не равны ничему, кроме самих себя:
null == 0; // false undefined == ""; // false null == false; // false undefined == false; // false null == undefined; // trueНесмотря на эти сходства, null и undefined не эквивалентны. Каждый из них является представителем своего типа: undefined — представляет тип Undefined, а null , соответственно — тип Null. Это легко доказать, сравнив их при помощи оператора строгого сравнения ( === ), который принимает в расчёт не только значения, но и типы данных:
undefined === null; // falseЭто важное различие, и оно не случайно, ведь эти примитивы служат для разных целей. Чтобы их различать, вы можете считать undefined неожиданным отсутствием значения, а null — умышленным отсутствием значения.
Получение undefined
Есть множество способов получить значение undefined в коде. Обычно это происходит при попытке получить значение там, где значения нет. В этом случае JavaScript, будучи динамическим, слабо типизированным языком, не покажет ошибку, а выдаст значение по умолчанию, undefined .
Любая объявленная переменная, которой при создании не присвоено никакого значения, имеет значение undefined :
var foo; // по умолчанию undefinedЗначение undefined также получается при попытке обратиться к несуществующему свойству объекту или элементу массива:
var array = [1, 2, 3]; var foo = array.foo; // свойство foo не существует, возвращается undefined var item = array[5]; // в массиве нет элемента 5, возвращается undefinedЕсли в функции нет оператора return , она возвращает undefined :
var value = (function( )<>)(); // возвращает undefinedЕсли функции не был передан какой-либо аргумент, он становится undefined :
(function(undefined)< // параметр равен undefined >)();Помимо всего вышеперечисленного, для получения undefined может использоваться оператор void . Некоторые библиотеки, вроде Underscore пользуются этим для надежной проверки типов, потому как void нельзя переопределить, и он всегда возвращает undefined :
function isUndefined(obj)< return obj === void 0; >Наконец, undefined — это предопределённая глобальная переменная (а не ключевое слово, как null ), которая равна undefined :
'undefined' in window; // trueНачиная с пятой версии ECMAScript эта переменная доступна только для чтения, а, вот, в предыдущих версиях её было возможно переопределить.
Применение null
В первую очередь null отличается своим применением, и в отличие от undefined , null больше используется для присваивания значения. Как раз из-за этого оператор typeof для null возвращает «object». Изначально это объяснялось тем, что null использовался (и используется) как пустая ссылка там, где ожидается объект, что-то вроде заглушки. Такое поведение typeof было позже признано багом, и, хотя было предложено это поведение исправить, пока что, в целях обратной совместимости, всё остается как есть.
Вот, почему окружение JavaScript не выставляет никаких значений в null , и это делается только программно. В документации на MDN написано следующее:
В различных API null часто возвращается в тех местах, где ожидается объект, но такой объект подобрать нельзя.
Это правдиво для DOM, который не зависит от языка и никак не описывается в документации ECMAScript. Из-за того, что используется внешний API, попытка получить отсутствующий элемент возвращает null , а не undefined .
Вообще, если нужно присвоить «не-значение» переменной или свойству, передать его в функцию, или вернуть из функции, то null — это почти всегда лучший вариант. Упрощённо: JavaScript использует undefined , а программисты должны использовать null .
Другой способ применения null — явное «зануливание» переменной ( object = null ), когда ссылка на объект больше не требуется. Кстати, это считается хорошей практикой. Присваивая null , вы фактически удаляете ссылку на объект, и если на него нет других ссылок, он отправляется к сборщику мусора, таким образом возвращая доступную память.
Копнём глубже
Причина того, что null и undefined эдакие чёрные дыры, кроется не только в их поведении, но ещё и в том, как они обрабатываются внутри окружения JavaScript. Они не обладают теми характеристиками, которые обычно присущи другим примитивам и встроенным объектам.
Начиная с ES5 метод Object.prototype.toString , ставший стандартом де-факто для проверки типов, стал полезен в этом отношении и для null с undefined :
Object.prototype.toString.call(null); // [object Null] Object.prototype.toString.call(undefined); // [object Undefined]Однако, на самом деле у null и undefined этот метод не возвращает внутреннее свойство [[Class]] . По документации он работает следующим образом:
- Если значение this равно undefined , вернуть «[object Undefined]» .
- Если значение this равно null , вернуть «[object Null]» .
- Пусть O равно результату вызова ToObject с this , переданным как аргумент.
- Пусть class равно внутреннему свойству [[Class]] объекта O.
- Вернуть значение String, которое является результатом сложения трёх строк «[object » , class, и «]» .
Этот метод просто возвращает заготовленную строку, если обнаруживает null или undefined , просто чтобы унифицировать функциональность с другими объектами. Такое поведение встречается сплошь и рядом во всей документации, большая часть методов содержат простую проверку, и если встретился null или undefined , возвращают значение сразу. Фактически, нигде не написано, что у них содержатся какие-либо внутренние свойства, обычно имеющиеся у каждого нативного объекта. Это как если бы они вообще не были объектами. Интересно, эти примитивы в окружении JavaScript как-то явно и особо обрабатываются? Может быть, кто-то более знакомый с имплементацией мог бы подсказать.
Заключение
Неважно, насколько необычными кажутся примитивы null и undefined , понимание разницы между ними и их различиями в использовании согласно JavaScript очень важно для понимания языка в целом. Это понимание, конечно же, само по себе не заставит работать ваше приложение или, например, не сломает его, но, строго говоря, оно положительно скажется в долгосрочной перспективе, облегчив вам разработку и отладку будущих проектов.
Комментарий переводчика
При написании этой статьи автор забыл упомянуть одну важную деталь: у примитивов, как таковых, не может быть свойств вообще, они есть только у объектов. А при попытке получить свойство у примитива, он будет неявно преобразован в объект. В этом легко убедиться:
var s = 'test', o = Object(s); o.foo = 42; s.foo = 42; o.foo; // 42 s.foo; // undefinedДело в том, что null и undefined просто нельзя преобразовать в объект, на чем и строится объяснение ключевых особенностей этих примитивов автором этой статьи.
Также, фраза про то, что null в окружении JavaScript без явного присваивания не используется, неверна. В конце цепочки прототипов находится null , и это как раз тот случай, когда ожидается объект, но его нет:
Object.getPrototypeOf(Object.prototype); // null
Оригинальная статья: Exploring the Abyss of Null and Undefined in JavaScript Статью вычитывали: SilentImp, cosmiksoul, FMRobot, subzey
© 2013 Frontender Magazine
Кроме материалов, опубликованных под лицензией Creative Commons
Null в JavaScript: объект или примитив
Null — один из семи примитивных типов данных в JavaScript (остальные —строки, числа, булевые значения, undefined, BigInt и Symbol).
И только для типа null проверка typeof возвращает объект. Значит ли это, что null — объект? Нет☝️
Null все-таки примитив. История с типом — баг при создании JavaScript.Так как же он работает?
В первой версии JS значения хранились в 32-битных ячейках. Первые биты были тегами, то есть указывали на тип данных, к которому принадлежит значение.
Таких тегов было 5:
000 — объект
1 — целое число
010 — double (дробное число)
100 — строка
110 — booleanТо есть теги занимали три первых бита в 32-битной ячейке (и один бит в случает целых чисел).
У типа null не было своего отдельного тега. При этом, значение null хранится в памяти в виде нуля (0000, т.е. во всех отведенных под значение битах — нули).
А мы помним, что если у нас в начале значения 000, то программа воспринимает их как тег объекта. Вот и получается такой баг, который разработчики признали, но решили не менять, т.к. это может поломать все уже существующие программы.
Источники: The history of “typeof null”, A quick and thorough guide to ‘null’