Как лучше всего проверить, есть ли свойство объекта в JavaScript undefined
?
Как лучше всего проверить, есть ли свойство объекта в JavaScript undefined
?
Ответы:
Обычный способ проверить, является ли значение свойства особым значением 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`");
}
obj !== undefined
сейчас. undefined
имел обыкновение быть изменчивым, как undefined = 1234
то, что вызвало бы интересные результаты. Но после Ecmascript 5 он больше не доступен для записи, поэтому мы можем использовать более простую версию. codereadability.com/how-to-check-for-undefined-in-javascript
Я считаю, что есть ряд неправильных ответов на эту тему. Вопреки распространенному мнению, «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 не объявлен.
=== undefined
изумление. Да, вы можете назначить undefined
, но для этого нет законных оснований, и вполне предсказуемо, что это может нарушить ваш код. В C вы можете #define true false
, а в Python вы можете назначить True
и False
, но люди не чувствуют необходимости разрабатывать свой код на этих языках таким образом, чтобы защитить себя от возможности умышленного саботажа своей собственной среды в другом месте кода. , Почему возможность присвоения undefined
даже стоит рассмотреть здесь?
void 0
чтобы получить значение, на которое undefined
указывает. Так что вы можете сделать if (myVar === void 0)
. 0
не является специальным, вы можете буквально поместить любое выражение там.
undefined
. MDN: не определено
Несмотря на то, что здесь яростно рекомендуют многие другие ответы, 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
не является ключевым словом в JavaScript. Это свойство глобального объекта с неопределенным значением. Однако, начиная с ES5, это свойство доступно только для чтения и не настраивается . Ни один современный браузер не позволит undefined
изменить свойство, и с 2017 года это имело место в течение длительного времени. Отсутствие строгого режима также не влияет undefined
на поведение - он просто делает заявления типа undefined = 5
ничего не делать вместо броска. Поскольку это не ключевое слово, вы можете объявлять переменные с именем undefined
, и эти переменные можно изменить, создав такой некогда общий шаблон:
(function (undefined) {
// …
})()
более опасно, чем использование глобального undefined
. Если вам нужно быть совместимым undefined
с ES3, замените на void 0
- не прибегайте к typeof
. ( void
всегда был унарным оператором, который оценивается как неопределенное значение для любого операнда.)
С тем, как переменные работают вне пути, пришло время обратиться к фактическому вопросу: свойствам объекта. Нет никаких причин когда-либо использовать typeof
для свойств объекта. Более раннее исключение, касающееся обнаружения признаков, здесь не применимо - typeof
имеет специальное поведение только для переменных, а выражения, которые ссылаются на свойства объекта, не являются переменными.
Эта:
if (typeof foo.bar === 'undefined') {
⋮
}
это всегда точно эквивалент в this³:
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
свойству глобального объекта. подставь void 0
иначе.
undefined
, скрывая контекст по умолчанию. Что для большинства практических целей имеет тот же эффект, что и перезапись.
void 0
для сравнения с неопределенным, но опять же - это глупо и излишне.
typeof something === "undefined")
в коде.
void 0
(на этот раз) и короче, и безопаснее! Это победа в моей книге.
В JavaScript есть ноль и есть неопределенный . У них разные значения.
Марин Хавербеке в своей бесплатной онлайн-книге « Красноречивый JavaScript » (выделено мной) утверждает :
Существует также аналогичное значение, нулевое, значение которого «это значение определено, но оно не имеет значения». Разница в значении между неопределенным и нулевым является в основном академической и обычно не очень интересной. В практических программах часто необходимо проверить, имеет ли что-то значение. В этих случаях может быть использовано выражение что-то == undefined, поскольку, даже если они не совпадают по значению, null == undefined приведет к значению true.
Итак, я думаю, что лучший способ проверить, было ли что-то неопределенным, было бы:
if (something == undefined)
Надеюсь это поможет!
Редактировать: в ответ на ваше редактирование свойства объекта должны работать так же.
var person = {
name: "John",
age: 28,
sex: "male"
};
alert(person.name); // "John"
alert(person.fakeVariable); // undefined
undefined
это просто переменная, которая может быть переназначена пользователем: запись undefined = 'a';
приведет к тому, что ваш код перестанет делать то, что вы думаете. Использование typeof
лучше, а также работает с переменными (не только свойствами), которые не были объявлены.
Что это значит: «неопределенное свойство объекта» ?
На самом деле это может означать две совершенно разные вещи! Во-первых, это может означать свойство, которое никогда не было определено в объекте, и, во-вторых, это может означать свойство, которое имеет неопределенное значение . Давайте посмотрим на этот код:
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
против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.
undefined
что она является членом global
. Также ни, console.log(global);
ни for (var key in global) { ... }
не показывает undefined в качестве члена глобальной . Но проверить, как 'undefined' in global
показать обратное.
[[Enumerable]]
это ложь :-)
Minuses of typeof obj.prop == 'undefined'
этого можно избежать, написав как typeof obj.prop == typeof undefined
. Это также дает очень хорошую симметрию.
obj.prop === undefined
.
if ('foo' in o
)… ваш ответ действительно первый правильный ответ здесь. Практически все остальные просто отвечают на это предложение.
Проблема сводится к трем случаям:
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); }
Что было понятнее, когда написано без проверки неопределенности.
if( "x" in blob ) { fn(blob.x); }
Но, как уже упоминалось, это не совсем то же самое (но более чем достаточно для моих нужд).
if (!("x" in blob)) {}
с скобками во всем, потому что! Оператор имеет приоритет над «в». Надеюсь, что это помогает кому-то.
a = {b: undefined}
; тогда typeof a.b === typeof a.c === 'undefined'
но 'b' in a
и !('c' in a)
.
{ x : undefined }
или, по крайней мере, добавить ее в качестве другой альтернативы (2.) в таблице - мне пришлось немного подумать, чтобы понять, что точка (2.) оценивает undefined
(хотя Вы упоминаете об этом позже).
if ( typeof( something ) == "undefined")
Это сработало для меня, а другие нет.
typeof (something == "undefined")
.
(typeof something) === "undefined"
.
Я не уверен, откуда исходит происхождение использования ===
with 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
==
прежнему требуется как минимум проверка типа - интерпретатор не может сравнить два операнда, не зная сначала их тип.
==
на один персонаж меньше, чем ===
:)
Перекрестный ответ на мой ответ по связанному вопросу Как проверить наличие «неопределенного» в 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
Если вы делаете
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');
}
Когда первое и простое условие выполняется, интерпретатор пропускает следующие тесты.
Всегда лучше использовать экземпляр / объект переменной, чтобы проверить, получило ли оно допустимое значение. Это более стабильный и лучший способ программирования.
(У)
Я не видел (надеюсь, что не пропустил) никого, кто проверял объект перед собственностью. Итак, это самый короткий и самый эффективный (хотя и не обязательно самый понятный):
if (obj && obj.prop) {
// Do something;
}
Если obj или obj.prop не определены, имеют значение null или «ложь», оператор if не выполнит блок кода. Это обычно желаемое поведение в большинстве операторов блока кода (в JavaScript).
var x = obj && obj.prop || 'default';
В статье « Изучение бездны нуля и неопределенности в JavaScript» я прочитал, что фреймворки, такие как Underscore.js, используют эту функцию:
function isUndefined(obj){
return obj === void 0;
}
void 0
это всего лишь краткий способ записи undefined
(так как void, за которым следует любое выражение, возвращается), он сохраняет 3 символа. Это тоже можно сделать var a; return obj === a;
, но это еще один персонаж. :-)
void
является зарезервированным словом, в то время как undefined
это не то , а undefined
равно void 0
по умолчанию, вы можете присвоить значение , undefined
например undefined = 1234
.
isUndefined(obj)
: 16 символов obj === void 0
: 14 символов - сказал он.
Просто что-то не определено в JavaScript, не определено , не имеет значения, является ли оно свойством внутри Object / Array или просто как переменная ...
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
в своем коде, но если вы используете это снова и снова, создайте функцию, подобную угловому образцу, которую я разделяю, и продолжаю использовать ее как следующий шаблон кода СУХОЙ.
Также еще одна вещь, для проверки свойства объекта в реальном приложении, в котором вы не уверены, существует ли этот объект или нет, сначала проверьте, существует ли объект.
Если вы проверите свойство объекта, а объект не существует, вы получите ошибку и остановите работу всего приложения.
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).
Строгое равенство и неопределенность
Вы можете использовать неопределенные операторы и операторы строгого равенства и неравенства, чтобы определить, имеет ли переменная значение. В следующем коде переменная x не определена, а оператор if оценивается как true.
var x;
if (x === undefined) {
// these statements execute
}
else {
// these statements do not execute
}
Примечание: здесь должен использоваться оператор строгого равенства, а не стандартный оператор равенства, потому что x == undefined также проверяет, является ли x нулевым, а строгое равенство - нет. ноль не эквивалентно неопределенному. Смотрите операторы сравнения для деталей.
Оператор Typeof и неопределенный В
качестве альтернативы можно использовать 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`)
}
больше> здесь
Скорее всего, вы хотите if (window.x)
. Эта проверка безопасна, даже если x не был объявлен ( var x;
) - браузер не выдает ошибку.
if (window.history) {
history.call_some_function();
}
window - это объект, который содержит все глобальные переменные в качестве своих членов, и разрешено пытаться получить доступ к несуществующему члену. Если x не был объявлен или не был установлен, то window.x
возвращает undefined . undefined приводит к ложному, когда if () оценивает его.
typeof history != 'undefined'
на самом деле работает в обеих системах.
Прочитав это, я поражен, что не видел этого. Я нашел несколько алгоритмов, которые будут работать для этого.
Если значение объекта никогда не определялось, это предотвратит возврат, 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");
}
if (!obj.prop)
var obj = {foo: undefined}; obj.foo === void 0
-> true
. Как это "никогда не определяется как undefined
"? Это не верно.
Сравните с void 0
, для краткости.
if (foo !== void 0)
Это не так многословно, как if (typeof foo !== 'undefined')
foo
не объявлен.
Решение неверное. В JavaScript
null == undefined
вернет true, потому что они оба «приведены» к логическому значению и являются ложными. Правильный способ будет проверить
if (something === undefined)
который является оператором идентичности ...
===
это тип равенства + (примитивное равенство | идентичность объекта), где примитивы включают строки. Я думаю, что большинство людей считают 'abab'.slice(0,2) === 'abab'.slice(2)
неинтуитивным, если считать ===
оператором идентичности.
Вы можете получить массив с неопределенным путем, используя следующий код.
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
.
Вот моя ситуация:
Я использую результат вызова 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"; }
Существует хороший и элегантный способ назначить определенное свойство новой переменной, если оно определено, или назначить ему значение по умолчанию в качестве запасного, если оно не определено.
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
Все ответы неполные. Это правильный способ узнать, что существует свойство, определенное как неопределенное:
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
Жаль, что это был правильный ответ, похоронен в неправильных ответах> _ <
Так что, для тех, кто проходит мимо, я дам вам неопределенные бесплатно !!
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
Проходя по комментариям, для тех, кто хочет проверить, является ли он неопределенным или его значение равно нулю:
//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;
Если вы используете Angular:
angular.isUndefined(obj)
angular.isUndefined(obj.prop)
Underscore.js:
_.isUndefined(obj)
_.isUndefined(obj.prop)
1
в переменную x
? Нужно ли Underscore или JQuery? (Удивительно, что люди будут использовать библиотеки даже для самых элементарных операций, таких как typeof
проверка)
Я использую, 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
не определена, и определяется после инициализации.
Я предлагаю три способа для тех, кто ожидает странных ответов:
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);
Попробуйте получить свойство входного значения, проверьте сообщение об ошибке, если оно существует. Если входное значение не определено, сообщение об ошибке будет Uncaught TypeError: Невозможно прочитать свойство 'b' из неопределенного
Преобразуйте входное значение в строку для сравнения "undefined"
и убедитесь, что это отрицательное значение.
В js необязательный параметр работает, когда входное значение точно undefined
.
В ES2019 появилась новая функция - необязательная цепочка, которую вы можете использовать для использования свойства объекта, только когда объект определен следующим образом:
const userPhone = user?.contactDetails?.phone;
Он будет ссылаться на свойство телефона только тогда, когда определены user и contactDetails.
Ссылка https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
function isUnset(inp) {
return (typeof inp === 'undefined')
}
Возвращает false, если переменная установлена, и true, если не определено.
Тогда используйте:
if (isUnset(var)) {
// initialize variable here
}
typeof
тест в функцию. Удивительно, что 4 человека проголосовали за это. -1.
Я хотел бы показать вам кое-что, что я использую для защиты undefined
переменной:
Object.defineProperty(window, 'undefined', {});
Это запрещает кому-либо изменять window.undefined
значение, поэтому уничтожает код на основе этой переменной. При использовании "use strict"
все попытки изменить его значение будут заканчиваться ошибкой, в противном случае это будет игнорироваться.
Вы также можете использовать Proxy, он будет работать с вложенными вызовами, но потребует одну дополнительную проверку:
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 someting
}