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

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

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

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

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

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

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

таким образом, общий консенсус, похоже, заключается в том, что undefined означает "нет такого свойства", в то время как null означает, что свойство существует, но не имеет значения.

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

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

12 ответов


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

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

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

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

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

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

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

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

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


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

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

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


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

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

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

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

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

это может быть JavaScript первоначальное намерение автора, что undefined должны представить "несуществование". Однако реализация оказалась не такой.


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


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

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

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


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


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

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

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

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


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

<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>

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


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

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


это важная языковая функция, если вы обернете свою программу вокруг evented парадигмы 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]
 * }
 */

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


null красиво

как и все другие типы живых сценарий.

cite: в JavaScript есть два значения, которые в основном говорят: "Я не exist' - undefined и null.

почему вы хотите сказать неправильные вещи?!

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

обычно говорят об этих вещах как о" типах", когда их нет. На самом деле это"категории". Но теперь все кончено.

так будет придерживаться его, чтобы сказать, что" null " является типом объекта без вида. И "null" говорит: "Я очень существую[!], но у меня нет содержания моего вида".

, тогда как неопределено не хватает как типа, так и вида, где неопределено случается также быть его определение типа. Неопределенный тип типа становится его отличительной типологией. Своего рода [существует ли " ничто "и как вы определяете"ничто"?] вопрос.

cite: undefined nor null может быть возвращен из функции конструктора, поскольку оба будут преобразователем в пустой объект

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

cite: единственная реальная разница, о которой я могу думать, это то, что один оценивает NaN, другое до 0 в числовом контексты.

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

в то время как логический контекст ожидает ссылки - не находит ничего для преобразования и дает "false".

идем сейчас...

cite: так еще раз: каково практическое использование отдельных значений для undefined и null?

я постараюсь дать вам только два эмпирических примера и надеюсь достаточно!--7-->

oElement.onclick >> null

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

oElement.innerText >> ""

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

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

оставайтесь Мороз и получайте удовольствие.


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

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

Так что я думаю это имеет смысл иметь тип данных Null.

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

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