Обнаружение неопределенного свойства объекта

Как лучше всего проверить, не определено ли свойство объекта в JavaScript?

Поведение ключевого слова "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) для оценки ваших знаний,...
2 974
0
1 265 947
48
Перейти к ответу Данный вопрос помечен как решенный

Ответы 48

if (somevariable == undefined) {
  alert('the variable is not defined!');
}

Вы также можете превратить его в функцию, как показано здесь:

function isset(varname){
  return(typeof(window[varname]) != 'undefined');
}

Во-первых, когда somevariable равно undefined, это не означает, что переменная не определена - это просто значение, которое не определено. Если переменная не определена, этот код выдаст ошибку. Во-вторых, эта функция isset будет работать только для глобальных переменных.

Rene Saarsoo 27.01.2010 02:09

как насчет локальных переменных? странный трюк с окном [переменная]

Denis 27.08.2013 17:09

В JavaScript есть ноль и неопределенный. У них разные значения.

  • неопределенный означает, что значение переменной не было определено; неизвестно, какова стоимость.
  • ноль означает, что значение переменной определено и установлено равным нулю (не имеет значения).

Марин Хавербеке утверждает в своей бесплатной онлайн-книге «Красноречивый JavaScript» (выделено мной):

There is also a similar value, null, whose meaning is 'this value is defined, but it does not have a value'. The difference in meaning between undefined and null is mostly academic, and usually not very interesting. In practical programs, it is often necessary to check whether something 'has a value'. In these cases, the expression something == undefined may be used, because, even though they are not exactly the same value, null == undefined will produce true.

Итак, я думаю, лучший способ проверить, не было ли что-то неопределенным, это:

if (something == undefined)

Свойства объекта должны работать одинаково.

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined

if (something == undefined) лучше писать как if (something === undefined)

Sebastian Rittau 30.11.2009 12:47

Следует отметить, что это не совсем безопасно. undefined - это просто переменная, которую пользователь может переназначить: запись undefined = 'a'; приведет к тому, что ваш код больше не будет делать то, что вы думаете. Использование typeof лучше, и оно также работает для переменных (а не только свойств), которые не были объявлены.

Gabe Moothart 14.04.2010 19:18

если что-то является неопределенной глобальной переменной, (something == undefined) вызывает ошибку javascript.

Morgan Cheng 21.04.2010 07:04

Проблема заключается в том, что если var a = null, тогда a == undefined оценивается как true, даже если a определенно определено.

Andrew 19.05.2011 22:50

if (something === undefined) у меня не работает с ie7 или ie8 if (typeof something == "undefined") есть.

juhan_h 14.06.2011 11:21

Эта интерпретация комментария «Красноречивый Javascript» - назад. Если вы действительно хотите просто проверить наличие undefined, предлагаемый код не будет работать (он также обнаружит определенное условие, но еще не присвоено значение [т.е. пустое]). Пустое значение. Предлагаемый код «if (something == undefined) ...» проверяет наличие обе undefined и null (значение не установлено), т.е. он интерпретируется как «if ((что-то не определено) OR (что-то равно null)) ...» Автор говорит, что часто вы хотите, чтобы В самом деле проверял наличие обе undefined и null.

Chuck Kollars 18.05.2012 02:35

Решение неверное. В JavaScript

null == undefined

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

if (something === undefined)

который является тождественным оператором ...

Для ясности, === - это равенство типов + (примитивное равенство | идентичность объекта), где примитивы включают строки. Я думаю, что большинство людей считают 'abab'.slice(0,2) === 'abab'.slice(2) неинтуитивным, если рассматривать === в качестве оператора идентификации.

clacke 30.07.2010 12:49

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

Simon East 15.06.2011 04:22

Какое решение? Вы можете напрямую ссылаться на него?

Peter Mortensen 25.07.2020 02:34
Ответ принят как подходящий

Обычный способ проверить, является ли значение свойства специальным значением undefined:

if (o.myProperty === undefined) {
  alert("myProperty value is the special value `undefined`");
}

Чтобы проверить, действительно ли объект не имеет такого свойства и, следовательно, вернет undefined по умолчанию, когда вы попытаетесь получить к нему доступ:

if (!o.hasOwnProperty('myProperty')) {
  alert("myProperty does not exist");
}

Чтобы проверить, является ли значение, связанное с идентификатором, специальным значением undefined, или же, если этот идентификатор не был объявлен. Примечание: этот метод является единственным способом обращения к идентификатору необъявленный (примечание: отличается от идентификатора undefined) без ранней ошибки:

if (typeof myVariable === 'undefined') {
  alert('myVariable is either the special value `undefined`, or it has not been declared');
}

В версиях JavaScript до ECMAScript 5 свойство с именем «undefined» глобального объекта было доступно для записи, и поэтому простая проверка foo === undefined могла бы вести себя неожиданно, если бы оно было случайно переопределено. В современном JavaScript это свойство доступно только для чтения.

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

Если вас беспокоит этот (маловероятный) крайний случай, вы можете использовать оператор void для получения самого специального значения undefined:

if (myVariable === void 0) {
  alert("myVariable is the special value `undefined`");
}

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

neu-rah 25.06.2012 23:20

@ neu-rah, почему ты не можешь написать функцию? почему бы что-то подобное не сработать? Мне кажется, это работает. Есть случай, который я не рассматриваю? jsfiddle.net/djH9N/6

Zack 24.09.2012 23:01

@Zack В ваших тестах для isNullorUndefined не учитывался случай, когда вы вызываете isNullOrUndefined (f), а f не объявлен (т.е. когда нет объявления "var f").

pnkfelix 15.02.2013 19:08

Мля, сейчас тысячи голосов. Это наихудший способ сделать это. Надеюсь, прохожие увидят этот комментарий и решат проверить… кхм… ответы Другой.

Ry- 14.05.2014 07:05

Теперь вы можете просто использовать obj !== undefined. undefined был изменчивым, как и undefined = 1234, что давало интересные результаты. Но после Ecmascript 5 он больше не доступен для записи, поэтому мы можем использовать более простую версию. codereadability.com/how-to-check-for-undefined-in-javascript

Bruno Buccolo 15.03.2016 23:50

@ Райан, какой "другой ответ"?

user1032531 14.12.2017 15:41

@ user1032531: Я бы порекомендовал свой

Ry- 14.12.2017 23:02

Одного большого пальца явно недостаточно. Спасибо.

Anjana Silva 10.09.2020 19:08

grrr im just going typeof window !== typeof undefined ... нет шансов ошибиться в написании undefined и работает в глобальном масштабе

Ray Foss 05.02.2021 00:53

function isUnset(inp) {
  return (typeof inp === 'undefined')
}

Возвращает false, если переменная установлена, и true, если не определена.

Затем используйте:

if (isUnset(var)) {
  // initialize variable here
}

Нет, не делай этого. Требуется только очень простой тест, чтобы доказать, что вы не можете осмысленно обернуть тест typeof в функцию. Удивительно, что за это проголосовали 4 человека. -1.

Stijn de Witt 01.11.2015 05:39

if ( typeof( something ) == "undefined") 

У меня это сработало, а у других - нет.

паренсы не нужны, так как typeof является оператором

aehlke 10.08.2010 15:22

Но они проясняют, что проверяется. В противном случае его можно было бы прочитать как typeof (something == "undefined").

Abhi Beckert 06.09.2012 04:28

Если вам нужны круглые скобки, вам следует изучить приоритет операторов в JS: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

Ian 07.03.2014 21:17

Круглые скобки полезны именно потому, что вам НЕ нужно изучать приоритет операторов в JS, и вам не нужно размышлять о том, нужно ли будущим программистам обслуживания изучать приоритет операторов в JS.

DaveWalley 11.04.2014 18:48

Круглые скобки полезны, чтобы прояснить ситуацию. Но в этом случае они просто делают оператор похожим на функцию. Без сомнения, это проясняет намерения программиста. Но если вы не уверены в приоритете оператора, вам лучше написать его как (typeof something) === "undefined".

Robert 14.05.2014 22:31

@Robert Я согласен с тем, что вы используете скобки (окружающие typeof), но в ES6 вы не можете использовать скобки для вызова функции, например quux `foo\n${ 42 }bar`.

CPHPython 07.03.2018 15:00

Я считаю, что на эту тему есть несколько неправильных ответов. Вопреки распространенному мнению, «undefined» - это ключевое слово в JavaScript нет, которому фактически может быть присвоено значение.

Правильный код

Самый надежный способ выполнить этот тест:

if (typeof myVar === "undefined")

Это всегда будет возвращать правильный результат и даже обработает ситуацию, когда myVar не объявлен.

Вырожденный код. НЕ ИСПОЛЬЗОВАТЬ.

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

Кроме того, myVar === undefined вызовет ошибку в ситуации, когда myVar не объявлен.

+1 за то, что отметили, что myVar === undefined вызовет ошибку, если myVar не был объявлен

Enrique 19.12.2011 22:27

Я согласен с тем, что undefined не является ключевым словом, undefined - это предопределенная переменная с неопределенным значением. Что-то вроде предупреждения, это функция, которую вы можете переопределить чем-то другим. Alert также не является ключевым словом, а является частью стандартного набора функций, ap частью оконного объекта, имеющего глобальную область видимости. Как и undefined, вы также можете переопределить функцию предупреждения, переназначив ее. Например: window.alert = function (s) {console.info (s); } также является законной конструкцией.

Codebeat 08.11.2012 10:49

Я нахожу приведенное здесь первое оправдание отказа от использования === undefined в недоумение. Да, вы можете назначить undefined, но для этого нет законной причины, и вполне предсказуемо, что это может привести к поломке вашего кода. В C вы можете #define true false, а в Python вы можете назначить True и False, но люди не чувствуют необходимости разрабатывать свой код на этих языках таким образом, чтобы защитить себя от возможности преднамеренного саботажа своей собственной среды в другом месте. в коде. Почему здесь вообще стоит задуматься о возможности присвоения undefined?

Mark Amery 13.01.2013 23:05

Насчет if (typeof myVar != "undefined"). Подходит ли "! = "?

Kevin Meredith 05.07.2013 20:17

в дополнение к комментариям Marks я не понимаю этого: «myVar === undefined вызовет ошибку в ситуации, когда myVar не объявлен». - почему это плохо? Зачем мне нет хотеть получить ошибку, если я ссылаюсь на необъявленные переменные?

eis 20.08.2013 19:12

@Kevin Да, так и будет, потому что typeof всегда будет возвращать строку, что делает ненужным сравнение с типобезопасностью. Просто считается хорошей практикой использовать === соответственно. Только !==. На самом деле я думаю, что jQuery использует только !=.

Ingo Bürk 24.08.2013 02:00

Также имейте в виду, что вы всегда можете выполнить void 0, чтобы получить значение, на которое указывает undefined. Так можно сделать if (myVar === void 0). 0 не является чем-то особенным, вы можете выразить там буквально любое выражение.

Claudiu 03.10.2013 21:45

В современных браузерах (FF4 +, IE9 +, Chrome unknown) больше невозможно изменить undefined. MDN: не определено

user247702 07.02.2014 18:09
рабочий пример для демонстрации of this point
rojobuffalo 16.01.2015 22:18

@Stijn: Хотя изменить глобальный undefined невозможно, все же возможно переопределить его локально, как показано в этом ответе. Скопируйте и вставьте образец кода ответа в современный браузер, и вы увидите, что myVar === undefined все еще может вызывать проблемы.

dharcourt 02.10.2015 22:12

@KevinMeredith "! =" Приемлемо? " Это определенно. В моей книге это лучше, чем !==, поскольку он короче, а более длинные формы не дают преимуществ i.c.w. typeof.

Stijn de Witt 01.11.2015 15:53

Этот ответ тоже неверен. Вопрос касался неопределенных свойств объекта, а не неопределенных переменных. Есть существенная разница. Совершенно разумно, например, сделать if (obj.field === undefined). Я думаю, что риск того, что кто-то сделает var undefined = false;, переоценен. Вам придется программировать неоправданно оборонительную программу, если вы хотите защитить себя от всех подобных побочных эффектов, вызванных плохим программированием.

Zero3 15.12.2015 18:38

Правило X: НИКОГДА не используйте зарезервированные слова в качестве имени переменной, функции или чего-либо еще. Не понимаю, что у вас так много положительных голосов. Поскольку это возможно, это не означает, что это законно, кроме того, это может измениться в будущем, и ваш код (и все, что от него зависит) больше не работает. Это плохой / ненадежный пример, и он показывает, как этого не делать.

Codebeat 23.11.2016 08:16

поскольку для свойства записи undefined установлено значение false. даже если вы назначите false для undefined, оно не будет установлено. поэтому undefined будет "undefined", всегда не ложным, поэтому ваш ответ не имеет смысла. Вы можете проверить это в спецификации сценария ECMA для JavaScript. ecma-international.org/ecma-262/5.1/#sec-15.1.1.3

Velu S Gautam 25.07.2017 15:36

Просто исходя из опыта, я думаю, вы, В самом деле, хотите, чтобы ваш код выдавал эту ошибку ReferenceError, если переменная не объявлена. Это так неприятно, когда что-то молча терпит неудачу.

Atav32 31.07.2017 16:02

@MarkPflug: К сожалению, в 2010 году это тоже не имело смысла. undefined не является ключевым словом в 2017 году. Вы все еще можете использовать var undefined = false;. Ответом на этот вопрос всегда было «не делай этого», а не «используйте запутанные обходные пути для чего-то, чего никогда не бывает».

Ry- 16.08.2017 03:17

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

user8897421 18.12.2017 16:39

^ полностью согласен. кто-то, кто может затенять undefined, может также затенять Math или назначать Function.prototype.apply или что-либо, что вы считаете само собой разумеющимся! Пожалуйста. ^ полностью согласен. кто-то, кто может затенять undefined, может также затенять Math или назначать Function.prototype.apply или что-либо, что вы считаете само собой разумеющимся! Пожалуйста. Как насчет Object.prototype.toJSON=()=>({rick:'rolled'})? Тогда JSON.stringify({hello:'world'}) === '{"rick":"rolled"}'. Существует так много способов нарушить ожидаемую среду JavaScript, что вы не можете написать код, который работает со всеми этими вещами.

CherryDT 18.03.2020 00:13

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

typeof x;                      // some string literal "string", "object", "undefined"
if (typeof x === "string") {   // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") {    // sufficient

Отличный момент, Эрик. Есть ли снижение производительности от проверки типа?

Simon East 29.06.2011 11:16

@Simon: как раз наоборот - можно было ожидать небольшого снижения производительности из-за избежания принуждения в случае '==='. Быстрый и грязный тест показал, что '===' на 5% быстрее, чем '==' в FF5.0.1.

Antony Hatchkins 18.12.2011 12:24

Более тщательный тест показал, что в FF, IE и Chrome '==' более или менее быстрее, чем '===' (5-10%), а Opera вообще не имеет никакого значения: jsperf.com/triple-equals-vs-twice-equals/6

Antony Hatchkins 18.12.2011 13:55

Использование == по-прежнему требует по меньшей мере проверки типа - интерпретатор не может сравнить два операнда, не зная сначала их тип.

Alnitak 13.08.2012 19:12

== на один символ меньше, чем === :)

svidgen 28.06.2013 18:54

@svidgen Вы добавляете смайлик, но, видя, что сеть представляет собой цепочку самый медленный в ссылке, я действительно считаю, что вы увидите больший прирост производительности, если пропустите лишний символ, чем вы когда-либо увидите при проверке типа. 5% ничего - это еще ничто. Лично я ненавижу догматическое кодирование. Я разрешаю вам выключать мозг во время набора текста, но есть причина, по которой тройное равенство в этом случае будет безопаснее, по нет.

Stijn de Witt 01.11.2015 05:21

Проблема сводится к трем случаям:

  1. У объекта есть свойство, и его значение не undefined.
  2. У объекта есть свойство, и его значение - undefined.
  3. У объекта нет собственности.

Это говорит нам о том, что я считаю важным:

Существует разница между неопределенным членом и определенным членом с неопределенным значением.

Но, к сожалению, typeof obj.foo не сообщает нам, какой из трех случаев у нас есть. Однако мы можем комбинировать это с "foo" in obj, чтобы различать случаи.

                               |  typeof obj.x === 'undefined' | !("x" in obj)
1.                     { x:1 } |  false                        | false
2.    { x : (function(){})() } |  true                         | false
3.                          {} |  true                         | true

Стоит отметить, что эти тесты одинаковы и для записей null.

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

Я бы сказал, что в некоторых случаях имеет больше смысла (и яснее) проверять, есть ли свойство, чем проверять, не определено ли оно, и единственный случай, когда эта проверка будет отличаться, - это случай 2, редкий случай фактическая запись в объекте с неопределенным значением.

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

if ( typeof blob.x != 'undefined' ) {  fn(blob.x); }

Что было яснее при написании без проверки на undefined.

if ( "x" in blob ) { fn(blob.x); }

Но, как уже упоминалось, это не совсем то же самое (но более чем достаточно для моих нужд).

Привет Майкл. Отличное предложение, и я думаю, оно делает вещи чище. Однако я обнаружил одну ошибку при использовании! оператор с "in". Вы должны сказать if (!("x" in blob)) {}, заключив скобки в скобки, потому что! оператор имеет приоритет перед 'in'. Надеюсь, это кому-то поможет.

Simon East 15.06.2011 04:28

Извините, Майкл, но это неверно или, по крайней мере, вводит в заблуждение в свете исходного вопроса. 'in' не является достаточным способом проверить, имеет ли свойство объекта typeof undefined. Для доказательства см. Эту скрипку: jsfiddle.net/CsLKJ/4

tex 25.02.2012 16:04

Эти две части кода делают разные вещи! Учтите и возразите, данное a = {b: undefined}; затем typeof a.b === typeof a.c === 'undefined', но 'b' in a и !('c' in a).

mgol 27.09.2012 18:07

+1. OP не дает понять, существует ли свойство и имеет ли оно значение неопределенный, или само свойство не определено (т.е. не существует).

RobG 01.04.2014 05:12

Я бы предложил изменить точку (2.) в вашей первой таблице на { x : undefined } или, по крайней мере, добавить ее в качестве другой альтернативы (2.) в таблице - мне пришлось на мгновение подумать, чтобы понять, что точка (2.) оценивается как undefined. (хотя вы упомянули об этом позже).

mucaho 14.05.2015 19:32

@mucaho Это было бы лучше, но я думаю, что есть (или, по крайней мере, были?) некоторые проблемы с такой конструкцией - то есть undefined не является (не было?) гарантированно неопределенным.

Michael Anderson 15.05.2015 11:20

Если вы это сделаете

if (myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

он завершится ошибкой, если переменная myvar не существует, потому что myvar не определена, поэтому сценарий не работает и тест не действует.

Поскольку объект окна имеет глобальную область видимости (объект по умолчанию) вне функции, объявление будет «прикреплено» к объекту окна.

Например:

var myvar = 'test';

Глобальная переменная Myvar такая же, как window.myvar или окно ['myvar']

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

if (window.myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

Вопрос, действительно ли переменная существует, не имеет значения, ее значение неверно. В противном случае глупо инициализировать переменные с помощью undefined, и для инициализации лучше использовать значение false. Когда вы знаете, что все переменные, которые вы объявляете, инициализированы с помощью false, вы можете просто проверить его тип или положиться на !window.myvar, чтобы проверить, имеет ли он правильное / допустимое значение. Таким образом, даже если переменная не определена, !window.myvar будет одинаковым для myvar = undefined, myvar = false или myvar = 0.

Если вы ожидаете определенного типа, проверьте тип переменной. Чтобы ускорить проверку состояния, вам лучше сделать:

if ( !window.myvar || typeof window.myvar != 'string' )
{
    alert('var does not exists or is not type of string');
}

Когда первое и простое условие выполняется, интерпретатор пропускает следующие тесты.

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

(у)

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

 function getAllUndefined(object) {

        function convertPath(arr, key) {
            var path = "";
            for (var i = 1; i < arr.length; i++) {

                path += arr[i] + "->";
            }
            path += key;
            return path;
        }


        var stack = [];
        var saveUndefined= [];
        function getUndefiend(obj, key) {

            var t = typeof obj;
            switch (t) {
                case "object":
                    if (t === null) {
                        return false;
                    }
                    break;
                case "string":
                case "number":
                case "boolean":
                case "null":
                    return false;
                default:
                    return true;
            }
            stack.push(key);
            for (k in obj) {
                if (obj.hasOwnProperty(k)) {
                    v = getUndefiend(obj[k], k);
                    if (v) {
                        saveUndefined.push(convertPath(stack, k));
                    }
                }
            }
            stack.pop();

        }

        getUndefiend({
            "": object
        }, "");
        return saveUndefined;
    }

jsFiddle ссылка

Хотя это не повлияет на действительность вашего кода, у вас есть опечатка: getUndefiend должен быть getUndefined.

icktoofay 14.05.2013 07:02

Object.hasOwnProperty(o, 'propertyname');

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

Object.hasOwnProperty не будет работать должным образом; он проверяет, есть ли у объекта Object свойство с именем, содержащимся в o. Вы наверное имеете в виду Object.prototype.hasOwnProperty.call(o, 'propertyname').

icktoofay 14.05.2013 06:59

Я не видел (надеюсь, что не пропустил), чтобы кто-то проверял объект перед свойством. Итак, это самый короткий и самый эффективный (хотя и не обязательно самый понятный):

if (obj && obj.prop) {
  // Do something;
}

Если obj или obj.prop имеет значение undefined, null или "ложный", оператор if не выполнит блок кода. Это обычно - желаемое поведение в большинстве операторов блока кода (в JavaScript).

Если вы хотите знать, почему это работает: Javascript: логические операторы и правдивость / ложность

mb21 04.02.2013 20:57

если вы хотите присвоить свойство переменной, если она определена, а не null и не falsey, иначе используйте какое-то значение по умолчанию, вы можете использовать: var x = obj && obj.prop || 'default';

Stijn de Witt 01.11.2015 05:27

Я считаю, что вопрос заключается в явной проверке на undefined. Ваше условие проверяет все ложные значения JS.

NikoKyriakid 20.07.2018 12:49

Кросс-постинг мой ответ из связанного вопроса Как я могу проверить наличие "неопределенного" в JavaScript?.

Конкретно для этого вопроса см. Тестовые примеры с someObject.<whatever>.


Некоторые сценарии, иллюстрирующие результаты различных ответов: http://jsfiddle.net/drzaus/UVjM4/

(Обратите внимание, что использование var для тестов in имеет значение при использовании оболочки с ограниченным объемом)

Код для справки:

(function(undefined) {
    var definedButNotInitialized;
    definedAndInitialized = 3;
    someObject = {
        firstProp: "1"
        , secondProp: false
        // , undefinedProp not defined
    }
    // var notDefined;

    var tests = [
        'definedButNotInitialized in window',
        'definedAndInitialized in window',
        'someObject.firstProp in window',
        'someObject.secondProp in window',
        'someObject.undefinedProp in window',
        'notDefined in window',

        '"definedButNotInitialized" in window',
        '"definedAndInitialized" in window',
        '"someObject.firstProp" in window',
        '"someObject.secondProp" in window',
        '"someObject.undefinedProp" in window',
        '"notDefined" in window',

        'typeof definedButNotInitialized == "undefined"',
        'typeof definedButNotInitialized === typeof undefined',
        'definedButNotInitialized === undefined',
        '! definedButNotInitialized',
        '!! definedButNotInitialized',

        'typeof definedAndInitialized == "undefined"',
        'typeof definedAndInitialized === typeof undefined',
        'definedAndInitialized === undefined',
        '! definedAndInitialized',
        '!! definedAndInitialized',

        'typeof someObject.firstProp == "undefined"',
        'typeof someObject.firstProp === typeof undefined',
        'someObject.firstProp === undefined',
        '! someObject.firstProp',
        '!! someObject.firstProp',

        'typeof someObject.secondProp == "undefined"',
        'typeof someObject.secondProp === typeof undefined',
        'someObject.secondProp === undefined',
        '! someObject.secondProp',
        '!! someObject.secondProp',

        'typeof someObject.undefinedProp == "undefined"',
        'typeof someObject.undefinedProp === typeof undefined',
        'someObject.undefinedProp === undefined',
        '! someObject.undefinedProp',
        '!! someObject.undefinedProp',

        'typeof notDefined == "undefined"',
        'typeof notDefined === typeof undefined',
        'notDefined === undefined',
        '! notDefined',
        '!! notDefined'
    ];

    var output = document.getElementById('results');
    var result = '';
    for(var t in tests) {
        if ( !tests.hasOwnProperty(t) ) continue; // bleh

        try {
            result = eval(tests[t]);
        } catch(ex) {
            result = 'Exception--' + ex;
        }
        console.info(tests[t], result);
        output.innerHTML += "\n" + tests[t] + ": " + result;
    }
})();

И результаты:

definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined

Что это значит: "неопределенное свойство объекта"?

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

var o = { a: undefined }

o.a не определен? Да! Его значение не определено. o.b не определен? Конечно! Свойство "b" вообще не существует! Хорошо, теперь посмотрим, как разные подходы ведут себя в обеих ситуациях:

typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

Мы ясно видим, что typeof obj.prop == 'undefined' и obj.prop === undefined эквивалентны, и они не различают эти разные ситуации. А 'prop' in obj может обнаружить ситуацию, когда свойство вообще не определено, и не обращает внимания на значение свойства, которое может быть неопределенным.

Так что делать?

1) Вы хотите знать, не определено ли свойство по первому или второму значению (наиболее типичная ситуация).

obj.prop === undefined // IMHO, see "final fight" below

2) Вы просто хотите знать, имеет ли объект какое-либо свойство, и не заботитесь о его значении.

'prop' in obj

Примечания:

  • Вы не можете одновременно проверить объект и его свойство. Например, этот x.a === undefined или этот typeof x.a == 'undefined' поднимает ReferenceError: x is not defined, если x не определен.
  • Переменная undefined - это глобальная переменная (в браузерах это фактически window.undefined). Он поддерживается с ECMAScript 1st Edition, а с ECMAScript 5 - только чтение. Таким образом, в современных браузерах это не может быть переопределено на истину, которым любят нас пугать многие авторы, но это все еще верно для старых браузеров.

Финальный бой: obj.prop === undefined vs typeof obj.prop == 'undefined'

Плюсы obj.prop === undefined:

  • Он немного короче и выглядит немного красивее
  • Движок JavaScript выдаст ошибку, если вы неправильно написали undefined.

Минусы obj.prop === undefined:

  • undefined можно переопределить в старых браузерах

Плюсы typeof obj.prop == 'undefined':

  • Это действительно универсально! Работает в новых и старых браузерах.

Минусы typeof obj.prop == 'undefined':

  • 'undefned' (неправильно написан) - это просто строковая константа, поэтому движок JavaScript не сможет вам помочь, если вы неправильно написали его, как только что сделал я.

Обновление (для серверного JavaScript):

Node.js поддерживает глобальную переменную undefined как global.undefined (ее также можно использовать без префикса global). Я не знаю других реализаций серверного JavaScript.

@Bergi спасибо за ваш комментарий. Я исправил свой ответ. В свою защиту могу сказать, что в настоящее время (начиная с версии 0.10.18) официальная документация Node.js ничего не говорит о undefined как члене global. Также ни console.info(global);, ни for (var key in global) { ... } не показывают неопределенный как член Глобальный. Но тест вроде 'undefined' in global показывает обратное.

Konstantin Smolyanin 11.09.2013 14:53

Дополнительная документация не нужна, так как это в спецификации EcmaScript, который также говорит, что [[Enumerable]] является ложным :-)

Bergi 11.09.2013 15:00

Что касается Minuses of typeof obj.prop == 'undefined', этого можно избежать, написав как typeof obj.prop == typeof undefined. Это также дает очень красивую симметрию.

hlovdal 24.10.2014 15:01

@hlovdal: Это совершенно бессмысленно по сравнению с obj.prop === undefined.

Ry- 12.04.2018 00:38

Когда мы верны заголовку вопроса «Обнаружение - неопределенное свойство», а не (другому и гораздо более простому) вопросу в первом предложении («проверьте, не определено ли…»), вы отвечаете if ('foo' in o)… ваш ответ действительно является первым правильным ответом здесь . Практически все остальные просто отвечают на это предложение.

Frank Nocke 11.06.2018 11:46

Вот моя ситуация:

Я использую результат вызова REST. Результат должен быть преобразован из JSON в объект JavaScript.

Есть одна ошибка, которую я должен защищать. Если аргументы для вызова REST были неправильными, поскольку пользователь указал аргументы неправильно, вызов REST возвращается в основном пустым.

Используя этот пост, чтобы помочь мне защититься от этого, я попробовал следующее:

if ( typeof restResult.data[0] === "undefined" ) { throw  "Some error"; }

В моей ситуации, если restResult.data [0] === "объект", я могу безопасно начать проверку остальных членов. Если не определено, то выдайте ошибку, как указано выше.

Я говорю, что для моей ситуации все предыдущие предложения в этом посте не сработали. Я не говорю, что я прав, а все ошибаются. Я совсем не мастер JavaScript, но надеюсь, это кому-то поможет.

Ваша защита typeof на самом деле не защищает от всего, с чем не может справиться прямое сравнение. Если restResult не определен или не объявлен, он все равно выдаст.

user8897421 18.12.2017 16:50

В вашем случае вы могли бы проще проверить, пуст ли массив: if (!restResult.data.length) { throw "Some error"; }

Headbank 28.02.2019 18:36

В статье Изучение бездны пустого и неопределенного в JavaScript я читал, что такие фреймворки, как Underscore.js, используют эту функцию:

function isUndefined(obj){
    return obj === void 0;
}

void 0 - это всего лишь краткий способ записи undefined (так как это то, что пустота, за которым следует любое выражение), сохраняет 3 символа. Он также мог использовать var a; return obj === a;, но это еще один символ. :-)

RobG 01.04.2014 05:16

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

Brian M. Hunt 14.09.2015 16:08

isUndefined(obj): 16 символов. obj === void 0: 14 символов. Ничего не сказано.

Stijn de Witt 01.11.2015 05:41

Сравните с void 0, для краткости.

if (foo !== void 0)

Это не так многословно, как if (typeof foo !== 'undefined')

Но это вызовет ошибку ReferenceError, если foo не объявлен.

daniel1426 08.03.2014 02:46

@ daniel1426: Значит, если в вашем коде есть ошибка, вы хотите ее скрыть, а не исправлять? Не лучший подход, ИМО.

user8897421 18.12.2017 16:47

Это не используется для сокрытия ошибок. Это обычный способ определения свойств среды для определения полифилов. Например: if (typeof Promise === 'undefined') {/ * define Promise * /}

gaperton 04.10.2018 06:05

'если (window.x) {}' безопасен от ошибок

Скорее всего вам нужен if (window.x). Эта проверка безопасна, даже если x не был объявлен (var x;) - браузер не выдает ошибку.

Пример: я хочу знать, поддерживает ли мой браузер History API.

if (window.history) {
    history.call_some_function();
}

Как это работает:

окно - это объект, который содержит все глобальные переменные в качестве своих членов, и допустимо пытаться получить доступ к несуществующему члену. Если Икс не был объявлен или не был установлен, window.x возвращает неопределенный. неопределенный приводит к ложный, когда если() оценивает его.

Но что, если вы запустите Node? typeof history != 'undefined' действительно работает в обеих системах.

Stijn de Witt 01.11.2015 05:28

Несмотря на то, что многие другие ответы здесь настоятельно рекомендуют typeofплохой выбор. Его никогда не следует использовать для проверки того, имеют ли переменные значение undefined, потому что он действует как комбинированная проверка для значения undefined и того, существует ли переменная. В подавляющем большинстве случаев вы знаете, когда существует переменная, и typeof просто представит возможность скрытого сбоя, если вы сделаете опечатку в имени переменной или в строковом литерале 'undefined'.

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

Поэтому, если вы не выполняете обнаружение функций², где есть неопределенность, будет ли заданное имя находиться в области действия (например, проверка typeof module !== 'undefined' как шага в коде, специфичном для среды CommonJS), typeof является опасным выбором при использовании с переменной, и правильный вариант - сравнить значение напрямую:

var foo = …;

if (foo === undefined) {
    ⋮
}

Некоторые распространенные заблуждения по этому поводу включают:

  • что чтение «неинициализированной» переменной (var foo) или параметра (function bar(foo) { … }, называемое bar()) завершится ошибкой. Это просто неправда - переменные без явной инициализации и параметры, которым не были присвоены значения, всегда становятся undefined и всегда находятся в области видимости.

  • что undefined можно перезаписать. Это правда, что undefined не является ключевым словом, но он является доступен только для чтения и не подлежит настройке. Есть и другие встроенные модули, которых вы, вероятно, не избежите, несмотря на их статус без ключевых слов (Object, Math, NaN ...), и практический код обычно не написан в активно вредоносной среде, поэтому это не хорошая причина для беспокоился о undefined. (Но если вы пишете генератор кода, не стесняйтесь использовать void 0.)

Разобравшись с принципами работы переменных, пришло время обратиться к самому вопросу: свойствам объекта. Нет причин использовать typeof для свойств объекта. Предыдущее исключение, касающееся обнаружения функций, здесь не применяется - typeof имеет особое поведение только для переменных, а выражения, которые ссылаются на свойства объекта, не являются переменными.

Этот:

if (typeof foo.bar === 'undefined') {
    ⋮
}

равно всегда точно эквивалентен к этому³:

if (foo.bar === undefined) {
    ⋮
}

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

Когда дело доходит до свойств объекта, следует учитывать еще одно: действительно ли вы хотите вообще проверять undefined. Данное имя свойства может отсутствовать в объекте (при чтении дает значение undefined), присутствовать в самом объекте со значением undefined, присутствовать в прототипе объекта со значением undefined или присутствовать на любом из объектов с не-undefined ценить. 'key' in obj сообщит вам, находится ли ключ где-либо в цепочке прототипов объекта, а Object.prototype.hasOwnProperty.call(obj, 'key') сообщит вам, находится ли он непосредственно на объекте. Я не буду вдаваться в подробности в этом ответе о прототипах и использовании объектов в качестве карт со строковыми ключами, поскольку он в основном предназначен для противодействия всем плохим советам в других ответах, независимо от возможных интерпретаций исходного вопроса. Прочтите прототипы объектов на MDN, чтобы узнать больше!

¹ unusual choice of example variable name? this is real dead code from the NoScript extension for Firefox.
² don’t assume that not knowing what’s in scope is okay in general, though. bonus vulnerability caused by abuse of dynamic scope: Project Zero 1225
³ once again assuming an ES5+ environment and that undefined refers to the undefined property of the global object.

@BenjaminGruenbaum Верно, но полностью вводит в заблуждение. Любой контекст, отличный от контекста по умолчанию, может определять свой собственный undefined, скрывая контекст по умолчанию. Что для большинства практических целей имеет тот же эффект, что и его перезапись.

blgt 25.03.2014 18:32

@blgt Это параноик и не имеет отношения ни к чему практическому. Каждый контекст может переопределить console.info, переопределить методы прототипа Array и даже переопределить перехват и изменение Function.prototype.call` каждый раз, когда вы вызываете функцию в JavaScript. Защищаться от этого очень параноидально и довольно глупо. Как я (и minitech) сказал, вы можете использовать void 0 для сравнения с undefined, но опять же - это глупо и излишне.

Benjamin Gruenbaum 25.03.2014 18:41

Мне жаль, что у меня не было более одного голоса за. Это самый правильный ответ. Я действительно хочу перестать видеть typeof something === "undefined") в коде.

Simon Baumgardt-Wellander 20.02.2018 22:37

@BenjaminGruenbaum Для ленивых программистов void 0 (на этот раз) и короче, и безопаснее и! В моей книге это победа.

wizzwizz4 11.04.2018 21:31

Это действительно должен быть принятый ответ. Он самый тщательный и актуальный.

Patrick Michaelsen 10.04.2019 23:40

Любой контекст, отличный от контекста по умолчанию, также может перезаписать, скажем, Math, или Object, или setTimeout, или буквально все, что вы ожидаете найти в глобальной области по умолчанию.

CherryDT 18.03.2020 00:21

ohw kay foo! == void 0 работает и короче, думаю, я могу использовать это: 3, и я знал, что вы имеете в виду свой собственный ответ, когда вы прокомментировали это>: D

Fuseteam 30.07.2020 02:54

теперь он не документирует то, что он делает, и может сбивать с толку, поэтому вместо этого я сделаю функцию isDefined return true, если не void 0, и false, если это так, и вместо этого верну>: 3

Fuseteam 30.07.2020 03:02

@Fuseteam: используйте !== undefined. Собственно, совет по void 0, наверное, стоит убрать.

Ry- 30.07.2020 03:18

@Fuseteam: он не такой читабельный и не имеет практических преимуществ перед undefined.

Ry- 30.07.2020 21:41

Я работал над удобочитаемостью, заключив ее в функцию isDefined (переменная), поэтому теперь я могу просто вызвать эту функцию, чтобы сделать это, как if (isDefined(variable))//do something xD, так что она короче и многоразовая, я думаю

Fuseteam 30.07.2020 22:54

@Fuseteam: Опять же, я настоятельно рекомендую не делать этого, а вместо этого написать if (variable !== undefined). Сравнение с undefined однозначно и знакомо, избыточные функции оболочки создают неопределенность («может быть, это также проверяет null?») Без улучшения читаемости.

Ry- 30.07.2020 23:00

я действительно изучал, какие еще типы "неопределенных" значений возможны, но достаточно справедливы

Fuseteam 30.07.2020 23:06

"propertyName" in obj //-> true | false

Также то же самое можно написать короче:

if (!variable){
    // Do it if the variable is undefined
}

или же

if (variable){
    // Do it if the variable is defined
}

Ваш первый случай может быть инициирован определенной переменной. Например, если переменная = 0, сработает! Переменная. Так что ваш ответ совершенно неверен.

Stranded Kid 10.07.2015 12:44

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

Ynot 12.05.2017 05:54

@Ynot - !variable будет истинным, если variable не определен, или определено и оказывается равным 0, ложный, так далее. Я не понимаю, как это может быть ответом на вопрос OP или хоть чем-то полезным.

Scott Smith 20.04.2018 08:13

Я не поддержал это, потому что не думал, что это лучший ответ. Я думал, что Stranded Kid поднял хороший вопрос, но он неправильно охарактеризовал решение. Тот факт, что вы можете представить себе вариант использования, в котором что-то не так, не означает, что не существует варианта использования, в котором это правильно. Это напрямую связано с вопросом OP в том смысле, что, если вы понимаете последствия, это можно использовать без проблем, чтобы проверить, не определено ли свойство (|| false). например проверка флага if (myobject.isFeatureEnabled) {

Ynot 21.04.2018 10:01

Все ответы неполные. Это правильный способ узнать, что существует свойство, «определенное как undefined»:

var hasUndefinedProperty = function hasUndefinedProperty(obj, prop){
  return ((prop in obj) && (typeof obj[prop] == 'undefined'));
};

Пример:

var a = { b : 1, e : null };
a.c = a.d;

hasUndefinedProperty(a, 'b'); // false: b is defined as 1
hasUndefinedProperty(a, 'c'); // true: c is defined as undefined
hasUndefinedProperty(a, 'd'); // false: d is undefined
hasUndefinedProperty(a, 'e'); // false: e is defined as null

// And now...
delete a.c ;
hasUndefinedProperty(a, 'c'); // false: c is undefined

Жаль, что это был правильный ответ, и он погребен в неправильных ответах> _

Итак, всем, кто проходит мимо, я дам вам undefined бесплатно !!

var undefined ; undefined ; // undefined
({}).a ;                    // undefined
[].a ;                      // undefined
''.a ;                      // undefined
(function(){}()) ;          // undefined
void(0) ;                   // undefined
eval() ;                    // undefined
1..a ;                      // undefined
/a/.a ;                     // undefined
(true).a ;                  // undefined

Просматривая комментарии, для тех, кто хочет проверить и то, и другое, не определено ли оно или его значение равно null:

//Just in JavaScript
var s; // Undefined
if (typeof s == "undefined" || s === null){
    alert('either it is undefined or value is null')
}

Если вы используете библиотеку jQuery, jQuery.isEmptyObject() подойдет для обоих случаев,

var s; // Undefined
jQuery.isEmptyObject(s); // Will return true;

s = null; // Defined as null
jQuery.isEmptyObject(s); // Will return true;

//Usage
if (jQuery.isEmptyObject(s)) {
    alert('Either variable:s is undefined or its value is null');
} else {
     alert('variable:s has value ' + s);
}

s = 'something'; // Defined with some value
jQuery.isEmptyObject(s); // Will return false;

jQuery также позаботится о любых проблемах кроссбраузерной совместимости с различными API JavaScript.

Henry Heleine 10.12.2014 01:12

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

Object.defineProperty(window, 'undefined', {});

Это запрещает кому-либо изменять значение window.undefined, тем самым уничтожая код, основанный на этой переменной. При использовании "use strict" все попытки изменить его значение завершатся ошибкой, в противном случае они будут игнорироваться.

Если вы используете Angular:

angular.isUndefined(obj)
angular.isUndefined(obj.prop)

Underscore.js:

_.isUndefined(obj) 
_.isUndefined(obj.prop) 

Как добавить 1 к переменной x? Мне нужен Underscore или jQuery? (удивительно, что люди будут использовать библиотеки даже для самых элементарных операций, таких как проверка typeof)

Stijn de Witt 01.11.2015 05:43

Читая это, я удивлен, что не заметил этого. Я нашел несколько алгоритмов, которые сработают для этого.

Никогда не определялся

Если значение объекта никогда не было определено, это предотвратит возврат true, если он определен как null или undefined. Это полезно, если вы хотите, чтобы значение true возвращалось для значений, установленных как undefined.

if (obj.prop === void 0) console.info("The value has never been defined");

Определено как неопределенное или никогда не определено

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

if (obj.prop === undefined) console.info("The value is defined as undefined, or never defined");

Определяется как ложное значение, неопределенное, нулевое или никогда не определенное.

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

if (obj.prop == false || obj.prop === null || obj.prop === undefined) {
    console.info("The value is falsy, null, or undefined");
}

Думаю, можно последний пример заменить на if (!obj.prop)

Stijn de Witt 01.11.2015 05:24

@StijndeWitt, вы можете, я был довольно неопытен, когда писал это, и мой английский, похоже, был так же плох, тем не менее, в ответе нет ничего неверный

Travis 07.04.2017 17:31

var obj = {foo: undefined}; obj.foo === void 0 -> true. Как это "никогда не определялось как undefined"? Это не правильно.

Patrick Roberts 15.06.2017 21:40

@PatrickRoberts Ты прав. Когда я писал этот ответ в феврале 2015 года (до ES6), первый вариант, который я описал, действительно работал, но теперь он устарел.

Travis 15.05.2020 01:31

Я использую if (this.variable), чтобы проверить, определено ли оно. Простой if (variable), рекомендовано в предыдущем ответе, мне не подходит.

Оказывается, он работает только тогда, когда переменная является полем некоторого объекта obj.someField, чтобы проверить, определена ли она в словаре. Но мы можем использовать this или window в качестве объекта словаря, поскольку любая переменная является полем в текущем окне, насколько я понимаю. Поэтому вот тест:

if (this.abc) 
    alert("defined"); 
else 
    alert("undefined");

abc = "abc";
if (this.abc) 
    alert("defined"); 
else 
    alert("undefined");

Сначала он обнаруживает, что переменная abc не определена, и она определяется после инициализации.

Использовать:

Чтобы проверить, не определено ли свойство:

if (typeof something === "undefined") {
    alert("undefined");
}

Чтобы проверить, не является ли свойство неопределенным:

if (typeof something !== "undefined") {
    alert("not undefined");
}

Из lodash.js.

var undefined;
function isUndefined(value) {
  return value === undefined;
}

Он создает переменную местный с именем undefined, которая инициализируется значением по умолчанию - реальным undefined, а затем сравнивает value с переменной undefined.


Обновление 09.09.2019

Я обнаружил, что Lodash обновил свою реализацию. См. моя проблема и код.

Чтобы быть пуленепробиваемым, просто используйте:

function isUndefined(value) {
  return value === void 0;
}

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

var a = obj.prop || defaultValue;

Подходит, если у вас есть функция, которая получает дополнительное свойство конфигурации:

var yourFunction = function(config){

   this.config = config || {};
   this.yourConfigValue = config.yourConfigValue || 1;
   console.info(this.yourConfigValue);
}

Сейчас выполняется

yourFunction({yourConfigValue:2});
//=> 2

yourFunction();
//=> 1

yourFunction({otherProperty:5});
//=> 1

Я удивлен, что еще не видел этого предложения, но оно имеет даже большую конкретность, чем тестирование с typeof. Используйте Object.getOwnPropertyDescriptor(), если вам нужно знать, было ли свойство объекта инициализировано с помощью undefined или оно никогда не инициализировалось:

// to test someObject.someProperty
var descriptor = Object.getOwnPropertyDescriptor(someObject, 'someProperty');

if (typeof descriptor === 'undefined') {
  // was never initialized
} else if (typeof descriptor.value === 'undefined') {
  if (descriptor.get || descriptor.set) {
    // is an accessor property, defined via getter and setter
  } else {
    // is initialized with `undefined`
  }
} else {
  // is initialized with some other value
}

Это, вероятно, единственная явная форма определения того, имеет ли существующее имя свойства явное и предполагаемое значение undefined; который, тем не менее, относится к типу JavaScript.

"propertyName" in containerObject && ""+containerObject["propertyName"] == "undefined";
>> true \ false

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

Не будет ложных срабатываний, таких как пустые или пустые строки, нули, нули или пустые массивы и тому подобное. Это именно так. Проверяет, т. Е. Проверяет, существует ли имя свойства (в противном случае это было бы ложным срабатыванием), чем явно проверяет, является ли его значение undefined, например. неопределенного типа JavaScript в форме строкового представления (буквально «undefined»), следовательно, == вместо ===, потому что дальнейшее преобразование невозможно. И это выражение вернет истину только в том случае, если оба, то есть все условия, выполнены. Например. если имя-свойства не существует, оно вернет false. Это единственно правильный результат, поскольку несуществующие свойства не могут иметь значений, даже если они не определены.

Пример:

containerObject = { propertyName: void "anything" }
>> Object { propertyName: undefined }

// Now the testing

"propertyName" in containerObject && ""+containerObject["propertyName"] == "undefined";
>> true

/* Which makes sure that nonexistent property will not return a false positive
 * unless it is previously defined  */

"foo" in containerObject && ""+containerObject["foo"] == "undefined";
>> false

А что, если свойство нить имеет значение "undefined"? ... как в containerObject = { propertyName: "undefined" }

user8897421 18.12.2017 16:57

lol, хорошо ... вы получите именно тот ложный результат, который, как вы утверждаете, предотвращает ваш код. jsfiddle.net/pfwx5j51

user8897421 21.12.2017 17:30

... кроме того, с вашим кодом == и === будут вести себя одинаково, потому что вы всегда сравниваете совпадающие типы. Так что это различие несущественно.

user8897421 21.12.2017 17:35

@rockstar Точно, - вам не нужен статический оператор сравнения для аргументов одного и того же типа. Это было бы перебором. Более того, если значение свойства является строкой undefined или типом undefined, ничего не меняет. Потому что они оба имеют одинаковое значение и равную доходность. Вы можете сэкономить несколько битов, назначив "undefined" в качестве значения свойства. Это излишество, потому что вы сможете получить строку undefined, не назначая ее. Я согласен - технически вы можете считать это «ложным срабатыванием», но практически и эмпирически это не так. Спасибо, в любом случае.

Bekim Bacaj 22.12.2017 01:48

С аргументами одного типа === и == выполняют одинаковую работу. Когда типы не соответствуют ==, работает более, поэтому называть === "overkill" не имеет большого смысла, поскольку он всегда обеспечивает равный или более простой алгоритм.

user8897421 22.12.2017 02:11

undefined и "undefined" имеют одинаковое значение только в вашем тесте, что и делает его ложноположительным, поскольку цель вашего теста - найти именно такое различие. Так что это явный провал и в любом случае будет излишне сложным, поскольку ("prop" in obj) && obj.prop === undefined проще и на самом деле правильный. Ага, пожалуйста.

user8897421 22.12.2017 02:12

@rockstar у вас ложноположительный случай никогда не бывает. И когда это так - это преднамеренно и, следовательно, равноправно, но если вы чувствуете в этом сильное чувство, не стесняйтесь редактировать мой ответ.

Bekim Bacaj 22.12.2017 02:15

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

user8897421 22.12.2017 02:23

В том-то и дело, что я не вижу никакой другой причины присвоения неопределенного значения в виде строки, кроме использования этого значения как слова, означающего undefined в некотором читаемом тексте, и, следовательно, это излишество, потому что на самом деле нет необходимости писать это, чтобы иметь возможность получить его. p.s === является излишним в JS при работе с аргументами одного типа, потому что JS является динамическим по рождению, а не по расширению. К нему нужно принуждать строгость. В любом случае, прошу вас исправить мою ошибку. Таким образом, он получит вашу подпись.

Bekim Bacaj 22.12.2017 02:43

Довольно распространено заблуждение, что === должен выполнять больше работы из-за динамической природы JS, но на самом деле он должен делать меньше, потому что, когда типы не совпадают, он может немедленно вернуть false вместо того, чтобы входить в алгоритм рекурсивного принуждения. Это принудительное приведение типов, что и делает ==, когда типы не совпадают. Когда они совпадают, == и ===использовать идентичные алгоритмы.

user8897421 22.12.2017 03:12

... Что касается undefined, то, вероятно, довольно редко иметь это как явное значение в любом случае, но если кто-то проверяет его, то они, вероятно, используют его по какой-то причине (хотя null, возможно, лучше). В таком случае, я думаю, они захотят добиться различия. Во всяком случае, просто указание на то, что в таких случаях это может противоречить намерению.

user8897421 22.12.2017 03:12

Никогда не используйте null для того, чем он не является.

Bekim Bacaj 28.12.2017 20:20

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

user8897421 28.12.2017 21:45

Просто что-либо не определено в JavaScript, это неопределенный, не имеет значения, является ли это свойством внутри Объект / Массив или просто простой переменной ...

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

Просто проверьте, есть ли typeof whatever === 'undefined', и он вернет логическое значение.

Так написана знаменитая функция isUndefined() в AngularJs v.1x:

function isUndefined(value) {return typeof value === 'undefined';} 

Итак, как вы видите, функция получает значение, если это значение определено, она вернет false, в противном случае для неопределенных значений вернет true.

Итак, давайте посмотрим, каковы будут результаты, когда мы будем передавать значения, включая свойства объекта, как показано ниже, это список переменных, которые у нас есть:

var stackoverflow = {};
stackoverflow.javascipt = 'javascript';
var today;
var self = this;
var num = 8;
var list = [1, 2, 3, 4, 5];
var y = null;

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

isUndefined(stackoverflow); //false
isUndefined(stackoverflow.javascipt); //false
isUndefined(today); //true
isUndefined(self); //false
isUndefined(num); //false
isUndefined(list); //false
isUndefined(y); //false
isUndefined(stackoverflow.java); //true
isUndefined(stackoverflow.php); //true
isUndefined(stackoverflow && stackoverflow.css); //true

Как видите, мы можем проверить что угодно, используя что-то вроде этого в нашем коде, как уже упоминалось, вы можете просто использовать typeof в своем коде, но если вы используете его снова и снова, создайте функцию, такую ​​как образец angular, которым я делюсь, и продолжайте повторно использовать как показано в следующем шаблоне кода DRY.

Еще одна вещь: для проверки свойства объекта в реальном приложении, в котором вы не уверены, существует ли объект или нет, сначала проверьте, существует ли объект.

Если вы проверите свойство объекта, а объект не существует, выдаст ошибку и остановит работу всего приложения.

isUndefined(x.css);
VM808:2 Uncaught ReferenceError: x is not defined(…)

Настолько просто, что вы можете заключить его внутрь оператора if, как показано ниже:

if (typeof x !== 'undefined') {
  //do something
}

Что также равно isDefined в Angular 1.x ...

function isDefined(value) {return typeof value !== 'undefined';}

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

Я также добавляю этот раздел из MDN, в котором есть полезная информация о typeof, undefined и void (0).

Strict equality and undefined
You can use undefined and the strict equality and inequality operators to determine whether a variable has a value. In the following code, the variable x is not defined, and the if statement evaluates to true.

var x;
if (x === undefined) {
   // these statements execute
}
else {
   // these statements do not execute
}

Note: The strict equality operator rather than the standard equality operator must be used here, because x == undefined also checks whether x is null, while strict equality doesn't. null is not equivalent to undefined. See comparison operators for details.


Typeof operator and undefined
Alternatively, typeof can be used:

var x;
if (typeof x === 'undefined') {
   // these statements execute
}

One reason to use typeof is that it does not throw an error if the variable has not been declared.

// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
   // these statements execute
}

if (x === undefined) { // throws a ReferenceError

}

However, this kind of technique should be avoided. JavaScript is a statically scoped language, so knowing if a variable is declared can be read by seeing whether it is declared in an enclosing context. The only exception is the global scope, but the global scope is bound to the global object, so checking the existence of a variable in the global context can be done by checking the existence of a property on the global object (using the in operator, for instance).


Void operator and undefined

The void operator is a third alternative.

var x;
if (x === void 0) {
   // these statements execute
}

// y has not been declared before
if (y === void 0) {
   // throws a ReferenceError (in contrast to `typeof`)
}

подробнее> здесь

Я предполагаю, что вы также захотите проверить, является ли он либоundefined или null. Если да, то предлагаю:

myVar == null

Это один из немногих случаев, когда двойное равенство очень полезен, поскольку он будет оценивать как true, когда myVar является undefined или null, но он будет оценивать как false, когда это другие ложные значения, такие как 0, false, '' и NaN.

Это фактический исходный код для метода Lodash isNil.

Удивлен, что больше голосов и комментариев не набралось. Что люди думают по этому поводу?

IliasT 09.02.2018 21:33

Я предлагаю здесь три способа для тех, кто ожидает странных ответов:

function isUndefined1(val) {
    try {
        val.a;
    } catch (e) {
        return /undefined/.test(e.message);
    }
    return false;
}

function isUndefined2(val) {
    return !val && val+'' === 'undefined';
}

function isUndefined3(val) {
    const defaultVal = {};
    return ((input = defaultVal) => input === defaultVal)(val);
}

function test(func){
    console.group(`test start :`+func.name);
    console.info(func(undefined));
    console.info(func(null));
    console.info(func(1));
    console.info(func("1"));
    console.info(func(0));
    console.info(func({}));
    console.info(func(function () { }));
    console.groupEnd();
}
test(isUndefined1);
test(isUndefined2);
test(isUndefined3);

isUndefined1:

Попробуйте получить свойство входного значения и проверьте сообщение об ошибке, если оно существует. Если входное значение не определено, сообщение об ошибке будет Uncaught TypeError: невозможно прочитать свойство 'b' неопределенного значения.

isUndefined2:

Преобразуйте входное значение в строку для сравнения с "undefined" и убедитесь, что это отрицательное значение.

isUndefined3:

В JavaScript необязательный параметр работает, если входное значение точно undefined.

Вы можете использовать функцию объекта JavaScript следующим образом:

var ojb  = {
    age: 12
}

if (ojb.hasOwnProperty('name')){
    console.info('property exists and is not undefined');
}

Вышеупомянутый метод возвращает true, если он получил это свойство или свойство не определено.

Вы также можете использовать прокси. Он будет работать с вложенными вызовами, но потребует еще одной дополнительной проверки:

function resolveUnknownProps(obj, resolveKey) {
  const handler = {
    get(target, key) {
      if (
        target[key] !== null &&
        typeof target[key] === 'object'
      ) {
        return resolveUnknownProps(target[key], resolveKey);
      } else if (!target[key]) {
        return resolveUnknownProps({ [resolveKey]: true }, resolveKey);
      }

      return target[key];
    },
  };

  return new Proxy(obj, handler);
}

const user = {}

console.info(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }

Таким образом, вы будете использовать это как:

const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;
if (!isUndefined) {
  // Do something
}

В библиотеке Лодаш есть несколько маленьких помощников:

isUndefined - чтобы проверить, является ли ценитьundefined.

_.isUndefined(undefined) // => true
_.isUndefined(null) // => false

имеет - чтобы проверить, содержит ли объект свойство

const object = { 'a': { 'b': 2 } }

_.has(object, 'a.b') // => true
_.has(object, 'a.c') // => false

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

var handler = {
  get: function(target, name) {
    return name in target ? target[name] : 'N/A';
  }
};

var p = new Proxy({}, handler);
p.name = 'Kevin';
console.info('Name: ' +p.name, ', Age: '+p.age, ', Gender: '+p.gender)

Будет выводить приведенный ниже текст без получения неопределенного.

Name: Kevin , Age: N/A , Gender: N/A

Простой способ проверить, существует ли ключ, - использовать in:

if (key in obj) {
  // Do something
} else {
  // Create key
}

const obj = {
  0: 'abc',
  1: 'def'
}

const hasZero = 0 in obj

console.info(hasZero) // true

Поскольку OP конкретно спрашивает, определено ли свойство в объекте, теперь это самый прямой и понятный ответ для всех, кто использует современный JavaScript.

bjg222 12.09.2019 18:25

ECMAScript 10 представил новую функцию - необязательная цепочка, которую вы можете использовать для использования свойства объекта, только когда объект определен следующим образом:

const userPhone = user?.contactDetails?.phone;

Он будет ссылаться на свойство phone только тогда, когда определены user и contactDetails.

Ref. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

Раньше я часто использовал функцию get из lodash, очень удобную для доступа к объектам такого типа, но новая дополнительная цепочка покрывает большую часть использования _.get

Al Hill 05.06.2020 19:17

Я нашел эту статью, 7 советов по работе с undefined в JavaScript, которая показывает действительно интересные вещи о undefined. подобно:

Существование undefined является следствием разрешающей природы JavaScript, которая позволяет использовать:

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

Да, но как он отвечает на вопрос?

Peter Mortensen 25.07.2020 02:55

В JavaScript есть выражения правдивый и фальшивка. Если вы хотите проверить, является ли свойство неопределенным или нет, есть прямой способ использовать данное условие если,

  1. Использование концепции правда / ложь.
if (!ob.someProp){
    console.info('someProp is falsy')
}

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

  1. Использование проверки === undefined в условии if
if (ob.someProp === undefined){
    console.info('someProp is undefined')
}
  1. Использование typeof

typeof действует как комбинированная проверка на неопределенное значение и на наличие переменной.

if (typeof ob.someProp === 'undefined'){
    console.info('someProp is undefined')
}
  1. Использование метода hasOwnProperty

В объект JavaScript встроена функция hasOwnProperty в прототипе объекта.

if (!ob.hasOwnProperty('someProp')){
    console.info('someProp is undefined')
}

Не вдаваясь в подробности, но путь 1st мне кажется укороченным и привлекательным. Вот подробности о значениях правда / ложь в JavaScript, а undefined - это ложное значение, указанное там. Таким образом, состояние if работает нормально, без каких-либо сбоев. Помимо undefined, значения NaN, false (очевидно), '' (пустая строка) и число 0 также являются ложными.

Warning: Make sure the property value does not contain any falsy value, otherwise the if condition will return false. For such a case, you can use the hasOwnProperty method

... вы также проверяете примеры кода, которые публикуете? ... например ... if (typeof ob.someProp === undefined) { ...

Peter Seliger 12.05.2020 17:20

... вы также не можете небрежно "исправить / исправить" предоставленные вами примеры, которые отвечают, как проверить наличие неопределенного свойства, восклицая после этого Предупреждение ... на самом деле if (!ob.someProp) { console.info('someProp is undefined'); } с самого начала должен быть реализован как if (!ob.someProp) { console.info('someProp is falsy'); }

Peter Seliger 12.05.2020 17:25

@PeterSeliger Спасибо, что заметили это.

Kiran Maniya 12.05.2020 17:47

Я также указывал на ваш пример № 3 / typeof ... он все еще реализован неправильно ... он должен быть ... if (typeof ob.someProp === 'undefined') { ... ваш код сравнивается не со строковым значением, а с неопределенным значением. Вот почему вопрос о том, действительно ли вы тестируете перед публикацией.

Peter Seliger 14.05.2020 00:26

@PeterSeliger Еще раз спасибо, что заметили, ну, я написал это прямо в пост, поэтому он подвержен ошибкам. Я бы поиграл перед публикацией. Исправление сделано

Kiran Maniya 14.05.2020 10:24

Есть очень простой и легкий способ.

Вы можете использовать необязательная цепочка:

x = {prop:{name:"sajad"}}

console.info(x.prop?.name) // Output is: "sajad"
console.info(x.prop?.lastName) // Output is: undefined

или же

if (x.prop?.lastName) // The result of this 'if' statement is false and is not throwing an error

Вы можете использовать необязательную цепочку даже для функций или массивов.

По состоянию на середину 2020 года это реализовано не повсеместно. Проверьте документацию на https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

Это именно то, что я искал. Спасибо!

aecend 11.10.2020 10:28

Рассмотрение

Многие из приведенных ответов дают неправильный результат, потому что они не различают случай, когда свойство объекта не существует, и случай, когда свойство имеет значение undefined. Вот доказательство для наиболее популярных решений:

let obj = {
  a: 666,
  u: undefined // The 'u' property has value 'undefined'
               // The 'x' property does not exist
}

console.info('>>> good results:');
console.info('A', "u" in obj, "x" in obj);
console.info('B', obj.hasOwnProperty("u"),      obj.hasOwnProperty("x"));

console.info('\n>>> bad results:');
console.info('C', obj.u === undefined,          obj.x === undefined);
console.info('D', obj.u == undefined,           obj.x == undefined);
console.info('E', obj["u"] === undefined,       obj["x"] === undefined);
console.info('F', obj["u"] == undefined,        obj["x"] == undefined);
console.info('G', !obj.u,                      !obj.x);
console.info('H', typeof obj.u === 'undefined', typeof obj.x === 'undefined');

В недавнем выпуске JavaScript появился новый оператор цепочки, который, скорее всего, является лучшим способом проверить, существует ли свойство, иначе он даст вам undefined.

см. пример ниже

  const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

const dogName = adventurer.dog?.name;
console.info(dogName);
// expected output: undefined

console.info(adventurer.someNonExistentMethod?.());
// expected output: undefined

Мы можем заменить этот старый синтаксис

if (response && response.data && response.data.someData && response.data.someData.someMoreData) {}

с этим более аккуратным синтаксисом

if ( response?.data?.someData?.someMoreData) {}

Этот синтаксис не поддерживается в IE, Opera, safari и samsund android.

для более подробной информации вы можете проверить этот URL

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

Версия для использования динамических переменных Вы знали?

var boo ='lala';

function check(){
  if (this['foo']){
        console.info('foo is here');}
  else{
        console.info('have no foo');
      }

  if (this['boo']){
        console.info('boo is here');}
  else{
        console.info('have no boo');
      }
}

check();

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