检查 JavaScript 中的对象属性是否未定义的最佳方法是什么?
50 回答
检查属性值是否为特殊值的常用方法undefined
是:
if(o.myProperty === undefined) {
alert("myProperty value is the special value `undefined`");
}
要检查一个对象是否实际上没有这样的属性,因此undefined
当您尝试访问它时会默认返回:
if(!o.hasOwnProperty('myProperty')) {
alert("myProperty does not exist");
}
要检查与标识符关联的值是否是特殊值undefined
,或者该标识符是否尚未声明:
if(typeof myVariable === 'undefined') {
alert('myVariable is either the special value `undefined`, or it has not been declared');
}
注意:这最后一种方法是引用未声明标识符而没有早期错误的唯一方法,这与具有值不同undefined
。
在 ECMAScript 5 之前的 JavaScript 版本中,全局对象上名为“undefined”的属性是可写的,因此foo === undefined
如果不小心重新定义了一个简单的检查,它可能会出现意外行为。在现代 JavaScript 中,该属性是只读的。
但是,在现代 JavaScript 中,“未定义”不是关键字,因此函数内部的变量可以命名为“未定义”并隐藏全局属性。
如果您担心这种(不太可能的)边缘情况,您可以使用void 运算符来获取特殊undefined
值本身:
if(myVariable === void 0) {
alert("myVariable is the special value `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 未声明的情况下会引发错误。
尽管这里有许多其他答案强烈推荐,但这typeof
是一个糟糕的选择。它永远不应该用于检查变量是否具有 value undefined
,因为它作为 valueundefined
和变量是否存在的组合检查。在绝大多数情况下,您知道变量何时存在,并且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') {
⋮
}
总是完全等价于 this³:
if (foo.bar === undefined) {
⋮
}
并考虑到上面的建议,以避免让读者混淆你为什么使用,因为使用它来检查相等性typeof
是最有意义的,因为它可以被重构为稍后检查变量的值,并且因为它只是简单===
看起来更好,您也应该始终=== undefined
在此处使用 ³。
当涉及到对象属性时要考虑的其他事情是您是否真的想要检查undefined
。给定的属性名称可以在对象上不存在(undefined
读取时产生值),以 value 出现在对象本身上,以 valueundefined
出现在对象的原型上undefined
,或者以非undefined
value 出现在任何一个对象上。'key' in obj
会告诉你一个键是否在对象的原型链上的任何地方,并且Object.prototype.hasOwnProperty.call(obj, 'key')
会告诉你它是否直接在对象上。不过,我不会在这个答案中详细介绍原型和使用对象作为字符串键映射,因为它主要是为了反驳其他答案中的所有坏建议,而不管原始问题的可能解释如何。继续阅读更多关于 MDN的对象原型!
¹ 示例变量名的不寻常选择?这是来自 Firefox 的 NoScript 扩展的真正死代码。
² 不要假设不知道范围内的内容通常是可以的。滥用动态范围造成的额外漏洞:零项目 1225
³ 再次假设 ES5+ 环境并且undefined
指undefined
的是全局对象的属性。
在 JavaScript 中有null和undefined。它们有不同的含义。
- undefined表示变量值没有被定义;不知道价值是什么。
- null表示已定义变量值并将其设置为 null(没有值)。
Marijn Haverbeke 在他的免费在线书籍“ Eloquent JavaScript ”(强调我的)中指出:
还有一个类似的值,null,意思是‘这个值被定义了,但是它没有值’。undefined 和 null 之间的含义差异主要是学术性的,通常不是很有趣。在实际程序中,经常需要检查某个东西是否“有价值”。在这些情况下,可以使用表达式 something == undefined,因为即使它们的值不完全相同, null == undefined 也会产生 true。
所以,我想检查某些东西是否未定义的最佳方法是:
if (something == undefined)
对象属性应该以相同的方式工作。
var person = {
name: "John",
age: 28,
sex: "male"
};
alert(person.name); // "John"
alert(person.fakeVariable); // undefined
这是什么意思:“未定义的对象属性”?
实际上它可能意味着两个完全不同的东西!首先,它可能表示从未在对象中定义的属性,其次,它可能表示具有未定义值的属性。让我们看一下这段代码:
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,则this
x.a === undefined
或 thistypeof x.a == 'undefined'
引发。ReferenceError: x is not defined
- 变量
undefined
是一个全局变量(实际上它window.undefined
在浏览器中)。它从 ECMAScript 1st Edition 开始就受到支持,并且从 ECMAScript 5 开始它是只读的。因此,在现代浏览器中,它不能被重新定义为真实的,因为许多作者喜欢用吓唬我们的方式来吓唬我们,但这对于旧浏览器来说仍然是真实的。
最后一战:obj.prop === undefined
vstypeof obj.prop == 'undefined'
优点obj.prop === undefined
:
- 它有点短,看起来有点漂亮
- 如果您拼写错误,JavaScript 引擎会给您一个错误
undefined
的缺点obj.prop === undefined
:
undefined
可以在旧浏览器中被覆盖
优点typeof obj.prop == 'undefined'
:
- 真的是万能的!它适用于新旧浏览器。
的缺点typeof obj.prop == 'undefined'
:
'undefned'
(拼写错误)这里只是一个字符串常量,所以如果您像我刚才那样拼错了它,JavaScript 引擎将无法帮助您。
更新(对于服务器端 JavaScript):
Node.js 支持全局变量undefined
as global.undefined
(它也可以在没有 'global' 前缀的情况下使用)。我不知道服务器端 JavaScript 的其他实现。
问题归结为三种情况:
- 该对象具有属性,其值不是
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 ( 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
我没有看到(希望我没有错过)任何人在财产之前检查对象。所以,这是最短和最有效的(虽然不一定是最清楚的):
if (obj && obj.prop) {
// Do something;
}
如果 obj 或 obj.prop 为 undefined、null 或“falsy”,则 if 语句将不会执行代码块。这通常是大多数代码块语句(在 JavaScript 中)中所需的行为。
更新:(2021 年 7 月 2 日)
最新版本的 JavaScript 为可选链引入了一个新的运算符:?.
这可能是检查对象属性是否存在的最明确和最有效的方法,向前推进。
参考:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
从相关问题交叉发布我的答案如何检查 JavaScript 中的“未定义”?.
具体到这个问题,请参阅测试用例someObject.<whatever>
。
说明各种答案结果的一些场景:http: //jsfiddle.net/drzaus/UVjM4/
(请注意,在作用域包装器中使用var
for测试会有所不同)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');
}
变量是否真的存在的问题并不重要,它的值是不正确的。否则用 undefined 初始化变量是愚蠢的,最好使用值 false 来初始化。当您知道您声明的所有变量都以 false 初始化时,您可以简单地检查它的类型或依靠它!window.myvar
来检查它是否具有正确/有效的值。因此,即使未定义变量, or or!window.myvar
也是相同的。myvar = undefined
myvar = false
myvar = 0
当您期望特定类型时,请测试变量的类型。为了加快测试条件,您最好执行以下操作:
if( !window.myvar || typeof window.myvar != 'string' )
{
alert('var does not exists or is not type of string');
}
当第一个简单条件为真时,解释器跳过下一个测试。
最好使用变量的实例/对象来检查它是否获得了有效值。它更稳定,是一种更好的编程方式。
(y)
在Exploring the Abyss of Null and Undefined in JavaScript一文中,我读到像Underscore.js这样的框架使用这个函数:
function isUndefined(obj){
return obj === void 0;
}
简单地说,任何东西都没有在 JavaScript 中定义,是undefined,不管它是对象/数组中的属性还是只是一个简单的变量......
JavaScripttypeof
使得检测未定义变量变得非常容易。
只需检查是否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
在您的代码中使用,但是如果您一遍又一遍地使用它,请创建一个像我共享的角度示例这样的函数并继续重用为遵循 DRY 代码模式。
还有一件事,要在实际应用程序中检查对象的属性,您甚至不确定该对象是否存在,请先检查该对象是否存在。
如果您检查对象的属性并且该对象不存在,则会抛出错误并停止整个应用程序的运行。
isUndefined(x.css);
VM808:2 Uncaught ReferenceError: x is not defined(…)
如此简单,您可以在 if 语句中包含如下内容:
if(typeof x !== 'undefined') {
//do something
}
这也等于 Angular 1.x 中的 isDefined ...
function isDefined(value) {return typeof value !== 'undefined';}
下划线等其他 javascript 框架也有类似的定义检查,但typeof
如果您还没有使用任何框架,我建议您使用。
我还添加了来自 MDN 的这一部分,其中包含有关 typeof、undefined 和 void(0) 的有用信息。
严格相等和未定义
您可以使用 undefined 以及严格相等和不等运算符来确定变量是否具有值。在以下代码中,未定义变量 x,并且 if 语句的计算结果为 true。
var x;
if (x === undefined) {
// these statements execute
}
else {
// these statements do not execute
}
注意:这里必须使用严格相等运算符而不是标准相等运算符,因为 x == undefined 也会检查 x 是否为空,而严格相等则不会。null 不等于未定义。有关详细信息,请参阅比较运算符。
typeof 运算符和 undefined
或者,可以使用 typeof:
var x;
if (typeof x === 'undefined') {
// these statements execute
}
使用 typeof 的一个原因是,如果尚未声明变量,它不会引发错误。
// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
// these statements execute
}
if (x === undefined) { // throws a ReferenceError
}
但是,应该避免这种技术。JavaScript 是一种静态范围的语言,因此可以通过查看变量是否在封闭上下文中声明来了解变量是否已声明。唯一的例外是全局作用域,但全局作用域绑定到全局对象,因此可以通过检查全局对象上是否存在属性来检查全局上下文中的变量是否存在(使用 in 运算符,例如)。
无效运算符和未定义
void 运算符是第三种选择。
var x;
if (x === void 0) {
// these statements execute
}
// y has not been declared before
if (y === void 0) {
// throws a ReferenceError (in contrast to `typeof`)
}
更多 >这里
' if (window.x) { } ' 是错误安全的
很可能你想要if (window.x)
。即使 x 尚未声明 ( var x;
),此检查也是安全的 - 浏览器不会抛出错误。
示例:我想知道我的浏览器是否支持 History API
if (window.history) {
history.call_some_function();
}
这是如何工作的:
window是一个将所有全局变量作为其成员的对象,尝试访问不存在的成员是合法的。如果x尚未声明或尚未设置,则window.x
返回undefined。当if()评估它时,未定义会导致错误。
读到这里,我很惊讶我没有看到这个。我发现了多种适用于此的算法。
从未定义
true
如果一个对象的值从未被定义,如果它被定义为null
or ,这将阻止返回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");
}
ECMAScript 10引入了一个新特性——可选链,只有当一个对象被这样定义时,你才能使用它来使用一个对象的属性:
const userPhone = user?.contactDetails?.phone;
只有在定义了 user 和 contactDetails 时,它才会引用 phone 属性。
参考。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
解决方案不正确。在 JavaScript 中,
null == undefined
将返回 true,因为它们都被“强制转换”为布尔值并且为 false。正确的方法是检查
if (something === undefined)
这是身份运算符...
"propertyName" in obj //-> true | false
您可以使用以下代码获取所有未定义路径的数组。
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链接
为了简洁起见,与void 0
, 进行比较。
if (foo !== void 0)
它没有那么冗长if (typeof foo !== 'undefined')
如果已定义新变量,则有一种很好且优雅的方法可以将已定义属性分配给新变量,如果未定义,则将默认值分配给它作为后备。
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
这是我的情况:
我正在使用 REST 调用的结果。结果应从 JSON 解析为 JavaScript 对象。
我需要捍卫一个错误。如果 REST 调用的参数不正确,就用户指定的参数错误而言,REST 调用返回基本上是空的。
在使用这篇文章来帮助我防御这一点时,我尝试了这个:
if( typeof restResult.data[0] === "undefined" ) { throw "Some error"; }
对于我的情况,如果 restResult.data[0] === "object",那么我可以安全地开始检查其余成员。如果未定义,则抛出上述错误。
我要说的是,就我的情况而言,这篇文章中之前的所有建议都不起作用。我不是说我是对的,每个人都是错的。我根本不是 JavaScript 大师,但希望这会对某人有所帮助。
所有的答案都不完整。这是知道有一个属性“定义为未定义”的正确方法:
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
浏览评论,对于那些想要同时检查的人是未定义还是它的值为空:
//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)
下划线.js:
_.isUndefined(obj)
_.isUndefined(obj.prop)
我在这里为那些期待奇怪答案的人提供了三种方法:
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);
未定义1:
尝试获取输入值的属性,并检查错误消息是否存在。如果输入值未定义,则错误消息将是Uncaught TypeError: Cannot read property 'b' of undefined。
未定义2:
将输入值转换为要比较的字符串,"undefined"
并确保它是负值。
未定义3:
在 JavaScript 中,当输入值正好是 时,可选参数起作用undefined
。
有一个非常简单的方法。
您可以使用可选链接:
x = {prop:{name:"sajad"}}
console.log(x.prop?.name) // Output is: "sajad"
console.log(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上的文档
我if (this.variable)
用来测试它是否被定义。一个简单的if (variable)
,在以前的答案中推荐的,对我来说失败了。
事实证明,它仅在变量是某个对象的字段时才起作用,obj.someField
以检查它是否在字典中定义。但是我们可以使用this
orwindow
作为字典对象,因为任何变量都是当前窗口中的一个字段,据我所知。因此这里是一个测试:
if (this.abc)
alert("defined");
else
alert("undefined");
abc = "abc";
if (this.abc)
alert("defined");
else
alert("undefined");
它首先检测到变量abc
未定义,并在初始化后定义。
function isUnset(inp) {
return (typeof inp === 'undefined')
}
如果设置了变量,则返回 false,如果未定义,则返回 true。
然后使用:
if (isUnset(var)) {
// initialize variable here
}
我想向您展示我正在使用的东西来保护undefined
变量:
Object.defineProperty(window, 'undefined', {});
这禁止任何人更改window.undefined
值,从而破坏基于该变量的代码。如果使用"use strict"
,任何试图改变它的值的东西都会以错误告终,否则它会被默默地忽略。
来自 lodash.js。
var undefined;
function isUndefined(value) {
return value === undefined;
}
它创建一个名为的局部变量undefined
,该变量使用默认值进行初始化——实数undefined
,然后value
与变量进行比较undefined
。
2019 年 9 月 9 日更新
我发现 Lodash 更新了它的实现。请参阅我的问题和代码。
为了防弹,只需使用:
function isUndefined(value) {
return value === void 0;
}
您也可以使用代理。它适用于嵌套调用,但需要额外检查:
function resolveUnknownProps(obj, resolveKey) {
const handler = {
get(target, key) {
if (
target[key] !== null &&
typeof target[key] === 'object'
) {
return resolveUnknownProps(target[key], resolveKey);
} else if (!target[key]) {
return resolveUnknownProps({ [resolveKey]: true }, resolveKey);
}
return target[key];
},
};
return new Proxy(obj, handler);
}
const user = {}
console.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }
所以你会像这样使用它:
const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;
if (!isUndefined) {
// Do something
}
在最近的 JavaScript 版本中,引入了新的链接运算符,这很可能是检查属性是否存在的最好方法,否则它会给你 undefined
见下面的例子
const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah'
}
};
const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined
console.log(adventurer.someNonExistentMethod?.());
// expected output: undefined
我们可以替换这个旧语法
if (response && response.data && response.data.someData && response.data.someData.someMoreData) {}
使用这种更简洁的语法
if( response?.data?.someData?.someMoreData) {}
IE、Opera、safari 和 samsund android 不支持此语法
有关更多详细信息,您可以查看此 URL
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
此外,同样的事情可以写得更短:
if (!variable){
// Do it if the variable is undefined
}
或者
if (variable){
// Do it if the variable is defined
}
采用:
检查属性是否未定义:
if (typeof something === "undefined") {
alert("undefined");
}
检查属性是否未定义:
if (typeof something !== "undefined") {
alert("not undefined");
}
检查密钥是否存在的一种简单方法是使用in
:
if (key in obj) {
// Do something
} else {
// Create key
}
const obj = {
0: 'abc',
1: 'def'
}
const hasZero = 0 in obj
console.log(hasZero) // true
我很惊讶我还没有看到这个建议,但它比使用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
}
Lodash库中有几个小助手:
isUndefined - 检查值是否为undefined
.
_.isUndefined(undefined) // => true
_.isUndefined(null) // => false
has - 检查对象是否包含属性
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.log('Name: ' +p.name, ', Age: '+p.age, ', Gender: '+p.gender)
将输出以下文本而不会得到任何未定义。
Name: Kevin , Age: N/A , Gender: N/A
这可能是确定现有属性名称是否具有明确的预期值的唯一明确形式undefined
; 尽管如此,它还是一种 JavaScript 类型。
"propertyName" in containerObject && ""+containerObject["propertyName"] == "undefined";
>> true \ false
true
此表达式仅在给定上下文的属性名称存在(真实)且仅当其预期值是显式时才会返回undefined
。
不会出现误报,例如空字符串或空字符串、零、空数组或空数组等。这正是这样做的。检查即确保属性名称存在(否则将是误报),而不是显式检查其值是否undefined
为字符串表示形式中未定义的 JavaScript 类型(字面意思是“未定义”),==
而不是===
因为没有进一步转换是可能的。并且这个表达式只有在两者都满足的情况下才会返回 true,即所有条件都满足。例如,如果属性名称不存在, - 它将返回 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
您可以像这样使用 JavaScript 对象函数:
var ojb ={
age: 12
}
if(ojb.hasOwnProperty('name')){
console.log('property exists and is not undefined');
}
true
如果获得该属性或该属性未定义,则上述方法返回。
我发现这篇文章7 Tips to Handle undefined in JavaScript,它展示了一些非常有趣的东西,undefined
比如:
undefined 的存在是 JavaScript 的宽容性质的结果,它允许使用:
- 未初始化的变量
- 不存在的对象属性或方法
- 越界索引访问数组元素
- 什么都不返回的函数的调用结果
在 JavaScript 中,表达式有真值和假值。如果要检查属性是否未定义,可以直接使用给定的if条件,
- 使用真/假概念。
if(!ob.someProp){
console.log('someProp is falsy')
}
但是,还有其他几种方法可以检查对象是否具有属性,但对我来说似乎很长。这是那些。
- 使用
=== undefined
签入if
条件
if(ob.someProp === undefined){
console.log('someProp is undefined')
}
- 使用
typeof
typeof
用作对 undefined 值和变量是否存在的组合检查。
if(typeof ob.someProp === 'undefined'){
console.log('someProp is undefined')
}
- 使用
hasOwnProperty
方法
JavaScript 对象已经内置在hasOwnProperty
对象原型中的函数中。
if(!ob.hasOwnProperty('someProp')){
console.log('someProp is undefined')
}
没有深入,但第一种方式对我来说看起来很短而且很好。以下是JavaScript 中真值/假值的详细信息,并且undefined
是其中列出的假值。所以if
条件表现正常,没有任何故障。除了undefined
, values NaN
,false
(显然),''
(空字符串)和 number0
也是假值。
警告:确保属性值不包含任何虚假值,否则
if
条件将返回 false。对于这种情况,您可以使用该hasOwnProperty
方法
审查
许多给定的答案给出了错误的结果,因为它们没有区分对象属性不存在的情况和属性具有值的情况undefined
。以下是最流行解决方案的证明:
let obj = {
a: 666,
u: undefined // The 'u' property has value 'undefined'
// The 'x' property does not exist
}
console.log('>>> good results:');
console.log('A', "u" in obj, "x" in obj);
console.log('B', obj.hasOwnProperty("u"), obj.hasOwnProperty("x"));
console.log('\n>>> bad results:');
console.log('C', obj.u === undefined, obj.x === undefined);
console.log('D', obj.u == undefined, obj.x == undefined);
console.log('E', obj["u"] === undefined, obj["x"] === undefined);
console.log('F', obj["u"] == undefined, obj["x"] == undefined);
console.log('G', !obj.u, !obj.x);
console.log('H', typeof obj.u === 'undefined', typeof obj.x === 'undefined');
使用动态变量的版本 你知道吗?
var boo ='lala';
function check(){
if(this['foo']){
console.log('foo is here');}
else{
console.log('have no foo');
}
if(this['boo']){
console.log('boo is here');}
else{
console.log('have no boo');
}
}
check();
处理未定义
function isUndefined(variable,defaultvalue=''){
if (variable == undefined )
{
return defaultvalue;
}
return variable
}
var obj={
und:undefined,
notundefined:'hi i am not undefined'
}
function isUndefined(variable,defaultvalue=''){
if (variable == undefined )
{
return defaultvalue;
}
return variable
}
console.log(isUndefined(obj.und,'i am print'))
console.log(isUndefined(obj.notundefined,'i am print'))
我们在ES6中可以使用!!
Convert all values to Boolean。使用它,所有虚假值都变为false。
第一个解决方案
if (!(!!variable)) {
// Code
}
第二种解决方案
if (!variable) {
// Code
}
Object.hasOwnProperty(o, 'propertyname');
但是,这不会通过原型链查找。
if (somevariable == undefined) {
alert('the variable is not defined!');
}
你也可以把它变成一个函数,如下所示:
function isset(varname){
return(typeof(window[varname]) != 'undefined');
}