Почему в JavaScript есть значение null?

В JavaScript есть два значения, которые в основном говорят «Я не существую» - undefined и null.

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

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

Они также оба оценивают false в логических контекстах. Единственное реальное различие, о котором я могу думать, заключается в том, что один оценивается как NaN, а другой - как 0 в числовом контексте.

Итак, почему существуют и undefined, и null, если это просто сбивает с толку программистов, которые неправильно проверяют наличие null, пытаясь выяснить, установлено ли свойство или нет?

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

Таким образом, по общему мнению, undefined означает «такого свойства нет», в то время как null означает «свойство существует, но не имеет значения».

Я мог бы смириться с этим, если бы реализации JavaScript действительно обеспечивали такое поведение, но undefined - совершенно допустимое примитивное значение, поэтому его можно легко присвоить существующим свойствам, чтобы разорвать этот контракт. Следовательно, если вы хотите убедиться, что свойство существует, вам все равно придется использовать оператор in или hasOwnProperty(). Итак, еще раз: каково практическое использование отдельных значений для undefined и null?

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

Чтобы ответить на ваш последний вопрос: Нет, вам не следует устанавливать свойства для undefined.

Shog9 20.01.2009 21:34

«undefined» - это просто переменная в глобальной области видимости с примитивным значением «undefined». Можно определить другое значение переменной: {undefined = "Hello"; alert (undefined);} Более надежный способ проверки на undefined: {if (typeof myvar === "undefined") alert ("undefined")}

some 21.01.2009 20:57

См. Раздел 4.3.9 - 12 в ecma-international.org/publications/files/ECMA-ST/Ecma-262.p‌ df для undefined / null и 15.1.1.3 для переменной «undefined» в глобальной области видимости.

some 21.01.2009 21:03

Вы должны либо удалить объект, либо установить для него значение null, если это имеет больший смысл, но не значение undefined.

some 21.01.2009 21:05
In JavaScript, there are two values which basically say 'I don't exist' - undefined and null. Нет, это говорит только undefined.
Lightness Races in Orbit 13.02.2014 17:24

Возможный дубликат В чем разница между null и undefined в JavaScript?

Donald Duck 11.05.2018 10:44
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
121
6
29 616
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

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

Лучше всего описывается здесь, но вкратце:

undefined - это отсутствие типа и значения, а null - отсутствие значения.

Более того, если вы делаете простые сравнения «==», вы правы, они выходят одинаково. Но попробуйте ===, который сравнивает тип и значение, и вы заметите разницу.

Я знаю, что null !== undefined - мой вопрос был в том, зачем нужны две вещи, которые выражают одну и ту же семантическую концепцию; Кроме того, в вашей ссылке упоминается, что «null - это объект» - это неправильно, это примитив ...

Christoph 20.01.2009 19:22

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

Daniel Schaffer 20.01.2009 19:31

Но в том-то и дело, это не одно и то же семантическое понятие. При использовании == Null принудительно подразумевает то же самое для удобства программиста.

Eddie Parker 20.01.2009 19:33

@Christoph typeof null === 'object';

Eric Elliott 13.04.2013 15:53

@EricElliott: typeof лжет - прочтите спецификацию или попробуйте вернуть null из конструктора

Christoph 13.04.2013 15:59

@Christoph Конечно, вы правы, но этот комментарий «попробуйте вернуть null из конструктора» - сбивающий с толку контрапункт вашему аргументу: он вернет объект. Возврат ложного значения любой из конструктора приведет к тому, что конструктор вместо этого вернет this.

Eric Elliott 18.04.2013 05:23

@EricElliott: возвращаемое значение конструкторов не имеет ничего общего с ложностью, но с объектной сущностью: если возвращаемое значение является объектом, верните его; если это примитив, такой как null или 42, отбросьте возвращаемое значение и вместо этого верните вновь созданный объект

Christoph 18.04.2013 10:47

@Christoph Как я мог это забыть? Спасибо за исправление. знак равно

Eric Elliott 20.04.2013 18:28

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

но вы можете использовать undefined для назначения свойств, поэтому этот контракт (возвращать undfined только в том случае, если такого свойства нет) может быть легко нарушен программистом ...

Christoph 20.01.2009 19:30

Вы может, но вам определенно не следует. Undefined используется как очень простая / упрощенная форма исключения в JavaScript - не используйте его как значение и присваивайте его какому-либо свойству! Это сумасшедший.

rfunduk 13.02.2009 01:18

Попробуйте этот пример:

<html>
<head>
    <script type = "text/javascript">
        function ShowObjProperties(obj) {
            var property, propCollection = "";

            for(property in obj) {
                propCollection += (property + ": " + obj[property] + "\n");
            }

            alert(propCollection);
        }

        var obj = {
            userid: 3,
            name: 'me!',
            speak: function() { alert('Hi! My name is ' + this.name + ' and my ID is ' + this.userid + '.'); }
        }

        //Shows all properties
        ShowObjProperties(obj);

        //The Speak function is no longer in the list!
        delete obj.speak;
        alert(typeof obj.speak);
        ShowObjProperties(obj);

        //The UserID is still listed, it just has no value!
        obj.userid = null;
        ShowObjProperties(obj);
    </script>
</head>
<body>

</body>
</html>

Я думаю, что здесь есть реальная польза для двух разных типов.

А в прототипах, я думаю, это член null или просто undefined.

Kev 20.01.2009 20:06

но это работает только до тех пор, пока никто не пытается его сломать - если я установлю obj.userid = undefined, он потерпит неудачу - см. последнее изменение моего вопроса

Christoph 20.01.2009 20:15

Все сводится к динамической природе javascripts.

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

и каким образом это имеет отношение к моему вопросу?

Christoph 20.01.2009 20:41

Это актуально, потому что отвечает на ваш вопрос. «null» - это своего рода «синглтон», означающий «не имеет значения». "undefined" говорит вам, что что-то ... шокирует, я знаю ... не определено. Это совершенно разные вещи.

rfunduk 13.02.2009 01:20

Я думаю, что ваш вывод о том, что JavaScript определяет undefined как «такого свойства нет», а null как «свойство не имеет значения», является совершенно правильным. И для такого динамичного языка, как JavaScript, это очень важное различие. Использование утки означает, что нам нужно различать свойство, которое не существует, и свойство, не имеющее значения. Это наш основной способ получения информации о типе. в статически типизированном языке существует явное различие между пустым полем и несуществующим полем. В JavaScript это не исключение. Однако он проверяется во время выполнения и может быть изменен до этого времени.

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

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

Не могли бы вы поделиться этой ролевой игрой?

Michael 13.01.2020 10:16
Ответ принят как подходящий

На самом деле вопрос не в том, «почему в JS есть нулевое значение» - в большинстве языков есть какое-то нулевое значение, и оно обычно считается очень полезным.

Вопрос в том, «почему в JS стоит значение неопределенный». Основные места, где он используется:

  1. когда вы объявляете var x;, но не назначаете ему, x содержит значение undefined;
  2. когда ваша функция получает меньше аргументов, чем объявляет;
  3. когда вы обращаетесь к несуществующему свойству объекта.

null определенно работал бы так же хорошо для (1) и (2) *. (3) действительно должен вызывать исключение сразу же, и тот факт, что он не возвращает этот странный undefined, который выйдет из строя позже, является большим источником трудностей отладки.

*: вы также можете утверждать, что (2) должен вызывать исключение, но тогда вам придется предоставить лучший, более явный механизм для аргументов по умолчанию / переменных.

Однако в JavaScript изначально не было исключений или какого-либо способа спросить объект, есть ли у него член под определенным именем - единственный способ был (и иногда остается) получить доступ к члену и посмотреть, что вы получите. Учитывая, что у null уже была цель, и вы вполне могли захотеть установить для нее член, требовалось другое внеполосное значение. Итак, у нас есть undefined, это проблематично, как вы указываете, и это еще одна замечательная «особенность» JavaScript, от которой мы никогда не сможем избавиться.

I actually use undefined when I want to unset the values of properties no longer in use but which I don't want to delete. Should I use null instead?

Да. Сохраните undefined как специальное значение для сигнализации, когда другие языки могут вместо этого генерировать исключение.

null обычно лучше, за исключением некоторых интерфейсов IE DOM, где установка чего-либо на null может привести к ошибке. Часто в этом случае работает пустая строка.

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

Erik Reppen 18.01.2014 22:33

Забавно, как принятый ответ на вопрос начинается со слов «на самом деле не в этом вопрос ...»

Phillip 22.06.2015 08:02

@bobince разве в ранних версиях JS не было оператора in или hasOwnProperty? Потому что они намного безопаснее, чем obj.hello !== undefined, для проверки наличия свойства у объекта.

Andy 31.03.2016 02:13

Да ладно, я ответил на свой вопрос. Согласно MDN, они оба были представлены в ES3.

Andy 31.03.2016 02:15

это важная языковая функция, если вы оборачиваете свою программу вокруг четной парадигмы javascript.

// a key exists as a placeholder for something
if (obj[name] === null) 
// no key exists int eh hashtable that is in this object
if (obj[name] === undefined)

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

filter_func_pt = {
  date:function(d){ return Math.round(d.getTime()/1000);},
  user: null,
}

function transform(obj){
    var ret = {};
    for( var prop in obj){
       var f = filter_func_pt[prop];
       if (f)
          ret[prop] = f(obj);
       else if (filter_func_pt[prop] === null)
         continue;
       else
         ret[prop] == obj;
    }
  return ret;
}

var a = {
   date: new Date(),
   user: 'sam'
   votes: [23, 41, 55] 
};

var b = transform(a);

/* b = {
 *    date: 1298582417
 *    votes: [23, 41, 55]
 * }
 */

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

Этот пример надуманный и немного бессмысленный. Null совсем не проясняет ваше намерение, а скорее маскирует его. Вы могли бы использовать более явную строку, чтобы прояснить смысл. Например, «удержать» или «убрать», а затем вы также можете более подробно узнать о типе функции и фактически проверить наличие функции.

Eric Elliott 02.05.2013 22:03

null красивый

как и все другие типы Live Script.

cite: In JavaScript, there are two values which basically say 'I don't exist' - undefined and null.

Почему вы хотите говорить неправильные вещи ?!

"ноль" - это "пустой объект", точно так же, как «0» - это "пустой номер". 0 - это ничто, но существует как Тип числа. ноль, конечно, тоже пусто, но «это есть», и это хорошо определенная вещь в Тип объекта.

Об этих вещах принято говорить как о «типах», хотя это не так. Фактически это «категории». Но теперь все кончено.

Так что буду придерживаться его, чтобы сказать, что «null» - это тип объекта без вида. А «null» говорит: «Я очень много существую [!], Но у меня нет контента моего типа».

В то время как неопределенный не имеет ни типа, ни типа, где неопределенный также является его определением типа. Неопределенный тип типа становится его отличительной типологией. Что-то вроде вопроса [существует ли «ничего» и как определить «ничего»?].

cite: undefined nor null can be returned from a constructor function, as both will be converter to an empty object

Вы умудрились в очередной раз сказать неверную вещь. Конечно, нет, «undefined» - это не объект, это простой токен, который мы, люди, понимаем; но в отличие от этого ноль - и он говорит вам, что: его Тип правильный, но Тип, который вы ищете, не содержится в нем или, по крайней мере, в настоящее время отсутствует. Приходите к нам позже, когда мы поместим \ присвоим ему какой-нибудь объект \.

cite: The only real difference I can think of is that one evaluates to NaN, the other to 0 in numeric contexts.

В этом вся суть их основного различия, как уже упоминалось: неопределенный - это простой токен, и поскольку он состоит из того же «генетического» материала, что и его дальние родственники: строки, операция [+ undefined] преобразует его в NaN, аналогично null, конечно, вместо этого превратится в правильный тип 0 \ Number, а в отличие от неопределенный, который превратится в строку (! Которая не пуста!), И именно поэтому вместо этого она дает NaN. Где: + undefined >> + "undefined" >> NaN. Поскольку числовой контекст ожидает явного значения.

Хотя логический контекст ожидает ссылку, не находит ничего для преобразования и возвращает false.

Давай прорежем сейчас ...

cite: So once again: what's the practical use for seperate values for undefined and null?

Я постараюсь привести только два эмпирических примера и надеюсь, что их хватит.

oElement.onclick >> null

// означает - свойство существует; его ожидаемое значение имеет тип: Объект, и этот oElement поддерживает событие «onclick»!

oElement.innerText >> ""

// означает - свойство существует; его ожидаемое значение имеет тип: Нить, что означает, что oElement поддерживает свойство «innerText».

в обоих случаях - если вы получили "undefined", это означает, что свойство не существует; не поддерживается или имеет неправильную реализацию (поставщик ua).

Оставайся на морозе и получай удовольствие.

Не портите свои посты, эней. Удалите их (используя кнопку Удалить прямо над этим комментарием), если хотите удалить свой вклад.

Michael Petrotta 12.03.2012 01:53

кнопки удаления нет - но если вы ее видите - нажмите ее!

user1170379 20.03.2012 06:33

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

Чтобы ответить на ваш вопрос, undefined означает, что значение никогда не устанавливалось. На практике это обычно указывает на ошибку. Если yourObject.property не определен, это означает, что вы по какой-то причине не установили свойство, или я ищу то, чего вообще не существует. Это реальная проблема при работе над проектом с более чем одним кодировщиком.

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

В Java попытки доступа к неопределенному полю всегда приводят к исключению. Фактически, компилятор может предупреждать вас об этом в вашем коде.

Я не думаю, что есть какая-то причина иметь и null, и undefined, потому что единственная причина, которую предлагали многие люди («undefined означает, что такой переменной / свойства нет»), недействительна, по крайней мере, в JavaScript. undefined не может сказать вам, существует ли переменная / свойство или нет.

console.info(foo);               // "ReferenceError: foo is not defined"
                                // foo does not exist
var foo;
console.info(foo);               // "undefined", a different response
console.info(foo === undefined); // "true", but it does exist

var obj = {};
console.info(obj.hasOwnProperty("foo")); // "false", no such property
obj.foo = undefined;
console.info(obj.hasOwnProperty("foo")); // "true", it exists and has the value "undefined"
console.info(obj.foo === undefined);     // "true", but it does exist

obj.bar = "delete me";
obj.bar = undefined;
console.info(obj.hasOwnProperty("bar")); // "true", not actually deleted
delete obj.bar;
console.info(obj.hasOwnProperty("bar")); // "false", deleted

Как видите, проверка foo === undefined не говорит вам, существует ли foo, а установка obj.bar = undefined на самом деле не удаляет bar.

Возможно, автор JavaScript изначально предполагал, что undefined должен олицетворять «небытие». Однако реализация оказалась не такой.

Замените undefined на null в приведенных выше примерах кода, и все ответы будут одинаковыми. Я не знаю, как это ответить на вопрос. Было ли это означать комментарий к чьему-то ответу?

Eric Elliott 18.04.2013 05:28

@EricElliott Мой ответ на вопрос заключается в том, что нет причин иметь и null, и undefined, потому что единственная причина, по которой многие люди предлагали, неверна.

Lei Zhao 29.04.2013 20:32

Вы должны отредактировать свой ответ и сказать это на самом деле. Я мог бы проголосовать, если бы вы дали такой ответ. знак равно

Eric Elliott 02.05.2013 21:50

@EricElliott Я думаю, вы правы. Я отредактировал свой ответ. Спасибо!

Lei Zhao 07.05.2013 10:43

обратите внимание, что выполнение первых двух строк из файла фактически выведет «undefined» из-за подъема

martinkunev 23.01.2014 19:15

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

Aleksej Komarov 26.07.2014 19:43

после прочтения потрясающего обсуждения undefined и null, небольшой поиск в Google привел меня к Mozilla Documentations https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null упоминается - null часто извлекается в том месте, где можно ожидать объект, но ни один объект не является релевантным.

Не похож на шаблон объекта Null https://en.wikipedia.org/wiki/Null_object_pattern

Итак, я думаю, имеет смысл иметь тип данных Null.

Документация также упоминается как typeof null // "объект" (не "null" по устаревшим причинам)

Не уверен, какие унаследованные причины

Другие вопросы по теме