JavaScript中如何检查对象是否存在

364

我如何在 JavaScript 中验证对象的存在?

以下代码可行:

if (!null)
   alert("GOT HERE");

但是这会抛出一个错误:

if (!maybeObject)
   alert("GOT HERE");

错误信息:

maybeObject未定义。


这个问题的问题在于使用了“存在”这个词。实际上,“存在”是什么意思?一个对象可以“存在”,但有意地没有值(let myobj = null)。在这种情况下,访问对象的属性会导致运行时错误,这才是你真正感兴趣的。因此,虽然被接受的答案在技术上是正确的,并且获得了大量的分数,但它并没有任何实际价值。 - EML
18个回答

689

在未定义的变量上可以安全地使用typeof运算符。

如果它被赋予任何值,包括null,typeof将返回除undefined之外的其他值。 typeof始终返回一个字符串。

因此,

if (typeof maybeObject != "undefined") {
   alert("GOT THERE");
}

85
如果它总是一个字符串,你真的可以(应该)使用“!==”进行比较。 - Micah
12
由于这是JavaScript的核心功能,很遗憾没有更好且更少出错的内置功能。字符串比较防止编译器百分之百地可靠地告诉我们在这些检查中是否犯了小错误(如打字错误)。 - Domi
@T.J.Crowder 这些示例似乎无法访问了。 - Stefan van den Akker
1
@StefanvandenAkker:错误示例的链接应该是http://jsbin.com/ibeho3/1/。好的示例没问题:http://jsbin.com/ibeho3/2/。(不幸的是,JSBin会重定向到最新版本,人们一直在编辑它,已经改变了很多。) - T.J. Crowder
@Micah 就因为 typeof 总是返回字符串,我们可以放心地使用简单的不等比较运算符而非严格的不等比较运算符。在这种情况下使用严格比较运算符没有意义,因为我们总是处理字符串值。 简单的不等运算符 != 或简单的相等运算符 == 并不总是不好的;在某些情况下它们可以非常方便。 - Christos Lytras
显示剩余3条评论

50

这里有很多半真半假的说法,所以我想澄清一些事情。

实际上你不能准确地判断一个变量是否存在(除非你想将每一行代码都包裹在try-catch块中)。

原因是Javascript有这个臭名昭著的值undefined,令人惊讶的是它并不意味着变量未定义,或者变量不存在undefined !== not defined

var a;
alert(typeof a); // undefined (declared without a value)
alert(typeof b); // undefined (not declared)

所以,一个存在的变量和一个不存在的变量都可以报告给你 undefined 类型。

至于 @Kevin 所误解的一点,null == undefined。这是由于类型强制转换造成的,也是 Crockford 建议所有对此不确定的人始终使用严格相等运算符 === 来测试可能为假值的原因。 null !== undefined 将给出您可能期望的结果。请注意,foo != null 可以是检查变量既不是 undefined 也不是 null 的有效方法。当然,您也可以明确指定,因为这可能有助于可读性。

如果您限制问题检查对象是否存在,则 typeof o == "object" 可能是一个好主意,除非您不将数组视为对象,因为这也会报告 object 类型,这可能会让您有些困惑。更不用说 typeof null 也会给您返回 object,这是完全错误的。

您真正应该小心的领域是主机对象,其中您应该小心 typeofundefinednullunknown 和其他神秘物。它们不能被信任。它们可以自由地做几乎任何肮脏的事情。因此,请小心使用它们,如果可以,请检查其功能,因为这是使用可能不存在的功能的唯一安全方法。


5
如果foo未定义,简单地执行 foo!=null 将产生一个ReferenceError错误。因此,最好使用typeof,除非你打算捕获这个异常。 - JAL
1
我再为您写一次:*undefined !== not defined && foo != null可以有效地检查变量既不是'undefined'也不是'null'*。我没说!= null适合用来检查它是否存在。您正在将其上下文脱离了。 (我还提到这是一个侧面说明,与OP问题的主题没有严格关系) - gblazex
2
你又把“未定义”和类型“undefined”混淆了。它们不是一样的。注意:可以使用“!==”,应该使用。在变量被声明(参数列表或其他地方)并且您想要检查它是否有值时,“!= null”是完全安全的。这是与OP所要求的不同用例,这就是为什么我将其作为注释引入的原因。整个段落都是关于@Kevin的帖子和类型强制转换的。如果你仔细阅读,你会注意到的。 - gblazex
@JAL,你忽略了一个重要的部分,即当你知道变量已经被声明时,使用!= null不会产生错误风险。这对于检查函数参数非常有用,例如:var hasValue = function(foo) {return foo != null} - tybro0103
@tybro0103 这是真的,但整个问题是“如何在JavaScript中验证对象的存在?”如果您确定它已被声明,那就是另一种情况。 - JAL
我知道答案中已经说明了,但是我想再次强调,“undefined”并不完全意味着“未定义”。代码片段 foo != null 作为检查等同于 (foo !== null && foo !== undefined),如果变量未被定义,这将会抛出异常。 - James Hurley

19

你可以使用:

if (typeof objectName == 'object') {
    //do something
}

18

两种方法:

typeof 用于本地变量

您可以使用 typeof测试本地对象:

if (typeof object !== "undefined") {}

全局变量的窗口

您可以通过检查window对象来测试全局对象(在全局作用域中定义的对象):

if (window.FormData) {}

9
如果这是一个全局对象,你可以使用if (!window.maybeObject)

2
我发现如果maybeObject是一个全局对象,window.hasOwnProperty('maybeObject')更易读。 - Nathaniel Rogers

7

如果您只关心它是否存在(是否已经声明?),批准的答案就足够了:

if (typeof maybeObject != "undefined") {
   alert("GOT THERE");
}

如果您希望它具有实际价值,您应该添加:
if (typeof maybeObject != "undefined" && maybeObject != null ) {
   alert("GOT THERE");
}

由于 null 的类型是 object

例如:bar = { x: 1, y: 2, z: null }

typeof( bar.z ) == "object" 
typeof( bar.not_present ) == "undefined" 

通过这种方式,您可以检查它既不是null也不是undefined,并且由于typeof不会在值不存在时出错,加上&&短路运算符,您永远不会遇到运行时错误。

个人建议在某处添加一个帮助函数(让我们不要信任typeof()):

function exists(data){
   data !== null && data !== undefined
}

if( exists( maybeObject ) ){
    alert("Got here!"); 
}

第一个已经实现了第二个。如果它没有值,它就不认为它存在。 - T S
@TS:并非如此;typeof nullobject,正如这个答案所说,出于历史原因。如果您不添加第二个测试,将会出现运行时错误。 - EML

6
您可以使用 "typeof"。
if(typeof maybeObject != "undefined")
    alert("GOT HERE");

5

1
问题在于,如果maybeObject未声明,则会抛出错误:maybeObject未定义 - Juanma Menendez
1
如果 maybeObject0, 0.0 或 "",则判断为假。 - alejandrociatti

5

这个讨论串已经开启了相当长的一段时间。我认为其间使用三元运算符是最简单的选择:

maybeObject ? console.log(maybeObject.id) : ""

是的,类似于 var maybeObject = typeof maybeObject !== "undefined" ? Chart:false; 并检查是否不为 false - Hmerman6006

4

我刚刚测试了上面的typeOf示例,但都没有对我起作用,所以我使用了这个:

    btnAdd = document.getElementById("elementNotLoadedYet");
    if (btnAdd) {
       btnAdd.textContent = "Some text here";
    } else {
      alert("not detected!");
    }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接