Перейти к содержимому

Почему null в js объект

  • автор:

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.

null

Примитивный тип данных. Состоит из единственного значения null и обозначает отсутствие значения.

Время чтения: меньше 5 мин

Открыть/закрыть навигацию по статье

  1. Кратко
  2. Пример
  3. Как понять
  4. На практике
    1. Николай Лопин советует
    1. В чём разница между null, undefined и объявленной переменной без начального значения? (let foo;)

    Обновлено 3 августа 2022

    Кратко

    Скопировать ссылку «Кратко» Скопировано

    Null — это примитивный тип данных, который состоит из единственного значения null .

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

    Пример

    Скопировать ссылку «Пример» Скопировано

     const password = null const password = null      

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

     const mainFocusByDays =  mon: 'Исправить баг в вёрстке', tue: 'Разобрать почту', wed: 'Написать бота', thu: 'Изучить примитивные типы', fri: 'Отправить резюме в Яндекс', sat: null, sun: null> const mainFocusByDays =  mon: 'Исправить баг в вёрстке', tue: 'Разобрать почту', wed: 'Написать бота', thu: 'Изучить примитивные типы', fri: 'Отправить резюме в Яндекс', sat: null, sun: null >      

    Как понять

    Скопировать ссылку «Как понять» Скопировано

    null обозначает понятия «отсутствует», «ничего», «пусто» или «значение неизвестно». Оно всегда явно задаётся программистом, JavaScript автоматически не устанавливает его.

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

    В языке существует похожий примитив undefined , он обозначает, что значение ещё не установлено. Их можно легко спутать, потому что оба обозначают отсутствие значения. Разница состоит в том, что null обозначает намеренное отсутствие, а undefined — неявное.

    Например, сам JavaScript использует undefined для обозначения не проинициализированных переменных:

     let newValue console.log(newValue)// undefined // в явном виде говорим, что значение отсутствуетnewValue = null let newValue console.log(newValue) // undefined // в явном виде говорим, что значение отсутствует newValue = null      

    На практике

    Скопировать ссылку «На практике» Скопировано

    Николай Лопин советует

    Скопировать ссылку «Николай Лопин советует» Скопировано

    �� Оператор typeof некорректно определяет тип у null и возвращает значение ‘object’ по историческим причинам.

     console.log(typeof null)// 'object' console.log(typeof null) // 'object'      

    �� Разделение между undefined и null очень слабое. Это рекомендация, которую не все выполняют. Команды могут договориться о своей трактовке этих значений.

    Например, в приложении нужно отобразить список пользователей, полученный с сервера. Пока данных нет, мы рисуем заглушку. В этом случае мы можем трактовать значение undefined как «отправили запрос на сервер, рисуем заглушку и ждём ответа», а null как «сервер ответил, что у него нет данных».

    �� Уточняйте договорённости по undefined и null на проекте. Часто они не зафиксированы на бумаге, но имеют большое значение.

    На собеседовании

    Скопировать ссылку «На собеседовании» Скопировано

    В чём разница между null , undefined и объявленной переменной без начального значения? ( let foo; )

    Скопировать ссылку «В чём разница между null, undefined и объявленной переменной без начального значения? (let foo;)» Скопировано

    Скопировать ссылку «Александр Рассудихин отвечает» Скопировано

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

    Без начального значения можно оставлять только переменную объявленную через let или var . Если объявить переменную через const и не задать ей начального значения, будет ошибка: Uncaught SyntaxError : Missing initializer in const declaration .

    Оператор typeof для null работает странно. typeof ( null ) выдаст нам строку ‘object’. Это официально признанная ошибка в языке, сохраняемая для совместимости. Ошибка тут в том, что null это отдельный тип данных, а не объект. С undefined всё куда лучше и typeof ( undefined ) выдаст нам ‘undefined’. Почитать ещё о typeof можно здесь.

    Поговорим немного о приведении типов. Для начала, пример:

     console.log(null + null); // 0console.log(undefined + undefined); // NaN console.log(null + null); // 0 console.log(undefined + undefined); // NaN      

    null во время сложения приводится к нулю. Это логично, так как числовым значением «ничего» является как раз 0.
    С undefined другое поведении, так как JavaScript пытается привести его к числу, но у него не получается и в результате мы получаем NaN .

    Немного упомяну и про оператор нулевого слияния ( ? ? ). В выражении между двумя операндами, он будет возвращать первый операнд, если он не равен null или undefined . Можно сказать, что ? ? приравнивает смысл undefined и null к «ничего не содержит» и в этом случае, кладёт в переменную значение второго операнда.

    Исследование бездны 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]] . По документации он работает следующим образом:

    1. Если значение this равно undefined , вернуть «[object Undefined]» .
    2. Если значение this равно null , вернуть «[object Null]» .
    3. Пусть O равно результату вызова ToObject с this , переданным как аргумент.
    4. Пусть class равно внутреннему свойству [[Class]] объекта O.
    5. Вернуть значение 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 в JS тип «object»?

    На «Хабре» вышла статья, проливающая свет на загадку — почему же у null в Джаваскрипте тип «объект». Причём, если попытаться этому «объекту» добавить какое-то свойство, то браузер воспротивится: скажет, что null объектом не является.

    Null как объект (13.48КиБ)

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

    Оказывается, это баг. Точнее даже не баг, а просто «так получилось». В ранних интерпретаторах Джаваскрипта тип хранился в первых трёх битах значения. Для типа «а это у нас null» значения не хватило, ему дали тип «объект», а под значение выделили нулевой указатель. Ну typeof, особо не заморачиваясь, выдавала object.

    К сожалению, программисты поленились сделать дополнительную проверку. Можно было при наличии нулевого указателя попросить typeof выводить «null» и дело в шляпе. Сейчас, как оказалось, куча кода завязано на это поведение и ломать уже ничего никто не будет.

    9 комментариев

    Если уж хочется что-то поменять, то логичнее будет расширить поведение до полноценного Object? Хоть какая-то польза может выйти.

    История в тему: недавно на собеседовании вьюноши учудили и начали спрашивать меня про типы данных. Тогда про null для них и случилось открытие ) Детишки про фишку тупо не знали. Ясно, что на работу уже не позвали. А снаружи это вполне солидный ресурс.

    Евгений Степанищев (bolknote.ru) 2014

    Комментарий для shaltai-boltai:

    Честно сказать, если его расширить, то мне польза неочевидна как-то 🙂 Давать ему методы через прототип? 🙂 Разве что только для целостности языка какая-то польза будет.

    А вот проблемы некоторые это рождает. Например, известнейшая проверка «а объект ли это» снабжается костылём «и не null».

    Ну да, больше для целостности. Null-объект можно делать типизированным, можно какую-то историю для undo хранить. Всё лучше, чем ничего.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *