检查 JavaScript 中的对象属性是否未定义的最佳方法是什么?
in
运算符:'key' in obj ? 'obj has key property' : 'obj does not have key property'
`
检查属性值是否为特殊值 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 中,“未定义”不是关键字,因此函数内部的变量可以命名为“未定义”并隐藏全局属性。
如果您担心这种(不太可能的)边缘情况,您可以使用 the void operator 来获取特殊的 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 未声明的情况下引发错误。
void 0
来获取 undefined
指向的值。所以你可以做if (myVar === void 0)
。 0
并不特殊,您可以在其中放置任何表达式。
undefined
。 MDN: undefined
if (obj.field === undefined)
是完全合理的。我认为有人做var undefined = false;
的风险被高估了。如果您想防止因糟糕的编程而导致的所有此类副作用,您将不得不进行不合理的防御性编程。
undefined
(这只能由糟糕的开发人员完成),但他们却乐于使用其他可能也被遮蔽的全局标识符。奇怪。很奇怪。
尽管这里的许多其他答案都强烈推荐,typeof
是一个糟糕的选择。它永远不应该用于检查变量是否具有值 undefined
,因为它作为对值 undefined
和变量是否存在的组合检查。在绝大多数情况下,您知道变量何时存在,如果您在变量名或字符串文字 'undefined'
中输入错误,typeof
只会引入潜在的静默失败。
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)或参数(函数 bar(foo) { ... },称为 bar())将失败。这根本不是真的——没有显式初始化的变量和没有给定值的参数总是变得未定义,并且总是在范围内。
那个未定义的可以被覆盖。确实 undefined 不是关键字,但它是只读且不可配置的。尽管有非关键字状态(Object、Math、NaN……),但您可能无法避免使用其他内置函数,而且实用代码通常不是在积极的恶意环境中编写的,因此这不是一个很好的理由担心未定义。 (但如果您正在编写代码生成器,请随意使用 void 0。)
了解变量的工作方式之后,是时候解决实际问题了:对象属性。没有理由将 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')
将告诉您它是否直接在对象上。不过,我不会在这个答案中详细介绍原型和使用对象作为字符串键映射,因为它主要是为了反驳其他答案中的所有坏建议,而不管原始问题的可能解释如何。阅读object prototypes on MDN了解更多信息!
¹ 示例变量名的不寻常选择?这是来自 Firefox 的 NoScript 扩展的真正死代码。
² 不要假设不知道范围内的内容通常是可以的。滥用动态范围导致的额外漏洞:Project Zero 1225
³ 再次假设 ES5+ 环境并且 undefined
引用全局对象的 undefined
属性。
undefined
,隐藏默认上下文。对于大多数实际目的而言,这与覆盖它具有相同的效果。
void 0
与 undefined 进行比较,但又一次 - 这是愚蠢和矫枉过正的。
typeof something === "undefined")
。
Math
或 Object
或 setTimeout
,或者您希望在默认情况下在全局范围内找到的任何内容。
在 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
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
笔记:
您不能同时检查对象及其属性。例如,this xa === undefined 或 this typeof xa == 'undefined' 引发 ReferenceError: x is not defined if x is not defined。
变量 undefined 是一个全局变量(实际上它在浏览器中是 window.undefined)。从 ECMAScript 第一版开始就支持它,从 ECMAScript 5 开始它是只读的。因此,在现代浏览器中,它不能被重新定义为真实的,因为许多作者喜欢用吓唬我们的方式来吓唬我们,但这对于旧浏览器来说仍然是真实的。
最后一战:obj.prop === undefined vs typeof obj.prop == 'undefined'
obj.prop === undefined
的优点:
它有点短,看起来有点漂亮
如果你拼错了 undefined,JavaScript 引擎会给你一个错误
obj.prop === undefined
的减号:
undefined 可以在旧浏览器中被覆盖
typeof obj.prop == 'undefined'
的优点:
真的是万能的!它适用于新旧浏览器。
typeof obj.prop == 'undefined'
的减号:
这里的 'undefned'(拼写错误)只是一个字符串常量,所以如果您像我刚才那样拼错了,JavaScript 引擎将无法帮助您。
更新(对于服务器端 JavaScript):
Node.js 支持将全局变量 undefined
作为 global.undefined
(它也可以在没有“全局”前缀的情况下使用)。我不知道服务器端 JavaScript 的其他实现。
undefined
作为 global
的成员。此外,console.log(global);
和 for (var key in global) { ... }
都不会将 undefined 显示为 global 的成员。但是像 'undefined' in global
这样的测试显示相反。
[[Enumerable]]
是错误的 :-)
Minuses of typeof obj.prop == 'undefined'
,这可以通过写成 typeof obj.prop == typeof undefined
来避免。这也提供了非常好的对称性。
obj.prop === undefined
相比,这完全没有意义。
if ('foo' in o
)...您的答案确实是这里的第一个正确答案。几乎所有其他人都只是回答这句话。
问题归结为三种情况:
该对象具有属性并且其值不是未定义的。该对象具有该属性,其值未定义。该对象不具有该属性。
这告诉我们一些我认为重要的事情:
未定义成员和具有未定义值的已定义成员之间存在差异。
但不幸的是,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)) {}
用括号括起来,因为!运算符优先于“in”。希望对某人有所帮助。
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"
。
我不确定将 ===
与 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
var x = obj && obj.prop || 'default';
obj.prop
是 false
、0
、""
和其他各种错误值,它会失败。这正是我们不应该做的,也适用于不应该以这种方式使用的可选链接。
从相关问题交叉发布my answerHow can I check for "undefined" in 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');
}
变量是否真的存在的问题并不重要,它的值是不正确的。否则用 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');
}
当第一个简单条件为真时,解释器跳过下一个测试。
最好使用变量的实例/对象来检查它是否获得了有效值。它更稳定,是一种更好的编程方式。
(y)
在文章 Exploring the Abyss of Null and Undefined in 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 中定义,是未定义的,不管它是对象/数组中的属性还是只是一个简单的变量......
JavaScript 有 typeof
,它可以很容易地检测未定义的变量。
只需检查 typeof whatever === 'undefined'
是否会返回一个布尔值。
这就是 AngularJs v.1x 中著名的函数 isUndefined()
的编写方式:
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
}
这也等于 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 运算符和 undefined 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`)
}
更多> here
ECMAScript 10 引入了一项新功能 - 可选链接,仅当对象定义如下时,您才能使用该功能使用对象的属性:
const userPhone = user?.contactDetails?.phone;
只有在定义了 user 和 contactDetails 时,它才会引用 phone 属性。
参考。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
'if (window.x) { }' 是错误安全的
您很可能需要 if (window.x)
。即使未声明 x (var x;
),此检查也是安全的 - 浏览器不会引发错误。
示例:我想知道我的浏览器是否支持 History API
if (window.history) {
history.call_some_function();
}
这是如何工作的:
window 是一个将所有全局变量作为其成员的对象,尝试访问不存在的成员是合法的。如果 x 尚未声明或尚未设置,则 window.x
返回 undefined。当 if() 评估它时,undefined 会导致 false。
typeof history != 'undefined'
实际上适用于两个系统。
读到这里,我很惊讶我没有看到这个。我发现了多种适用于此的算法。
从未定义
如果从未定义过对象的值,如果将其定义为 null
或 undefined
,这将阻止返回 true
。如果您希望为设置为 undefined
的值返回 true,这将很有帮助
if(obj.prop === void 0) console.log("The value has never been defined");
定义为未定义或从未定义
如果您希望它对于使用 undefined
的值定义或从未定义的值作为 true
,您可以简单地使用 === 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
”如何?这是错误的。
"propertyName" in obj //-> true | false
解决方案不正确。在 JavaScript 中,
null == undefined
将返回 true,因为它们都被“强制转换”为布尔值并且为 false。正确的方法是检查
if (something === undefined)
这是身份运算符...
===
是类型相等 +(原始相等 | 对象标识),其中原始包含字符串。如果将 ===
视为身份运算符,我认为大多数人认为 'abab'.slice(0,2) === 'abab'.slice(2)
不直观。
为了简洁起见,与 void 0
进行比较。
if (foo !== void 0)
它不像 if (typeof foo !== 'undefined')
那样冗长
foo
未声明,它将引发 ReferenceError。
您可以使用以下代码获取所有未定义路径的数组。
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
。
如果已定义新变量,则有一种很好且优雅的方法可以将已定义属性分配给新变量,如果未定义,则将默认值分配给它作为后备。
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
let objAndPropCheck = (obj || { }).prop || 0;
所有的答案都不完整。这是知道有一个属性“定义为未定义”的正确方法:
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
这是我的情况:
我正在使用 REST 调用的结果。结果应从 JSON 解析为 JavaScript 对象。
我需要捍卫一个错误。如果 REST 调用的参数不正确,就用户指定的参数错误而言,REST 调用返回基本上是空的。
在使用这篇文章来帮助我防御这一点时,我尝试了这个:
if( typeof restResult.data[0] === "undefined" ) { throw "Some error"; }
对于我的情况,如果 restResult.data[0] === "object",那么我可以安全地开始检查其余成员。如果未定义,则抛出上述错误。
我要说的是,就我的情况而言,这篇文章中之前的所有建议都不起作用。我不是说我是对的,每个人都是错的。我根本不是 JavaScript 大师,但希望这会对某人有所帮助。
typeof
守卫实际上并没有防范直接比较无法处理的任何事情。如果 restResult
未定义或未声明,它仍然会抛出。
if(!restResult.data.length) { throw "Some error"; }
浏览评论,对于那些想要同时检查的人是未定义还是它的值为空:
//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)
1
添加到变量 x
?我需要下划线还是 jQuery? (令人惊讶的是,即使是最基本的操作,例如 typeof
检查,人们也会使用库)
我在这里为那些期待奇怪答案的人提供了三种方法:
函数 isUndefined1(val) { 尝试 { val.a; } catch (e) { return /undefined/.test(e.message); } 返回假; } function isUndefined2(val) { return !val && val+'' === 'undefined'; } function isUndefined3(val) { const defaultVal = {};返回 ((输入 = defaultVal) => 输入 === defaultVal)(val); } function test(func){ console.group(`test start :`+func.name); console.log(func(undefined));控制台.log(func(null));控制台.log(func(1)); console.log(func("1")); console.log(func(0)); console.log(func({})); console.log(func(function () { }));控制台.groupEnd(); } 测试(isUndefined1);测试(isUndefined2);测试(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)
,recommended in a previous answer,对我来说失败了。
事实证明,它仅在变量是某个对象的字段时才起作用,obj.someField
检查它是否在字典中定义。但是我们可以使用 this
或 window
作为字典对象,因为据我所知,任何变量都是当前窗口中的一个字段。因此这里是一个测试:
如果(this.abc)警报(“定义”);否则警报(“未定义”); abc = "abc";如果(this.abc)警报(“定义”);否则警报(“未定义”);
它首先检测到变量 abc
是未定义的,它是在初始化之后定义的。
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"
,任何试图改变它的值的东西都会出错,否则它会被忽略。
obj !== undefined
。undefined
过去是可变的,例如undefined = 1234
会导致有趣的结果。但是在 Ecmascript 5 之后,它不再可写了,所以我们可以使用更简单的版本。 codereadability.com/how-to-check-for-undefined-in-javascript