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



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


if (somevariable == undefined) {
alert('the variable is not defined!');
}
Вы также можете превратить его в функцию, как показано здесь:
function isset(varname){
return(typeof(window[varname]) != 'undefined');
}
как насчет локальных переменных? странный трюк с окном [переменная]
В 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)
Следует отметить, что это не совсем безопасно. undefined - это просто переменная, которую пользователь может переназначить: запись undefined = 'a'; приведет к тому, что ваш код больше не будет делать то, что вы думаете. Использование typeof лучше, и оно также работает для переменных (а не только свойств), которые не были объявлены.
если что-то является неопределенной глобальной переменной, (something == undefined) вызывает ошибку javascript.
Проблема заключается в том, что если var a = null, тогда a == undefined оценивается как true, даже если a определенно определено.
if (something === undefined) у меня не работает с ie7 или ie8 if (typeof something == "undefined") есть.
Эта интерпретация комментария «Красноречивый Javascript» - назад. Если вы действительно хотите просто проверить наличие undefined, предлагаемый код не будет работать (он также обнаружит определенное условие, но еще не присвоено значение [т.е. пустое]). Пустое значение. Предлагаемый код «if (something == undefined) ...» проверяет наличие обе undefined и null (значение не установлено), т.е. он интерпретируется как «if ((что-то не определено) OR (что-то равно null)) ...» Автор говорит, что часто вы хотите, чтобы В самом деле проверял наличие обе undefined и null.
Решение неверное. В JavaScript
null == undefined
вернет истину, потому что они оба "приведены" к логическому значению и являются ложными. Правильный способ - проверить
if (something === undefined)
который является тождественным оператором ...
Для ясности, === - это равенство типов + (примитивное равенство | идентичность объекта), где примитивы включают строки. Я думаю, что большинство людей считают 'abab'.slice(0,2) === 'abab'.slice(2) неинтуитивным, если рассматривать === в качестве оператора идентификации.
Неправильный. Это вызывает ошибку, если переменная не была создана. Не должно быть проголосовано. Вместо этого используйте typeof.
Какое решение? Вы можете напрямую ссылаться на него?
Обычный способ проверить, является ли значение свойства специальным значением 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, почему ты не можешь написать функцию? почему бы что-то подобное не сработать? Мне кажется, это работает. Есть случай, который я не рассматриваю? jsfiddle.net/djH9N/6
@Zack В ваших тестах для isNullorUndefined не учитывался случай, когда вы вызываете isNullOrUndefined (f), а f не объявлен (т.е. когда нет объявления "var f").
Мля, сейчас тысячи голосов. Это наихудший способ сделать это. Надеюсь, прохожие увидят этот комментарий и решат проверить… кхм… ответы Другой.
Теперь вы можете просто использовать obj !== undefined. undefined был изменчивым, как и undefined = 1234, что давало интересные результаты. Но после Ecmascript 5 он больше не доступен для записи, поэтому мы можем использовать более простую версию. codereadability.com/how-to-check-for-undefined-in-javascript
@ Райан, какой "другой ответ"?
@ user1032531: Я бы порекомендовал свой
Одного большого пальца явно недостаточно. Спасибо.
grrr im just going typeof window !== typeof undefined ... нет шансов ошибиться в написании undefined и работает в глобальном масштабе
function isUnset(inp) {
return (typeof inp === 'undefined')
}
Возвращает false, если переменная установлена, и true, если не определена.
Затем используйте:
if (isUnset(var)) {
// initialize variable here
}
Нет, не делай этого. Требуется только очень простой тест, чтобы доказать, что вы не можете осмысленно обернуть тест typeof в функцию. Удивительно, что за это проголосовали 4 человека. -1.
if ( typeof( something ) == "undefined")
У меня это сработало, а у других - нет.
паренсы не нужны, так как typeof является оператором
Но они проясняют, что проверяется. В противном случае его можно было бы прочитать как typeof (something == "undefined").
Если вам нужны круглые скобки, вам следует изучить приоритет операторов в JS: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Круглые скобки полезны именно потому, что вам НЕ нужно изучать приоритет операторов в JS, и вам не нужно размышлять о том, нужно ли будущим программистам обслуживания изучать приоритет операторов в JS.
Круглые скобки полезны, чтобы прояснить ситуацию. Но в этом случае они просто делают оператор похожим на функцию. Без сомнения, это проясняет намерения программиста. Но если вы не уверены в приоритете оператора, вам лучше написать его как (typeof something) === "undefined".
Я считаю, что на эту тему есть несколько неправильных ответов. Вопреки распространенному мнению, «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 не был объявлен
Я согласен с тем, что undefined не является ключевым словом, undefined - это предопределенная переменная с неопределенным значением. Что-то вроде предупреждения, это функция, которую вы можете переопределить чем-то другим. Alert также не является ключевым словом, а является частью стандартного набора функций, ap частью оконного объекта, имеющего глобальную область видимости. Как и undefined, вы также можете переопределить функцию предупреждения, переназначив ее. Например: window.alert = function (s) {console.info (s); } также является законной конструкцией.
Я нахожу приведенное здесь первое оправдание отказа от использования === undefined в недоумение. Да, вы можете назначить undefined, но для этого нет законной причины, и вполне предсказуемо, что это может привести к поломке вашего кода. В C вы можете #define true false, а в Python вы можете назначить True и False, но люди не чувствуют необходимости разрабатывать свой код на этих языках таким образом, чтобы защитить себя от возможности преднамеренного саботажа своей собственной среды в другом месте. в коде. Почему здесь вообще стоит задуматься о возможности присвоения undefined?
Насчет if (typeof myVar != "undefined"). Подходит ли "! = "?
в дополнение к комментариям Marks я не понимаю этого: «myVar === undefined вызовет ошибку в ситуации, когда myVar не объявлен». - почему это плохо? Зачем мне нет хотеть получить ошибку, если я ссылаюсь на необъявленные переменные?
@Kevin Да, так и будет, потому что typeof всегда будет возвращать строку, что делает ненужным сравнение с типобезопасностью. Просто считается хорошей практикой использовать === соответственно. Только !==. На самом деле я думаю, что jQuery использует только !=.
Также имейте в виду, что вы всегда можете выполнить void 0, чтобы получить значение, на которое указывает undefined. Так можно сделать if (myVar === void 0). 0 не является чем-то особенным, вы можете выразить там буквально любое выражение.
В современных браузерах (FF4 +, IE9 +, Chrome unknown) больше невозможно изменить undefined. MDN: не определено
@Stijn: Хотя изменить глобальный undefined невозможно, все же возможно переопределить его локально, как показано в этом ответе. Скопируйте и вставьте образец кода ответа в современный браузер, и вы увидите, что myVar === undefined все еще может вызывать проблемы.
@KevinMeredith "! =" Приемлемо? " Это определенно. В моей книге это лучше, чем !==, поскольку он короче, а более длинные формы не дают преимуществ i.c.w. typeof.
Этот ответ тоже неверен. Вопрос касался неопределенных свойств объекта, а не неопределенных переменных. Есть существенная разница. Совершенно разумно, например, сделать if (obj.field === undefined). Я думаю, что риск того, что кто-то сделает var undefined = false;, переоценен. Вам придется программировать неоправданно оборонительную программу, если вы хотите защитить себя от всех подобных побочных эффектов, вызванных плохим программированием.
Правило X: НИКОГДА не используйте зарезервированные слова в качестве имени переменной, функции или чего-либо еще. Не понимаю, что у вас так много положительных голосов. Поскольку это возможно, это не означает, что это законно, кроме того, это может измениться в будущем, и ваш код (и все, что от него зависит) больше не работает. Это плохой / ненадежный пример, и он показывает, как этого не делать.
поскольку для свойства записи undefined установлено значение false. даже если вы назначите false для undefined, оно не будет установлено. поэтому undefined будет "undefined", всегда не ложным, поэтому ваш ответ не имеет смысла. Вы можете проверить это в спецификации сценария ECMA для JavaScript. ecma-international.org/ecma-262/5.1/#sec-15.1.1.3
Просто исходя из опыта, я думаю, вы, В самом деле, хотите, чтобы ваш код выдавал эту ошибку ReferenceError, если переменная не объявлена. Это так неприятно, когда что-то молча терпит неудачу.
@MarkPflug: К сожалению, в 2010 году это тоже не имело смысла. undefined не является ключевым словом в 2017 году. Вы все еще можете использовать var undefined = false;. Ответом на этот вопрос всегда было «не делай этого», а не «используйте запутанные обходные пути для чего-то, чего никогда не бывает».
Забавно, что люди предлагают эти глупые и подверженные ошибкам взломы, чтобы избежать затенения undefined (что может сделать только ужасный разработчик), но они беспечно используют другие глобальные идентификаторы, которые также могли быть затенены. Странно. Просто странно.
^ полностью согласен. кто-то, кто может затенять undefined, может также затенять Math или назначать Function.prototype.apply или что-либо, что вы считаете само собой разумеющимся! Пожалуйста. ^ полностью согласен. кто-то, кто может затенять undefined, может также затенять Math или назначать Function.prototype.apply или что-либо, что вы считаете само собой разумеющимся! Пожалуйста. Как насчет Object.prototype.toJSON=()=>({rick:'rolled'})? Тогда JSON.stringify({hello:'world'}) === '{"rick":"rolled"}'. Существует так много способов нарушить ожидаемую среду JavaScript, что вы не можете написать код, который работает со всеми этими вещами.
Но это больше не актуально с ECMAScript 5 (и более поздними версиями)?
Я не уверен, откуда взялось использование === с 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: как раз наоборот - можно было ожидать небольшого снижения производительности из-за избежания принуждения в случае '==='. Быстрый и грязный тест показал, что '===' на 5% быстрее, чем '==' в FF5.0.1.
Более тщательный тест показал, что в FF, IE и Chrome '==' более или менее быстрее, чем '===' (5-10%), а Opera вообще не имеет никакого значения: jsperf.com/triple-equals-vs-twice-equals/6
Использование == по-прежнему требует по меньшей мере проверки типа - интерпретатор не может сравнить два операнда, не зная сначала их тип.
== на один символ меньше, чем === :)
@svidgen Вы добавляете смайлик, но, видя, что сеть представляет собой цепочку самый медленный в ссылке, я действительно считаю, что вы увидите больший прирост производительности, если пропустите лишний символ, чем вы когда-либо увидите при проверке типа. 5% ничего - это еще ничто. Лично я ненавижу догматическое кодирование. Я разрешаю вам выключать мозг во время набора текста, но есть причина, по которой тройное равенство в этом случае будет безопаснее, по нет.
Проблема сводится к трем случаям:
undefined.undefined.Это говорит нам о том, что я считаю важным:
Существует разница между неопределенным членом и определенным членом с неопределенным значением.
Но, к сожалению, 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'. Надеюсь, это кому-то поможет.
Извините, Майкл, но это неверно или, по крайней мере, вводит в заблуждение в свете исходного вопроса. 'in' не является достаточным способом проверить, имеет ли свойство объекта typeof undefined. Для доказательства см. Эту скрипку: jsfiddle.net/CsLKJ/4
Эти две части кода делают разные вещи! Учтите и возразите, данное a = {b: undefined}; затем typeof a.b === typeof a.c === 'undefined', но 'b' in a и !('c' in a).
+1. OP не дает понять, существует ли свойство и имеет ли оно значение неопределенный, или само свойство не определено (т.е. не существует).
Я бы предложил изменить точку (2.) в вашей первой таблице на { x : undefined } или, по крайней мере, добавить ее в качестве другой альтернативы (2.) в таблице - мне пришлось на мгновение подумать, чтобы понять, что точка (2.) оценивается как undefined. (хотя вы упомянули об этом позже).
@mucaho Это было бы лучше, но я думаю, что есть (или, по крайней мере, были?) некоторые проблемы с такой конструкцией - то есть undefined не является (не было?) гарантированно неопределенным.
Если вы это сделаете
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.
Object.hasOwnProperty(o, 'propertyname');
Однако это не просматривается в цепочке прототипов.
Object.hasOwnProperty не будет работать должным образом; он проверяет, есть ли у объекта Object свойство с именем, содержащимся в o. Вы наверное имеете в виду Object.prototype.hasOwnProperty.call(o, 'propertyname').
Я не видел (надеюсь, что не пропустил), чтобы кто-то проверял объект перед свойством. Итак, это самый короткий и самый эффективный (хотя и не обязательно самый понятный):
if (obj && obj.prop) {
// Do something;
}
Если obj или obj.prop имеет значение undefined, null или "ложный", оператор if не выполнит блок кода. Это обычно - желаемое поведение в большинстве операторов блока кода (в JavaScript).
Если вы хотите знать, почему это работает: Javascript: логические операторы и правдивость / ложность
если вы хотите присвоить свойство переменной, если она определена, а не null и не falsey, иначе используйте какое-то значение по умолчанию, вы можете использовать: var x = obj && obj.prop || 'default';
Я считаю, что вопрос заключается в явной проверке на undefined. Ваше условие проверяет все ложные значения JS.
Кросс-постинг мой ответ из связанного вопроса Как я могу проверить наличие "неопределенного" в 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:
undefined.Минусы obj.prop === undefined:
undefined можно переопределить в старых браузерахПлюсы typeof obj.prop == 'undefined':
Минусы typeof obj.prop == 'undefined':
'undefned' (неправильно написан) - это просто строковая константа, поэтому движок 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 показывает обратное.
Дополнительная документация не нужна, так как это в спецификации EcmaScript, который также говорит, что [[Enumerable]] является ложным :-)
Что касается Minuses of typeof obj.prop == 'undefined', этого можно избежать, написав как typeof obj.prop == typeof undefined. Это также дает очень красивую симметрию.
@hlovdal: Это совершенно бессмысленно по сравнению с obj.prop === undefined.
Когда мы верны заголовку вопроса «Обнаружение - неопределенное свойство», а не (другому и гораздо более простому) вопросу в первом предложении («проверьте, не определено ли…»), вы отвечаете if ('foo' in o)… ваш ответ действительно является первым правильным ответом здесь . Практически все остальные просто отвечают на это предложение.
Вот моя ситуация:
Я использую результат вызова REST. Результат должен быть преобразован из JSON в объект JavaScript.
Есть одна ошибка, которую я должен защищать. Если аргументы для вызова REST были неправильными, поскольку пользователь указал аргументы неправильно, вызов REST возвращается в основном пустым.
Используя этот пост, чтобы помочь мне защититься от этого, я попробовал следующее:
if ( typeof restResult.data[0] === "undefined" ) { throw "Some error"; }
В моей ситуации, если restResult.data [0] === "объект", я могу безопасно начать проверку остальных членов. Если не определено, то выдайте ошибку, как указано выше.
Я говорю, что для моей ситуации все предыдущие предложения в этом посте не сработали. Я не говорю, что я прав, а все ошибаются. Я совсем не мастер JavaScript, но надеюсь, это кому-то поможет.
Ваша защита typeof на самом деле не защищает от всего, с чем не может справиться прямое сравнение. Если restResult не определен или не объявлен, он все равно выдаст.
В вашем случае вы могли бы проще проверить, пуст ли массив: if (!restResult.data.length) { throw "Some error"; }
В статье Изучение бездны пустого и неопределенного в JavaScript я читал, что такие фреймворки, как Underscore.js, используют эту функцию:
function isUndefined(obj){
return obj === void 0;
}
void 0 - это всего лишь краткий способ записи undefined (так как это то, что пустота, за которым следует любое выражение), сохраняет 3 символа. Он также мог использовать var a; return obj === a;, но это еще один символ. :-)
void - это зарезервированное слово, тогда как undefined - нет, т.е. хотя undefined по умолчанию равен void 0, вы можете присвоить значение undefined, например. undefined = 1234.
isUndefined(obj): 16 символов. obj === void 0: 14 символов. Ничего не сказано.
Сравните с void 0, для краткости.
if (foo !== void 0)
Это не так многословно, как if (typeof foo !== 'undefined')
Но это вызовет ошибку ReferenceError, если foo не объявлен.
@ daniel1426: Значит, если в вашем коде есть ошибка, вы хотите ее скрыть, а не исправлять? Не лучший подход, ИМО.
Это не используется для сокрытия ошибок. Это обычный способ определения свойств среды для определения полифилов. Например: if (typeof Promise === 'undefined') {/ * define Promise * /}
Скорее всего вам нужен if (window.x). Эта проверка безопасна, даже если x не был объявлен (var x;) - браузер не выдает ошибку.
if (window.history) {
history.call_some_function();
}
окно - это объект, который содержит все глобальные переменные в качестве своих членов, и допустимо пытаться получить доступ к несуществующему члену. Если Икс не был объявлен или не был установлен, window.x возвращает неопределенный. неопределенный приводит к ложный, когда если() оценивает его.
Но что, если вы запустите Node? typeof history != 'undefined' действительно работает в обеих системах.
Несмотря на то, что многие другие ответы здесь настоятельно рекомендуют 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 Это параноик и не имеет отношения ни к чему практическому. Каждый контекст может переопределить console.info, переопределить методы прототипа Array и даже переопределить перехват и изменение Function.prototype.call` каждый раз, когда вы вызываете функцию в JavaScript. Защищаться от этого очень параноидально и довольно глупо. Как я (и minitech) сказал, вы можете использовать void 0 для сравнения с undefined, но опять же - это глупо и излишне.
Мне жаль, что у меня не было более одного голоса за. Это самый правильный ответ. Я действительно хочу перестать видеть typeof something === "undefined") в коде.
@BenjaminGruenbaum Для ленивых программистов void 0 (на этот раз) и короче, и безопаснее и! В моей книге это победа.
Это действительно должен быть принятый ответ. Он самый тщательный и актуальный.
Любой контекст, отличный от контекста по умолчанию, также может перезаписать, скажем, Math, или Object, или setTimeout, или буквально все, что вы ожидаете найти в глобальной области по умолчанию.
ohw kay foo! == void 0 работает и короче, думаю, я могу использовать это: 3, и я знал, что вы имеете в виду свой собственный ответ, когда вы прокомментировали это>: D
теперь он не документирует то, что он делает, и может сбивать с толку, поэтому вместо этого я сделаю функцию isDefined return true, если не void 0, и false, если это так, и вместо этого верну>: 3
@Fuseteam: используйте !== undefined. Собственно, совет по void 0, наверное, стоит убрать.
@Fuseteam: он не такой читабельный и не имеет практических преимуществ перед undefined.
Я работал над удобочитаемостью, заключив ее в функцию isDefined (переменная), поэтому теперь я могу просто вызвать эту функцию, чтобы сделать это, как if (isDefined(variable))//do something xD, так что она короче и многоразовая, я думаю
@Fuseteam: Опять же, я настоятельно рекомендую не делать этого, а вместо этого написать if (variable !== undefined). Сравнение с undefined однозначно и знакомо, избыточные функции оболочки создают неопределенность («может быть, это также проверяет null?») Без улучшения читаемости.
я действительно изучал, какие еще типы "неопределенных" значений возможны, но достаточно справедливы
"propertyName" in obj //-> true | false
Также то же самое можно написать короче:
if (!variable){
// Do it if the variable is undefined
}
или же
if (variable){
// Do it if the variable is defined
}
Ваш первый случай может быть инициирован определенной переменной. Например, если переменная = 0, сработает! Переменная. Так что ваш ответ совершенно неверен.
Я думаю, это просто неправильная формулировка, я думаю, он имел в виду «сделай это, если переменная не определена или другое ложное значение», что часто является логикой, которую люди ищут.
@Ynot - !variable будет истинным, если variable не определен, или определено и оказывается равным 0, ложный, так далее. Я не понимаю, как это может быть ответом на вопрос OP или хоть чем-то полезным.
Я не поддержал это, потому что не думал, что это лучший ответ. Я думал, что Stranded Kid поднял хороший вопрос, но он неправильно охарактеризовал решение. Тот факт, что вы можете представить себе вариант использования, в котором что-то не так, не означает, что не существует варианта использования, в котором это правильно. Это напрямую связано с вопросом OP в том смысле, что, если вы понимаете последствия, это можно использовать без проблем, чтобы проверить, не определено ли свойство (|| false). например проверка флага if (myobject.isFeatureEnabled) {
Все ответы неполные. Это правильный способ узнать, что существует свойство, «определенное как 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.
Я хотел бы показать вам кое-что, что я использую для защиты переменной 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)
Читая это, я удивлен, что не заметил этого. Я нашел несколько алгоритмов, которые сработают для этого.
Если значение объекта никогда не было определено, это предотвратит возврат 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)
@StijndeWitt, вы можете, я был довольно неопытен, когда писал это, и мой английский, похоже, был так же плох, тем не менее, в ответе нет ничего неверный
var obj = {foo: undefined}; obj.foo === void 0 -> true. Как это "никогда не определялось как undefined"? Это не правильно.
@PatrickRoberts Ты прав. Когда я писал этот ответ в феврале 2015 года (до ES6), первый вариант, который я описал, действительно работал, но теперь он устарел.
Я использую 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" }
lol, хорошо ... вы получите именно тот ложный результат, который, как вы утверждаете, предотвращает ваш код. jsfiddle.net/pfwx5j51
... кроме того, с вашим кодом == и === будут вести себя одинаково, потому что вы всегда сравниваете совпадающие типы. Так что это различие несущественно.
@rockstar Точно, - вам не нужен статический оператор сравнения для аргументов одного и того же типа. Это было бы перебором. Более того, если значение свойства является строкой undefined или типом undefined, ничего не меняет. Потому что они оба имеют одинаковое значение и равную доходность. Вы можете сэкономить несколько битов, назначив "undefined" в качестве значения свойства. Это излишество, потому что вы сможете получить строку undefined, не назначая ее. Я согласен - технически вы можете считать это «ложным срабатыванием», но практически и эмпирически это не так. Спасибо, в любом случае.
С аргументами одного типа === и == выполняют одинаковую работу. Когда типы не соответствуют ==, работает более, поэтому называть === "overkill" не имеет большого смысла, поскольку он всегда обеспечивает равный или более простой алгоритм.
undefined и "undefined" имеют одинаковое значение только в вашем тесте, что и делает его ложноположительным, поскольку цель вашего теста - найти именно такое различие. Так что это явный провал и в любом случае будет излишне сложным, поскольку ("prop" in obj) && obj.prop === undefined проще и на самом деле правильный. Ага, пожалуйста.
@rockstar у вас ложноположительный случай никогда не бывает. И когда это так - это преднамеренно и, следовательно, равноправно, но если вы чувствуете в этом сильное чувство, не стесняйтесь редактировать мой ответ.
Я не уверен, что вы имеете в виду, когда говорите, что это сделано преднамеренно и, следовательно, равноправно. Строковое значение "undefined" может иметь множество разных причин, поэтому, если нет очень необычной ситуации, строка "undefined" должна быть так же отлична от значения undefined, как и строка "foobar".
В том-то и дело, что я не вижу никакой другой причины присвоения неопределенного значения в виде строки, кроме использования этого значения как слова, означающего undefined в некотором читаемом тексте, и, следовательно, это излишество, потому что на самом деле нет необходимости писать это, чтобы иметь возможность получить его. p.s === является излишним в JS при работе с аргументами одного типа, потому что JS является динамическим по рождению, а не по расширению. К нему нужно принуждать строгость. В любом случае, прошу вас исправить мою ошибку. Таким образом, он получит вашу подпись.
Довольно распространено заблуждение, что === должен выполнять больше работы из-за динамической природы JS, но на самом деле он должен делать меньше, потому что, когда типы не совпадают, он может немедленно вернуть false вместо того, чтобы входить в алгоритм рекурсивного принуждения. Это принудительное приведение типов, что и делает ==, когда типы не совпадают. Когда они совпадают, == и ===использовать идентичные алгоритмы.
... Что касается undefined, то, вероятно, довольно редко иметь это как явное значение в любом случае, но если кто-то проверяет его, то они, вероятно, используют его по какой-то причине (хотя null, возможно, лучше). В таком случае, я думаю, они захотят добиться различия. Во всяком случае, просто указание на то, что в таких случаях это может противоречить намерению.
Никогда не используйте null для того, чем он не является.
О, не волнуйтесь, я не буду. Вот почему я говорю, что, возможно, лучше, чем undefined, представлять свойство определенный, которое не имеет полезного значения.
Просто что-либо не определено в 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.
Удивлен, что больше голосов и комментариев не набралось. Что люди думают по этому поводу?
Я предлагаю здесь три способа для тех, кто ожидает странных ответов:
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);Попробуйте получить свойство входного значения и проверьте сообщение об ошибке, если оно существует. Если входное значение не определено, сообщение об ошибке будет Uncaught TypeError: невозможно прочитать свойство 'b' неопределенного значения.
Преобразуйте входное значение в строку для сравнения с "undefined" и убедитесь, что это отрицательное значение.
В 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.
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
Я нашел эту статью, 7 советов по работе с undefined в JavaScript, которая показывает действительно интересные вещи о undefined.
подобно:
Существование undefined является следствием разрешающей природы JavaScript, которая позволяет использовать:
Да, но как он отвечает на вопрос?
В JavaScript есть выражения правдивый и фальшивка. Если вы хотите проверить, является ли свойство неопределенным или нет, есть прямой способ использовать данное условие если,
if (!ob.someProp){
console.info('someProp is falsy')
}
Однако есть еще несколько подходов к проверке наличия у объекта свойства, но мне это кажется долгим. Вот те.
=== undefined в условии ifif (ob.someProp === undefined){
console.info('someProp is undefined')
}
typeoftypeof действует как комбинированная проверка на неопределенное значение и на наличие переменной.
if (typeof ob.someProp === 'undefined'){
console.info('someProp is undefined')
}
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
ifcondition will return false. For such a case, you can use thehasOwnPropertymethod
... вы также проверяете примеры кода, которые публикуете? ... например ... if (typeof ob.someProp === undefined) { ...
... вы также не можете небрежно "исправить / исправить" предоставленные вами примеры, которые отвечают, как проверить наличие неопределенного свойства, восклицая после этого Предупреждение ... на самом деле if (!ob.someProp) { console.info('someProp is undefined'); } с самого начала должен быть реализован как if (!ob.someProp) { console.info('someProp is falsy'); }
@PeterSeliger Спасибо, что заметили это.
Я также указывал на ваш пример № 3 / typeof ... он все еще реализован неправильно ... он должен быть ... if (typeof ob.someProp === 'undefined') { ... ваш код сравнивается не со строковым значением, а с неопределенным значением. Вот почему вопрос о том, действительно ли вы тестируете перед публикацией.
@PeterSeliger Еще раз спасибо, что заметили, ну, я написал это прямо в пост, поэтому он подвержен ошибкам. Я бы поиграл перед публикацией. Исправление сделано
Есть очень простой и легкий способ.
Вы можете использовать необязательная цепочка:
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
Это именно то, что я искал. Спасибо!
Многие из приведенных ответов дают неправильный результат, потому что они не различают случай, когда свойство объекта не существует, и случай, когда свойство имеет значение 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();
Во-первых, когда somevariable равно undefined, это не означает, что переменная не определена - это просто значение, которое не определено. Если переменная не определена, этот код выдаст ошибку. Во-вторых, эта функция isset будет работать только для глобальных переменных.