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
}
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`)
}
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 (typeof something === "undefined") {
alert("something is undefined");
}
如果具有某些属性的对象变量可以使用如下所示的相同内容:
if (typeof my_obj.someproperties === "undefined"){
console.log('the property is not available...'); // print into console
}
40
同样的事情可以写得更短:
if (!variable){
//do it if variable is Undefined
}
要么
if (variable){
//do it if variable is Defined
}
35
您可以使用以下代码获取一个未定义路径的数组 .
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;
}
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 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;
828
function isUnset(inp) {
return (typeof inp === 'undefined')
}
如果设置了变量,则返回false;如果未定义,则返回true .
然后使用:
if (isUnset(var)) {
// initialize variable here
}
12
问题可归结为三种情况:
该对象具有该属性,其值不是 undefined .
该对象具有该属性,其值为 undefined .
该对象没有该属性 .
这告诉我们一些我认为重要的事情:
There is a difference between an undefined member and a defined member with an undefined value.
30 回答
如果您使用的是Angular:
Underscore.js:
尽管在这里被许多其他答案强烈推荐,
typeof
是一个糟糕的选择 . 它永远不应该用于检查变量是否具有值undefined
,因为它充当组合检查值undefined
以及变量是否存在 . 在绝大多数情况下,您知道变量何时存在,并且如果您在变量名称或字符串文字'undefined'
中输入错误,typeof
将仅引入静默失败的可能性 .因此,除非您正在进行特征检测²,否则给定名称是否在范围内是不确定的(例如,检查
typeof module !== 'undefined'
作为特定于CommonJS环境的代码中的步骤),_ _27416_在用于变量时是一个有害的选择,并且正确选项是直接比较值:一些常见的误解包括:
读取“未初始化”变量(
var foo
)或参数(function bar(foo) { … }
,称为bar()
)将失败 . 这根本不是真的 - 没有显式初始化的变量和未给定值的参数总是变为undefined
,并且始终在范围内 .可以覆盖
undefined
. 这还有很多 .undefined
不是JavaScript中的关键字 . 相反,它是具有Undefined值的全局对象上的属性 . 但是,从ES5开始,此属性是只读且不可配置的 . 没有现代浏览器允许更改undefined
属性,并且截至2017年已经存在很长时间了 . 缺乏严格模式也不会影响undefined
的行为 - 它只会使像_237426这样的语句不做任何事情而不是抛出 . 但是,由于它不是关键字,因此可以声明名称为undefined
的变量,并且可以更改这些变量,从而形成这种曾经常见的模式:比使用全局
undefined
更危险 . 如果您必须与ES3兼容,请将undefined
替换为void 0
- 不要求助于typeof
. (void
始终是一元运算符,其值为任何操作数的未定义值 . )通过变量如何解决问题,是时候解决实际问题了:对象属性 . 没有理由将
typeof
用于对象属性 . 有关特征检测的早期例外在此处不适用 -typeof
仅对变量有特殊行为,而引用对象属性的表达式不是变量 .这个:
总是完全等同于这个:
并考虑上面的建议,以避免让读者混淆你为什么使用
typeof
,因为使用===
检查相等性是最有意义的,因为它可以重构为稍后检查变量的值,因为它只是简单的看起来更好, you should always use === undefined³ here as well .在涉及对象属性时需要考虑的其他事项是你是否真的想要检查
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指的是全局对象的未定义属性 . 否则替换void 0 .
在Exploring the Abyss of Null and Undefined in JavaScript文章中,我读到像Underscore.js这样的框架使用了这个函数:
我使用
if (this.variable)
测试它是否已定义 . 简单if (variable)
,recommended above,对我来说失败了 . 事实证明,它仅在变量是某个对象的字段时起作用,obj.someField
来检查它是否在字典中定义 . 但是我们可以使用this
或window
作为字典对象,因为任何变量都是当前窗口中的字段,据我所知 . 因此这是一个测试它首先检测到变量
abc
未定义,并在初始化后定义 .只是在JavaScript中没有定义任何东西, undefined ,不是't matter if it'是一个对象/数组内的属性,或者只是一个简单的变量......
JavaScript有
typeof
,这使得检测未定义的变量变得非常容易 .只需检查
typeof whatever === 'undefined'
是否会返回一个布尔值 .这就是AngularJs v.1x中着名函数
isUndefined()
的编写方式:因此,当您看到函数接收到值时,如果定义了该值,它将返回
false
,否则对于未定义的值,返回true
.因此,让我们看看当我们传递值时会产生什么结果,包括下面的对象属性,这是我们拥有的变量列表:
我们检查它们如下,你可以看到它们前面的结果作为评论:
如你所见,我们可以在我们的代码中使用类似的东西来检查任何内容,如上所述,您可以在代码中使用typeof,但如果您反复使用它,请创建一个类似我分享的角度样本的函数并继续重用如下面的DRY代码模式 .
还有一件事,为了检查实际应用程序中的对象的属性,你甚至不确定对象是否存在,检查对象是否存在 .
如果检查对象上的属性并且该对象不存在,则会抛出错误并停止整个应用程序的运行 .
如此简单,你可以在if语句中包装如下:
这也等于Angular 1.x中的isDefined ...
另外其他javascript框架如下划线也有类似的定义检查,但我建议你使用
typeof
如果你还没有使用任何框架 .我还从MDN添加了这一部分,其中包含有关typeof,undefined和void(0)的有用信息 .
更多> here
我不确定使用
===
与typeof
的起源来自哪里,作为一种惯例,我看到它在许多库中使用,但是typeof运算符返回一个字符串文字,我们知道这个,所以为什么你也想要键入检查呢?我没有看到(希望我没有错过)任何人在 properties 前检查物体 . 所以,这是最短和最有效的(虽然不一定是最清楚的):
如果obj或obj.prop未定义,null或"falsy",则if语句将不执行代码块 . 这通常是大多数代码块语句(在JavaScript中)中所需的行为 .
使用:
如果具有某些属性的对象变量可以使用如下所示的相同内容:
同样的事情可以写得更短:
要么
您可以使用以下代码获取一个未定义路径的数组 .
jsFiddle链接
通过阅读,我很惊讶我没有看到这一点 . 我发现了多种适用于此的算法 .
从未定义
如果从未定义对象的值,则如果将其定义为
null
或undefined
,则将阻止返回true
. 如果要为设置为undefined
的值返回true,这将非常有用定义为未定义或从未定义
如果您想要将
true
的结果定义为undefined
或从未定义的值,则只需使用=== undefined
定义为假值,未定义,null或从未定义 .
通常,人们要求我使用算法来确定某个值是假的,
undefined
还是null
. 以下作品 .这是什么意思: "undefined object property" ?
实际上它可能意味着两件完全不同的东西!首先,它可以表示从未在对象中定义的属性,其次,它可以表示具有未定义值的属性 . 我们来看看这段代码:
是
o.a
未定义?是!它的 Value 是不确定的 . 是o.b
未定义?当然!根本没有属性'b'!好的,现在看看两种情况下不同方法的表现如何:我们可以清楚地看到
typeof obj.prop == 'undefined'
和obj.prop === undefined
是等价的,并且他们没有区分这些不同的情况 . 并且'prop' in obj
可以检测到属性没有注意可能未定义的属性值时的情况 .那该怎么办?
1)您想知道属性是否由第一个或第二个含义(最典型的情况)定义 .
2)您只想知道对象是否具有某些属性而不关心其值 .
注意:
您无法同时检查对象及其属性 . 例如,如果未定义x,则此
x.a === undefined
或此typeof x.a == 'undefined'
会引发ReferenceError: x is not defined
.变量
undefined
是一个全局变量(实际上它在浏览器中是window.undefined
) . 它自ECMAScript第1版以来一直受到支持,自ECMAScript 5以来它就是 read only . 所以在现代浏览器中,它不能被重新定义为真实,因为许多作者喜欢用我们来吓唬我们,但对于旧浏览器来说这仍然是正确的 .最后的战斗:obj.prop === undefined vs typeof obj.prop =='undefined'
优点
obj.prop === undefined
:它有点短,看起来更漂亮
如果拼写错误,JavaScript引擎会给你一个错误
undefined
obj.prop === undefined
的缺点:undefined
可以在旧浏览器中覆盖优点
typeof obj.prop == 'undefined'
:typeof obj.prop == 'undefined'
的缺点:'undefned'
(拼写错误)这里只是一个字符串常量,所以如果你像我刚才拼错了它,JavaScript引擎就无法帮助你 .更新(对于服务器端JavaScript):
Node.js支持全局变量
undefined
为global.undefined
(它也可以在没有'global'前缀的情况下使用) . 我不知道服务器端JavaScript的其他实现 .这对我有用,而其他人没有 .
所有答案都不完整 . 这是知道某个属性“定义为未定义”的正确方法:
例:
太糟糕了,这是正确的答案埋没在错误的答案> _ <
所以,对于任何经过的人,我都会免费给你undefined!
我相信这个话题有很多不正确的答案 . 与普遍看法相反,"undefined"在JavaScript中是 not 关键字,实际上可以为其分配值 .
正确代码
执行此测试的最强大方法是:
这将始终返回正确的结果,甚至可以处理未声明
myVar
的情况 .退化代码 . 不使用 .
此外,
myVar === undefined
将在myVar未声明的情况下引发错误 .从相关问题How to check for "undefined" in JavaScript?转发我的answer
具体到这个问题,请参阅
someObject.<whatever>
的测试用例 .一些场景说明了各种答案的结果:http://jsfiddle.net/drzaus/UVjM4/
(注意在
in
测试中使用var
会在作用域包装中产生影响)代码参考:
结果:
通过注释,对于那些想要检查它们的人来说,它是未定义的或其值为null:
如果您使用的是jQuery Library,那么
jQuery.isEmptyObject()
就足以满足这两种情况,如果设置了变量,则返回false;如果未定义,则返回true .
然后使用:
问题可归结为三种情况:
该对象具有该属性,其值不是
undefined
.该对象具有该属性,其值为
undefined
.该对象没有该属性 .
这告诉我们一些我认为重要的事情:
There is a difference between an undefined member and a defined member with an undefined value.
但不幸的是
typeof obj.foo
并没有告诉我们这三个案例中的哪一个 . 但是我们可以将它与"foo" in obj
结合起来区分案例 .值得注意的是,这些测试对于
null
条目也是相同的我认为在某些情况下更有意义(并且更清楚)检查属性是否存在,而不是检查它是否未定义,并且唯一的情况是这种检查将是不同的是案例2,这是罕见的情况具有未定义值的对象中的实际条目 .
例如:我刚刚重构了一堆代码,这些代码检查对象是否具有给定属性 .
在没有检查未定义的情况下编写时更清楚 .
但正如已经提到的,这些并不完全相同(但对我的需求来说已经足够好了) .
'if(window.x){}'是错误安全的
你很可能想要
if (window.x)
. 即使未声明x(var x;
),此检查也是安全的 - 浏览器不会抛出错误 .示例:我想知道我的浏览器是否支持History API
这是如何工作的:
window 是一个将所有全局变量保存为其成员的对象,尝试访问不存在的成员是合法的 . 如果 x hasn 't been declared or hasn' t已设置,则
window.x
返回 undefined . undefined 在 if() 评估时导致 false .解决方案不正确 . 在JavaScript中,
将返回true,因为它们都被“转换”为布尔值并且为false . 正确的方法是检查
这是身份运营商......
使用:
To check if property is undefined:
To check if property is not undefined:
我想向您展示一些我正在使用的东西,以保护
undefined
变量:这禁止任何人更改
window.undefined
值,因此会根据该变量销毁代码 . 如果使用"use strict"
,任何试图更改其值的内容都将以错误结束,否则将被忽略 .如果你这样做
当变量
myvar
不存在时,它将失败,因为未定义myvar,因此脚本被破坏且测试无效 .由于窗口对象在函数外部具有全局范围(默认对象),因此声明将“附加”到窗口对象 .
例如:
全局变量myvar与window.myvar或window ['myvar']相同
为避免在存在全局变量时测试错误,最好使用:
变量确实存在的问题无关紧要,其值不正确 . 否则,使用undefined初始化变量是愚蠢的,最好使用值false来初始化 . 当您知道所声明的所有变量都使用false初始化时,您只需检查其类型或依赖
!window.myvar
来检查它是否具有正确/有效的值 . 因此,即使未定义变量,!window.myvar
或myvar = false
或myvar = 0
的!window.myvar
也相同 .当您需要特定类型时,请测试变量的类型 . 为了加快测试条件,您最好:
当第一个和简单条件为真时,解释器会跳过下一个测试 .
最好使用变量的实例/对象来检查它是否具有有效值 . 它更稳定,是一种更好的编程方式 .
(y)的
对于那些期待奇怪答案的人,我提供了三种方法:
isUndefined1:
尝试获取输入值的属性,检查错误消息是否存在 . 如果输入值未定义,则错误消息将为Uncaught TypeError:无法读取未定义的属性'b'
isUndefined2:
将输入值转换为字符串以与
"undefined"
进行比较并确保其为负值 .isUndefined3:
在js中,当输入值正好是
undefined
时,可选参数有效 .在JavaScript中有 null 并且有 undefined . 它们有不同的含义 .
undefined 表示尚未定义变量值;不知道它的 Value 是多少 .
null 表示定义变量值并设置为null(没有值) .
Marijn Haverbeke在他的免费在线书籍“Eloquent JavaScript”(强调我的)中说:
所以,我想检查某些内容是否未定义的最佳方法是:
希望这可以帮助!
Edit: 为了响应您的编辑,对象属性应该以相同的方式工作 .
这是我的情况:
我正在使用REST调用的结果 . 结果应该从JSON解析为JavaScript对象 .
我需要保护一个错误 . 如果用户指定args错误,其余调用的args是不正确的,则其余的调用基本上是空的 .
虽然使用这篇文章来帮助我防范这个,但我尝试了这个 .
对于我的情况,如果restResult.data [0] ===“对象”,那么我可以安全地开始检查其余的成员 . 如果未定义,则抛出上述错误 .
我所说的是,就我的情况而言,本文上面的所有建议都没有用 . 我不是说我是对的,每个人都错了 . 我根本不是JavaScript大师,但希望这会对某人有所帮助 .
与
void 0
比较,用于简洁 .它不像
if (typeof foo !== 'undefined')
那么冗长如果已定义属性,则可以将定义的属性分配给新变量,如果未定义,则将其作为回退分配给它 .
如果你有一个函数,它接收一个额外的配置属性是合适的:
正在执行