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

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


person Matt Sheppard    schedule 26.08.2008    source источник


Ответы (48)


Обычный способ проверить, является ли значение свойства специальным значением 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`");
}
person Community    schedule 06.01.2009
comment
если что-то имеет значение null, оно определяется (как null), но вы также можете сопрягать проверки. Раздражающая деталь приведенного выше кода заключается в том, что вы не можете определить функцию для ее проверки, ну, вы можете определить функцию ... но попробуйте ее использовать. - person neu-rah; 25.06.2012
comment
@ neu-rah, почему ты не можешь написать функцию? почему бы что-то подобное не сработать? Мне кажется, это работает. Есть случай, который я не рассматриваю? jsfiddle.net/djH9N/6 - person Zack; 24.09.2012
comment
@Zack В ваших тестах для isNullorUndefined не учитывался случай, когда вы вызываете isNullOrUndefined (f), а f не объявлен (т.е. когда нет объявления var f). - person pnkfelix; 15.02.2013
comment
Мля, сейчас тысячи голосов. Это наихудший способ сделать это. Надеюсь, прохожие увидят этот комментарий и решат проверить… кхм… другие ответы. - person Ry-♦; 14.05.2014
comment
Вы можете просто использовать obj !== undefined сейчас. undefined раньше было изменчивым, как undefined = 1234, что могло приводить к интересным результатам. Но после Ecmascript 5 он больше не доступен для записи, поэтому мы можем использовать более простую версию. codereadability.com/how-to-check-for-undefined -in-javascript - person Bruno Buccolo; 15.03.2016
comment
@ Райан, какой еще ответ? - person user1032531; 14.12.2017
comment
@ user1032531: Я бы порекомендовал свой - person Ry-♦; 14.12.2017
comment
Одного большого пальца явно недостаточно. Спасибо. - person Anjana Silva; 10.09.2020
comment
grrr im просто _1 _... нет шансов ошибиться в написании undefined и работает в глобальной области - person Ray Foss; 05.02.2021

Я считаю, что на эту тему есть несколько неправильных ответов. Вопреки распространенному мнению, «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 не объявлен.

person MarkPflug    schedule 23.08.2010
comment
+1 за то, что отметили, что myVar === undefined вызовет ошибку, если myVar не был объявлен - person Enrique; 19.12.2011
comment
Я согласен с тем, что undefined не является ключевым словом, undefined - это предопределенная переменная с неопределенным значением. Что-то вроде предупреждения, это функция, которую вы можете переопределить чем-то другим. Alert также не является ключевым словом, а является частью стандартного набора функций, ap частью оконного объекта, имеющего глобальную область видимости. Как и undefined, вы также можете переопределить функцию предупреждения, переназначив ее. Например: window.alert = function (s) {console.log (s); } также является законной конструкцией. - person Codebeat; 08.11.2012
comment
А как насчет if(typeof myVar != "undefined"). "!=" приемлемо? - person Kevin Meredith; 05.07.2013
comment
в дополнение к комментариям Marks я этого не понимаю: myVar === undefined вызовет ошибку в ситуации, когда myVar не объявлен. - почему это плохо? Почему я не хочу получить ошибку, если я ссылаюсь на необъявленные переменные? - person eis; 20.08.2013
comment
@Kevin Да, это так, потому что typeof всегда будет возвращать строку, что делает ненужным сравнение с типобезопасностью. Просто считается хорошей практикой использовать === соотв. !== исключительно. На самом деле я думаю, что jQuery использует только !=. - person Ingo Bürk; 24.08.2013
comment
Также имейте в виду, что вы всегда можете сделать void 0, чтобы получить значение, на которое указывает undefined. Итак, вы можете сделать if (myVar === void 0). 0 не особенный, вы можете поместить туда буквально любое выражение. - person Claudiu; 03.10.2013
comment
В современных браузерах (FF4 +, IE9 +, Chrome unknown) больше невозможно изменить undefined. MDN: undefined - person user247702; 07.02.2014
comment
скрипт для демонстрации этого момента - person rojobuffalo; 16.01.2015
comment
@Stijn: Хотя изменить глобальный undefined невозможно, все же можно переопределить его локально, как показано в этом ответе. Скопируйте и вставьте образец кода ответа в современный браузер, и вы увидите, что myVar === undefined по-прежнему может вызывать проблемы. - person dharcourt; 02.10.2015
comment
@KevinMeredith! = Приемлемо? Это определенно. В моей книге он лучше, чем !==, поскольку он короче, а более длинные формы не дают никаких преимуществ i.c.w. typeof. - person Stijn de Witt; 01.11.2015
comment
Этот ответ тоже неверен. Вопрос касался неопределенных свойств объекта, а не неопределенных переменных. Есть существенная разница. Например, вполне разумно сделать if (obj.field === undefined). Я думаю, что риск того, что кто-то сделает var undefined = false;, переоценен. Вам придется запрограммировать неоправданно оборонительную программу, если вы хотите защитить себя от всех подобных побочных эффектов, вызванных плохим программированием. - person Zero3; 15.12.2015
comment
Правило X: НИКОГДА не используйте зарезервированные слова в качестве имени переменной, функции или чего-либо еще. Не понимаю, что у вас так много положительных голосов. Поскольку это возможно, это не означает, что это законно, кроме того, это может измениться в будущем, и ваш код (и все, что от него зависит) больше не работает. Это плохой / ненадежный пример, и он показывает, как этого не делать. - person Codebeat; 23.11.2016
comment
поскольку для свойства записи undefined установлено значение false. даже если вы назначите false для undefined, оно не будет установлено. поэтому undefined будет undefined, всегда не false, поэтому ваш ответ не имеет смысла. Вы можете проверить это в спецификации сценария ECMA для JavaScript. ecma-international.org/ecma-262/5.1/# сек-15.1.1.3 - person Velu S Gautam; 25.07.2017
comment
Просто исходя из опыта, я думаю, вы действительно хотите, чтобы ваш код выдавал эту ошибку ReferenceError, если переменная не объявлена. Это так неприятно, когда что-то молча терпит неудачу. - person Atav32; 31.07.2017
comment
@MarkPflug: К сожалению, в 2010 году это тоже не имело смысла. undefined не является ключевым словом в 2017 году. Вы все еще можете использовать var undefined = false;. Ответом на этот вопрос всегда было «не делай этого», а не «используйте запутанные обходные пути для чего-то, чего никогда не бывает». - person Ry-♦; 16.08.2017
comment
Забавно, что люди предлагают эти глупые и подверженные ошибкам взломы, чтобы избежать затенения undefined (что могло быть сделано только ужасным разработчиком), но они беспечно используют другие глобальные идентификаторы, которые также могли быть затенены. Странно. Просто странно. - person ; 18.12.2017
comment
^ полностью согласен. кто-то, кто может затенять undefined, может также затенять Math или назначать Function.prototype.apply или что-нибудь, что вы считаете само собой разумеющимся! Пожалуйста. ^ полностью согласен. кто-то, кто может затенять undefined, может также затенять Math или назначать Function.prototype.apply или что-нибудь, что вы считаете само собой разумеющимся! Пожалуйста. Как насчет Object.prototype.toJSON=()=>({rick:'rolled'})? JSON.stringify({hello:'world'}) === '{"rick":"rolled"}' тогда. Есть так много способов нарушить ожидаемую среду JavaScript, что вы не можете написать код, который работает со всеми этими вещами. - person CherryDT; 18.03.2020

Несмотря на то, что здесь яростно рекомендуют многие другие ответы, 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, чтобы узнать больше!

¹ необычный выбор имени переменной в качестве примера? это настоящий мертвый код из расширения NoScript для Firefox.
² не думайте, что незнание того, что находится в области видимости, в целом нормально. дополнительная уязвимость, вызванная злоупотреблением динамической областью видимости: Project Zero 1225
³ снова предполагается, что среда ES5 + и что undefined относится к свойству undefined глобального объекта.

person Ry-♦    schedule 26.02.2014
comment
@BenjaminGruenbaum Верно, но полностью вводит в заблуждение. Любой контекст, отличный от контекста по умолчанию, может определять свой собственный undefined, скрывая контекст по умолчанию. Что для большинства практических целей имеет тот же эффект, что и его перезапись. - person blgt; 25.03.2014
comment
@blgt Это параноик и не имеет отношения ни к чему практическому. Каждый контекст может переопределить console.log, переопределить методы прототипа Array и даже переопределить перехват и изменение Function.prototype.call` каждый раз, когда вы вызываете функцию в JavaScript. Защищаться от этого очень параноидально и довольно глупо. Как я (и minitech) сказал, вы можете использовать void 0 для сравнения с undefined, но опять же - это глупо и излишне. - person Benjamin Gruenbaum; 25.03.2014
comment
Мне жаль, что у меня не было более одного голоса за. Это самый правильный ответ. Я действительно хочу перестать видеть typeof something === "undefined") в коде. - person Simon Baumgardt-Wellander; 20.02.2018
comment
@BenjaminGruenbaum Для ленивых программистов void 0 (на этот раз) и короче , и безопаснее! В моей книге это победа. - person wizzwizz4; 11.04.2018
comment
Это действительно должен быть принятый ответ. Он самый тщательный и актуальный. - person Patrick Michaelsen; 10.04.2019
comment
Любой контекст, отличный от контекста по умолчанию, также может перезаписать, скажем, Math, Object или setTimeout, или буквально все, что вы ожидаете найти в глобальной области по умолчанию. - person CherryDT; 18.03.2020
comment
ohw kay foo! == void 0 работает и короче, думаю, я могу использовать это: 3, и я знал, что вы имеете в виду свой собственный ответ, когда вы прокомментировали это ›: D - person Fuseteam; 30.07.2020
comment
теперь он не документирует то, что он делает, и может сбивать с толку, поэтому вместо этого я сделаю функцию isDefined, возвращающую true, если не void 0, и false, если это так, и вместо этого верну это ›: 3 - person Fuseteam; 30.07.2020
comment
@Fuseteam: используйте !== undefined. На самом деле, мне, наверное, следует удалить совет по поводу void 0. - person Ry-♦; 30.07.2020
comment
@Fuseteam: он не такой читабельный и не имеет практических преимуществ перед undefined. - person Ry-♦; 30.07.2020
comment
Я работал над удобочитаемостью, заключив ее в функцию isDefined (переменная), поэтому теперь я могу просто вызвать эту функцию, чтобы сделать это как if(isDefined(variable))//do something xD, так что она короче и многоразовая, я думаю - person Fuseteam; 30.07.2020
comment
@Fuseteam: Опять же, я настоятельно рекомендую не делать этого, а вместо этого писать if (variable !== undefined). Сравнение с undefined однозначно и знакомо, избыточные функции-оболочки создают неопределенность («может быть, это также проверяет null?») Без улучшения читабельности. - person Ry-♦; 30.07.2020
comment
я действительно изучал, какие еще типы неопределенных значений возможны, но достаточно справедливо - person Fuseteam; 30.07.2020

В JavaScript есть null и есть undefined. У них разные значения.

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

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

Существует также аналогичное значение null, означающее «это значение определено, но не имеет значения». Разница в значениях между undefined и null в основном академическая и обычно не очень интересная. В практических программах часто необходимо проверить, «имеет ли что-то ценность». В этих случаях может использоваться выражение something == undefined, потому что, даже если это не совсем одно и то же значение, null == undefined вернет истину.

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

if (something == undefined)

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

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

alert(person.name); // "John"
alert(person.fakeVariable); // undefined
person Pandincus    schedule 26.08.2008
comment
if (something == undefined) лучше писать как if (something === undefined) - person Sebastian Rittau; 30.11.2009
comment
Следует отметить, что это не совсем безопасно. undefined - это просто переменная, которую пользователь может переназначить: запись undefined = 'a'; приведет к тому, что ваш код больше не будет делать то, что вы думаете. Использование typeof лучше, и оно также работает для переменных (а не только свойств), которые не были объявлены. - person Gabe Moothart; 14.04.2010
comment
если что-то является неопределенной глобальной переменной, (something == undefined) вызывает ошибку javascript. - person Morgan Cheng; 21.04.2010
comment
Проблема в том, что если var a = null, тогда a == undefined оценивается как true, даже если a определенно определено. - person Andrew; 19.05.2011
comment
if (something === undefined) у меня не работает с ie7 или ie8 if (typeof something == "undefined") есть. - person juhan_h; 14.06.2011
comment
Эта интерпретация комментария Eloquent Javascript обратная. Если вы действительно хотите просто проверить наличие undefined, предлагаемый код не будет работать (он также обнаружит определенное условие, но еще не присвоено значение [т.е. пустое]). Пустое значение. Предлагаемый код if (something == undefined) ... проверяет наличие обоих undefined и null (значение не установлено), т.е. он интерпретируется как if ((something is undefined) OR (something is null)) ... Автор говорит, что часто вы действительно хотите проверить наличие как undefined, так и null. - person Chuck Kollars; 18.05.2012

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

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

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.

person Konstantin Smolyanin    schedule 08.08.2013
comment
@Bergi спасибо за ваш комментарий. Я исправил свой ответ. В свою защиту могу сказать, что в настоящее время (начиная с версии 0.10.18) официальная документация Node.js ничего не говорит о undefined как члене global. Также ни console.log(global);, ни for (var key in global) { ... } не показывают undefined как член global. Но тест вроде 'undefined' in global показывает обратное. - person Konstantin Smolyanin; 11.09.2013
comment
Дополнительная документация не требовалась, поскольку она включена в спецификацию EcmaScript, в которой также говорится что [[Enumerable]] ложно :-) - person Bergi; 11.09.2013
comment
Что касается Minuses of typeof obj.prop == 'undefined', этого можно избежать, написав как typeof obj.prop == typeof undefined. Это также дает очень красивую симметрию. - person hlovdal; 24.10.2014
comment
@hlovdal: Это совершенно бессмысленно против obj.prop === undefined. - person Ry-♦; 12.04.2018
comment
Когда мы верны заголовку вопроса «Обнаружение неопределенного свойства», это не соответствует (другому и гораздо более простому) вопросу в первом предложении («проверьте, не определено ли. .. “), вы отвечаете if ('foo' in o)… ваш ответ действительно первый правильный ответ здесь. Практически все остальные просто отвечают на это предложение. - person Frank Nocke; 11.06.2018

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

  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); }

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

person Michael Anderson    schedule 08.06.2011
comment
Привет Майкл. Отличное предложение, и я думаю, оно делает вещи чище. Однако я обнаружил одну ошибку, когда я использовал! оператор с in. Вы должны сказать if (!("x" in blob)) {} в квадратных скобках, потому что! оператор имеет приоритет перед 'in'. Надеюсь, это кому-то поможет. - person Simon East; 15.06.2011
comment
Извините, Майкл, но это неверно или, по крайней мере, вводит в заблуждение в свете исходного вопроса. 'in' не является достаточным способом проверить, имеет ли свойство объекта typeof undefined. Для доказательства см. Эту скрипку: jsfiddle.net/CsLKJ/4 - person tex; 25.02.2012
comment
Эти две части кода делают разные вещи! Учитывать и возражать, данное a = {b: undefined}; затем typeof a.b === typeof a.c === 'undefined', но 'b' in a и !('c' in a). - person mgol; 27.09.2012
comment
+1. OP не дает понять, существует ли свойство и имеет ли значение undefined, или само свойство undefined (т.е. не существует). - person RobG; 01.04.2014
comment
Я бы предложил изменить точку (2.) в вашей первой таблице на { x : undefined } или, по крайней мере, добавить ее в качестве другой альтернативы (2.) в таблице - мне пришлось на мгновение подумать, чтобы понять, что точка (2.) оценивается как undefined (хотя вы упомянули об этом позже). - person mucaho; 14.05.2015
comment
@mucaho Это было бы лучше, но я думаю, что есть (или, по крайней мере, были?) некоторые проблемы с такой конструкцией - то есть undefined не (не было?) гарантированно не определено. - person Michael Anderson; 15.05.2015

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

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

person Kevin    schedule 27.07.2010
comment
паренсы не нужны, так как typeof является оператором - person aehlke; 10.08.2010
comment
Но они проясняют, что проверяется. В противном случае это могло бы читаться как typeof (something == "undefined"). - person Abhi Beckert; 06.09.2012
comment
Если вам нужны круглые скобки, вам следует изучить приоритет операторов в JS: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ - person Ian; 07.03.2014
comment
Круглые скобки полезны именно потому, что вам НЕ нужно изучать приоритет операторов в JS, и вам не нужно размышлять о том, нужно ли будущим программистам обслуживания изучать приоритет операторов в JS. - person DaveWalley; 11.04.2014
comment
Круглые скобки полезны, чтобы прояснить ситуацию. Но в этом случае они просто делают оператор похожим на функцию. Несомненно, это проясняет намерения программиста. Но если вы не уверены в приоритете операторов, вам лучше записать его как (typeof something) === "undefined". - person Robert; 14.05.2014
comment
@Robert Я согласен с тем, что вы используете скобки (окружающие typeof), но в ES6 вы не можете использовать скобки для вызова функции, например quux `foo\n${ 42 }bar`. - person CPHPython; 07.03.2018

Я не уверен, откуда взялось использование === с 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
person Eric    schedule 22.09.2010
comment
Отличный момент, Эрик. Есть ли снижение производительности от проверки типа? - person Simon East; 29.06.2011
comment
@Simon: как раз наоборот - можно было ожидать небольшого снижения производительности из-за избегания принуждения в случае '==='. Быстрый и грязный тест показал, что '===' на 5% быстрее, чем '==' в FF5.0.1. - person Antony Hatchkins; 18.12.2011
comment
Более тщательный тест показал, что в FF IE и Chrome '==' более или менее быстрее, чем '===' (5-10%), а Opera вообще не имеет никакого значения: jsperf.com/triple-equals-vs-twice-equals/6 - person Antony Hatchkins; 18.12.2011
comment
Использование == по-прежнему требует хотя бы проверки типа - интерпретатор не может сравнить два операнда, не зная предварительно их тип. - person Alnitak; 13.08.2012
comment
== на один символ меньше, чем === :) - person svidgen; 28.06.2013
comment
@svidgen Вы добавляете смайлик, но, видя, что сеть является самой медленной цепочкой в ​​ссылке, я на самом деле считаю, что вы увидите больший прирост производительности, если пропустите лишний символ, тогда вы когда-нибудь увидишь из проверки типа. 5% ничего - это еще ничто. Лично я ненавижу догматическое кодирование. Я позволяю вам выключать мозг во время набора текста, но нет никаких причин, по которым тройное равенство было бы безопаснее в этом случае. - person Stijn de Witt; 01.11.2015

Перекрестная публикация моего ответа из связанного вопроса Как проверить наличие неопределенности в 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.log(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
person drzaus    schedule 13.01.2013

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

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

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

ОБНОВЛЕНИЕ: (02.07.2021)

В последней версии JavaScript появился новый оператор для необязательного связывания: ?.

Вероятно, это будет наиболее явный и эффективный метод проверки существования свойств объекта в будущем.

Ссылка: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

person Joe Johnson    schedule 25.09.2012
comment
Если вы хотите узнать, почему это работает: Javascript: Логические операторы и правдивость / ложность - person mb21; 04.02.2013
comment
если вы хотите присвоить свойство переменной, если она определена, а не null и не falsey, иначе используйте какое-то значение по умолчанию, вы можете использовать: var x = obj && obj.prop || 'default'; - person Stijn de Witt; 01.11.2015
comment
Я считаю, что вопрос заключается в явной проверке undefined. Ваше условие проверяет все ложные значения JS. - person NikoKyriakid; 20.07.2018

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

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

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

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

Например:

var myvar = 'test';

Глобальная переменная myvar совпадает с window.myvar или window ['myvar']

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

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

Вопрос, действительно ли переменная существует, не имеет значения, ее значение неверно. В противном случае глупо инициализировать переменные неопределенным значением, и для инициализации лучше использовать значение 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');
}

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

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

(y)

person Codebeat    schedule 12.08.2011

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

function isUndefined(obj){
    return obj === void 0;
}
person Marthijn    schedule 19.12.2013
comment
void 0 - это просто краткий способ записи undefined (поскольку это то, что возвращает void, за которым следует любое выражение), он сохраняет 3 символа. Он также мог сделать var a; return obj === a;, но это еще один символ. :-) - person RobG; 01.04.2014
comment
void - зарезервированное слово, а undefined - нет, т.е. пока undefined по умолчанию равно void 0, вы можете присвоить значение undefined, например. undefined = 1234. - person Brian M. Hunt; 14.09.2015
comment
isUndefined(obj): 16 символов. obj === void 0: 14 знаков. Ничего не сказано. - person Stijn de Witt; 01.11.2015

Просто что-либо не определено в 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).

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

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

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


Оператор Typeof и undefined
В качестве альтернативы можно использовать typeof:

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

Одна из причин использования typeof заключается в том, что он не вызывает ошибки, если переменная не была объявлена.

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

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

}

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


Оператор аннулирования и неопределенный

Оператор void - третья альтернатива.

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`)
}

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

person Alireza    schedule 24.05.2017

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

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

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

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

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

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

person DenisS    schedule 10.02.2014
comment
Но что, если вы запустите Node? typeof history != 'undefined' фактически работает в обеих системах. - person Stijn de Witt; 01.11.2015

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

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

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

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

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

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

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

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

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

if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
    console.log("The value is falsy, null, or undefined");
}
person Travis    schedule 15.02.2015
comment
Думаю, вы можете заменить последний пример на if (!obj.prop) - person Stijn de Witt; 01.11.2015
comment
@StijndeWitt, вы можете, я был довольно неопытен, когда писал это, и мой английский, похоже, был одинаково плохим, тем не менее, в ответе нет ничего неправильного - person Travis; 07.04.2017
comment
var obj = {foo: undefined}; obj.foo === void 0 - ›true. Как это никогда не определяется как undefined? Это не правильно. - person Patrick Roberts; 15.06.2017
comment
@PatrickRoberts Ты прав. Когда я написал этот ответ в феврале 2015 года (до ES6), первый вариант, который я обрисовал, действительно работал, но теперь он устарел. - person Travis; 15.05.2020

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

null == undefined

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

if (something === undefined)

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

person Ricky    schedule 26.08.2008
comment
Чтобы было ясно, === - это равенство типов + (примитивное равенство | идентичность объекта), где примитивы включают строки. Я думаю, что большинство людей считают 'abab'.slice(0,2) === 'abab'.slice(2) неинтуитивным, если рассматривать === как оператор идентичности. - person clacke; 30.07.2010
comment
Неправильный. Это вызывает ошибку, если переменная не была создана. Не должно быть проголосовано. Вместо этого используйте typeof. - person Simon East; 15.06.2011
comment
Какое решение? Вы можете напрямую ссылаться на него? - person Peter Mortensen; 25.07.2020

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

const userPhone = user?.contactDetails?.phone;

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

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

person Przemek Struciński    schedule 27.09.2019
comment
Раньше я часто использовал функцию get из lodash, очень удобную для доступа к таким объектам, но новая дополнительная цепочка покрывает большую часть использования _.get - person Al Hill; 05.06.2020

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

if (foo !== void 0)

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

person bevacqua    schedule 02.01.2014
comment
Но это вызовет ошибку ReferenceError, если foo не объявлен. - person daniel1426; 08.03.2014
comment
@ daniel1426: Значит, если в вашем коде есть ошибка, вы хотите ее скрыть, а не исправлять? Не лучший подход, ИМО. - person ; 18.12.2017
comment
Это не используется для сокрытия ошибок. Это распространенный способ определения свойств среды для определения полифилов. Например: if (typeof Promise === 'undefined') {/ * define Promise * /} - person gaperton; 04.10.2018

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

 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

person Anoop    schedule 17.10.2011
comment
Хотя это не повлияет на действительность вашего кода, у вас есть опечатка: getUndefiend должно быть getUndefined. - person icktoofay; 14.05.2013

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

var a = obj.prop || defaultValue;

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

var yourFunction = function(config){

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

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

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

yourFunction();
//=> 1

yourFunction({otherProperty:5});
//=> 1
person Marian Klühspies    schedule 03.03.2016

Все ответы неполные. Это правильный способ узнать, что существует свойство, «определенное как 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
person Juan Garcia    schedule 18.06.2014

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

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

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

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

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

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

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

person wayneseymour    schedule 15.08.2013
comment
Ваш typeof страж на самом деле не защищает от всего, с чем не может справиться прямое сравнение. Если restResult не определен или не объявлен, он все равно выбросит. - person ; 18.12.2017
comment
В вашем случае вы могли бы проще проверить, пуст ли массив: if(!restResult.data.length) { throw "Some error"; } - person Headbank; 28.02.2019

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

//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;
person Angelin Nadar    schedule 08.07.2014
comment
jQuery также позаботится о любых проблемах кроссбраузерной совместимости с различными API JavaScript. - person Henry Heleine; 10.12.2014

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

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

Underscore.js:

_.isUndefined(obj) 
_.isUndefined(obj.prop) 
person Vitalii Fedorenko    schedule 14.12.2014
comment
Как добавить 1 к переменной x? Мне нужен Underscore или jQuery? (удивительно, что люди будут использовать библиотеки даже для самых элементарных операций, таких как typeof проверка) - person Stijn de Witt; 01.11.2015

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

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.log(func(undefined));
    console.log(func(null));
    console.log(func(1));
    console.log(func("1"));
    console.log(func(0));
    console.log(func({}));
    console.log(func(function () { }));
    console.groupEnd();
}
test(isUndefined1);
test(isUndefined2);
test(isUndefined3);

isUndefined1:

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

isUndefined2:

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

isUndefined3:

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

person blackmiaool    schedule 28.10.2017

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

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

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

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

or

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

person Sajad Saderi    schedule 05.05.2020
comment
Это именно то, что я искал. Спасибо! - person aecend; 11.10.2020

Я использую 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 не определена, и она определяется после инициализации.

person Val    schedule 06.03.2015

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

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

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

if (isUnset(var)) {
  // initialize variable here
}
person Rixius    schedule 12.07.2010
comment
Нет, не делай этого. Требуется всего лишь очень простой тест, чтобы доказать, что вы не можете осмысленно обернуть typeof тест в функцию. Удивительно, что за это проголосовали 4 человека. -1. - person Stijn de Witt; 01.11.2015

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

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

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

person Seti    schedule 09.10.2014

Из 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;
}
person lzl124631x    schedule 14.01.2016

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

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.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }

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

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

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

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

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

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

if (typeof something !== "undefined") {
    alert("not undefined");
}
person Mike Clark    schedule 14.08.2015

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

myVar == null

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

Это фактический исходный код для _ 13_.

person IliasT    schedule 15.06.2017
comment
Удивлен, что больше голосов и комментариев не набралось. Что люди думают по этому поводу? - person IliasT; 09.02.2018

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

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

or

if (variable){
    // Do it if the variable is defined
}
person raskalbass    schedule 16.06.2014
comment
Ваш первый случай может быть инициирован определенной переменной. Например, если переменная = 0, сработает! Переменная. Так что ваш ответ совершенно неверен. - person Stranded Kid; 10.07.2015
comment
Я думаю, что это просто неправильная формулировка, я думаю, он имел в виду сделать это, если переменная не определена или другое ложное значение, что часто является логикой, которую люди ищут. - person Ynot; 12.05.2017
comment
@Ynot - !variable будет истинным, если variable не определено, или определено и оказывается равным 0, false, и т. Д. . Я не понимаю, почему это либо ответ на вопрос OP, либо хоть какое-то полезное действие. - person Scott Smith; 20.04.2018
comment
Я не поддержал это, потому что не думал, что это лучший ответ. Я думал, что Stranded Kid поднял хороший вопрос, но он неправильно охарактеризовал решение. Тот факт, что вы можете представить себе вариант использования, в котором что-то не так, не означает, что не существует варианта использования, в котором это правильно. Это напрямую связано с вопросом OP в том смысле, что, если вы понимаете последствия, это можно использовать без проблем, чтобы проверить, не определено ли свойство (|| false). например проверка флага if (myobject.isFeatureEnabled) { - person Ynot; 21.04.2018

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

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

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

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

console.log(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

person Hanzla Habib    schedule 29.09.2020

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

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

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

const hasZero = 0 in obj

console.log(hasZero) // true
person CodeDraken    schedule 11.09.2018
comment
Поскольку OP конкретно спрашивает, определено ли свойство в объекте, теперь это самый прямой и понятный ответ для всех, кто использует современный JavaScript. - person bjg222; 12.09.2019

Представленный в 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.log('Name: ' +p.name, ', Age: '+p.age, ', Gender: '+p.gender)

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

Name: Kevin , Age: N/A , Gender: N/A
person Krishnadas PC    schedule 23.07.2018

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

isUndefined - чтобы проверить, равно ли value undefined.

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

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

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

_.has(object, 'a.b') // => true
_.has(object, 'a.c') // => false
person Aliaksandr Sushkevich    schedule 07.04.2018

Я удивлен, что еще не видел этого предложения, но он даже более конкретен, чем тестирование с 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
}
person Patrick Roberts    schedule 28.03.2017

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

var boo ='lala';

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

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

check();

person Adam111p    schedule 17.12.2020

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

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

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

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

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

person Kamil Kiełczewski    schedule 21.07.2020

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

var ojb ={
    age: 12
}

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

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

person Aditya Vashishtha    schedule 07.03.2018

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

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

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

Не будет ложных срабатываний, таких как пустые или пустые строки, нули, нули или пустые массивы и тому подобное. Это именно так. Проверяет, т. Е. Проверяет, существует ли имя свойства (в противном случае это было бы ложным срабатыванием), чем явно проверяет, равно ли его значение undefined, например. неопределенного типа JavaScript в форме строкового представления (буквально не определено), поэтому == вместо ===, потому что дальнейшее преобразование невозможно. И это выражение вернет истину только в том случае, если оба, то есть все условия, выполнены. Например. если имя-свойства не существует, оно вернет 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
person Bekim Bacaj    schedule 20.04.2017
comment
А что, если свойство имеет значение string "undefined"? ... как в containerObject = { propertyName: "undefined" } - person ; 18.12.2017
comment
lol, хорошо ... вы получите именно тот ложный результат, который, как вы утверждаете, предотвращает ваш код. jsfiddle.net/pfwx5j51 - person ; 21.12.2017
comment
... также с вашим кодом == и === будут вести себя одинаково, потому что вы всегда сравниваете совпадающие типы. Так что это различие несущественно. - person ; 21.12.2017
comment
@rockstar Точно, - вам не нужен статический оператор сравнения для аргументов одного и того же типа. Это было бы перебором. Более того, если значение свойства является строкой undefined или типом undefined, ничего не меняет. Потому что они оба имеют одинаковое значение и равную доходность. Вы можете сэкономить несколько битов, назначив undefined в качестве значения свойства. Это излишество, потому что вы сможете получить строку undefined, не назначая ее. Я согласен - технически вы можете считать это «ложным срабатыванием», но практически и эмпирически это не так. Спасибо, в любом случае. - person Bekim Bacaj; 22.12.2017
comment
С аргументами одного типа === и == выполняют одинаковую работу. Когда типы не совпадают, == выполняет больше работы, поэтому вызов === overkill не имеет большого смысла, поскольку он всегда обеспечивает равный или более простой алгоритм. - person ; 22.12.2017
comment
undefined и "undefined" имеют одинаковое значение только в вашем тесте, что и делает его ложноположительным, поскольку цель вашего теста - найти именно такое различие. Так что это явный провал и в любом случае будет излишне сложным, поскольку ("prop" in obj) && obj.prop === undefined проще и на самом деле правильно. Ага, пожалуйста. - person ; 22.12.2017
comment
@rockstar, у вас ложноположительный случай никогда не бывает. И когда это так - это преднамеренно и, следовательно, равноправно, но если вы чувствуете в этом сильное чувство, не стесняйтесь редактировать мой ответ. - person Bekim Bacaj; 22.12.2017
comment
Я не уверен, что вы имеете в виду, когда говорите, что это сделано преднамеренно и, следовательно, равноправно. Можно иметь строковое значение "undefined" по разным причинам, поэтому, если нет очень необычной ситуации, строка "undefined" должна быть так же отлична от значения undefined, как и строка "foobar". - person ; 22.12.2017
comment
В том-то и дело, что я не вижу никакой другой причины присвоения неопределенного значения в виде строки, кроме использования этого значения как слова, означающего undefined в некотором читаемом тексте, и, следовательно, это излишество, потому что на самом деле нет необходимости писать это, чтобы иметь возможность получить его. p.s === является излишним в JS при работе с аргументами одного типа, потому что JS является динамическим по рождению, а не по расширению. К нему нужно принуждать строгость. В любом случае, прошу вас исправить мою ошибку. Таким образом, он получит вашу подпись. - person Bekim Bacaj; 22.12.2017
comment
Довольно распространено заблуждение, что === должен выполнять больше работы из-за динамической природы JS, но на самом деле он должен делать меньше, потому что, когда типы не совпадают, он может вернуть false немедленно вместо использования алгоритма рекурсивного принуждения. Это принудительное приведение типов, что == и делает, когда типы не совпадают. Когда они совпадают, == и === используют идентичные алгоритмы. - person ; 22.12.2017
comment
... Что касается undefined, то, вероятно, довольно редко иметь это как явное значение в любом случае, но если кто-то проверяет его, то они, вероятно, используют его по какой-то причине (хотя null, возможно, лучше). В таком случае, я думаю, они захотят добиться различия. Во всяком случае, просто указание на то, что в таких случаях это может противоречить намерениям. - person ; 22.12.2017
comment
Никогда не используйте null для того, чем он не является. - person Bekim Bacaj; 28.12.2017
comment
О, не волнуйтесь, я не буду. Вот почему я говорю, что, возможно, лучше, чем undefined, представлять определенное свойство, не имеющее полезного значения. - person ; 28.12.2017

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

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

  • неинициализированные переменные
  • несуществующие свойства или методы объекта
  • индексы вне границ для доступа к элементам массива
  • результат вызова функции, которая ничего не возвращает
person Ravi Makwana    schedule 31.01.2020
comment
Да, но как он отвечает на вопрос? - person Peter Mortensen; 25.07.2020

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

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

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

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

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

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

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

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

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

Предупреждение: Убедитесь, что значение свойства не содержит ложных значений, иначе условие if вернет false. В таком случае вы можете использовать hasOwnProperty метод

person Kiran Maniya    schedule 01.05.2020
comment
... вы также проверяете публикуемые вами примеры кода? ... например ... if (typeof ob.someProp === undefined) { ... - person Peter Seliger; 12.05.2020
comment
... вы также не можете небрежно исправить / исправить предоставленные вами примеры, которые отвечают, как проверить наличие неопределенного свойства, восклицая после этого предупреждение ... фактически if (!ob.someProp) { console.log('someProp is undefined'); } с самого начала должно быть реализовано как if (!ob.someProp) { console.log('someProp is falsy'); } - person Peter Seliger; 12.05.2020
comment
@PeterSeliger Спасибо, что заметили это. - person Kiran Maniya; 12.05.2020
comment
Я также указывал на ваш пример №3 / typeof ... он все еще реализован неправильно ... он должен быть ... if (typeof ob.someProp === 'undefined') { ... ваш код сравнивается не со строковым значением, а с неопределенным значением. Вот почему вопрос о том, действительно ли вы тестируете перед публикацией. - person Peter Seliger; 14.05.2020
comment
@PeterSeliger Еще раз спасибо, что заметили, ну, я написал это прямо в пост, поэтому он подвержен ошибкам. Я бы поиграл перед публикацией. Исправление сделано - person Kiran Maniya; 14.05.2020

обрабатывать undefined

function isUndefined(variable,defaultvalue=''){

    if (variable == undefined )
    { 
        return defaultvalue;
    }
    return variable

}

var obj={
und:undefined,
notundefined:'hi i am not undefined'
}


function isUndefined(variable,defaultvalue=''){

    if (variable == undefined )
    { 
        return defaultvalue;
    }
    return variable

}

console.log(isUndefined(obj.und,'i am print'))
console.log(isUndefined(obj.notundefined,'i am print'))

person ßãlãjî    schedule 27.06.2021

Object.hasOwnProperty(o, 'propertyname');

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

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

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

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

function isset(varname){
  return(typeof(window[varname]) != 'undefined');
}
person tslocum    schedule 26.08.2008
comment
Во-первых, когда somevariable равно undefined, это не означает, что переменная не определена - это просто значение, которое не определено. Если переменная не определена, этот код выдаст ошибку. Во-вторых, эта функция isset будет работать только для глобальных переменных. - person Rene Saarsoo; 27.01.2010
comment
как насчет локальных переменных? странный трюк с окном [переменная] - person Denis; 27.08.2013