JavaScript检查变量是否存在(已定义/初始化)


1762

哪种方法检查变量是否已初始化是更好/正确的方法?(假设变量可以容纳任何内容(字符串,整数,对象,函数等)。

if (elem) { // or !elem

要么

if (typeof(elem) !== 'undefined') {

要么

if (elem != null) {

5
如果您想知道是否foo已声明,typeof foo === 'undefined'或者typeof foo === typeof undefined

1
高度赞成的答案不适用于已声明但具有值的变量undefined。正确的答案是这样的:stackoverflow.com/a/36432729/772035
保罗

@Paulpro,该版本使用hasOwnProperty('bar')不具有相同的不足之处,其他人,但需要为节点(替换一些调整windowglobal)。
oligofren

@Paulpro确实,但是在您回答之前,我一直在思考,我得出的结论是,这实际上不是一个实际问题。当您处理块或函数范围的变量时,通常是您拥有的代码或具有写访问权的代码,因此,在任何情况下都可以修复运行时错误。尚未定义的变量(不存在)的常见问题通常出在控件之外的代码中,因此您需要一种检测它的方法。这就是80/20解决方案。
oligofren

Answers:


3049

你想要typeof操作。特别:

if (typeof variable !== 'undefined') {
    // the variable is defined
}

35
这看起来是一个很好的解决方案,但是您能解释一下为什么可行吗?
Morgan Cheng

46
实际上,您应该检查对象是否符合您的需要。这样就应该是if(typeof console =='object'){//变量是我需要的变量}
staticsan

59
@George四:“只是做'如果(变量)” -嗯,没有,失败了虚假和0
贾森小号

17
“ if(variable)”也无法测试对象属性的存在。
斯科特,2010年

54
@ geowa4实际上,如果未定义变量,则会抛出错误。
kevinji

856

typeof运营商将检查变量真的不确定。

if (typeof variable === 'undefined') {
    // variable is undefined
}

typeof运营商,不同于其他运营商,不会抛出的ReferenceError与未声明的变量使用时例外。

但是,请注意typeof null将返回"object"。我们必须小心避免将变量初始化为的错误null。为了安全起见,我们可以改用以下方法:

if (typeof variable === 'undefined' || variable === null) {
    // variable is undefined or null
}

有关使用严格比较===而不是简单相等的更多信息==,请参见:
JavaScript比较中应使用哪个equals运算符(== vs ===)?


2
if(!variable_here){//您的代码在这里。}; 无法判断该变量是false还是未定义
boh

5
if(! variable_here)在很多情况下都会破裂。如果变量为0或false,它将失败。那不是你想要的。
Cory Danielson

2
无法决定是否对此进行投票。严格说来typeof foo === "undefined",答案是正确的,并且比投票结果最好的答案要好,但是附加注释使此答案令人困惑。
Alnitak

1
@StevenPenny检查时间表。发布此答案后,其他问题合并了最高答案
Rob

1
这个答案不起作用。这是唯一可行的答案:stackoverflow.com/a/36432729/772035
Paul

221

在许多情况下,使用:

if (elem) { // or !elem

将为您完成工作!...这将检查以下情况:

  1. undefined:如果该值未定义且为undefined
  2. null:如果为null,例如,如果DOM元素不存在...
  3. 空字符串''
  4. 0:数字零
  5. NaN:不是数字

因此,它将涵盖所有情况,但总有一些奇怪的情况我们也要介绍,例如,一个带有空格的字符串,例如这样的字符串' ',将在javascript中定义,因为它在字符串中包含空格...例如,在这种情况下,您可以使用trim()再添加一张支票,例如:

if(elem) {

if(typeof elem === 'string' && elem.trim()) {
///

同样,这些检查仅针对,因为对象和数组在Javascript中的工作方式不同,因此空数组[]和空对象{}始终为true

我创建下面的图像以快速显示答案:

未定义,null等


2
@Alireza,太好了!您的回答将帮助很多人。我已经记住了这些虚假的价值观,我唯一不确定的是关于[]。
Thiago Yoithi

13
我收到“ ReferenceError:未定义elem”的问题
ropo

3
@ropo,这是因为您甚至没有定义elem来检查它的含义,如果是您的情况,则需要使用已经提到的typeof(elem)===“ string”进行检查...
Alireza

19
然后,当它说if(elem)检查未定义时(当它返回未定义的错误时),答案是误导的,不是吗?
时髦

1
给我一个用例,检查变量是否未定义以及是否用未定义的值定义?你们中的一些人正在抓紧稻草,试图看起来光彩夺目,但是如果您将一个值设置为undefined并检查该值显然会返回false或您需要更改代码,smh ....这个答案是正确的! !!!
almcaffee

210

在JavaScript中,可以定义一个变量,但是保留value undefined,因此最常见的答案在技术上并不正确,而是执行以下操作:

if (typeof v === "undefined") {
   // no variable "v" is defined in the current scope
   // *or* some variable v exists and has been assigned the value undefined
} else {
   // some variable (global or local) "v" is defined in the current scope
   // *and* it contains a value other than undefined
}

这可能足以满足您的目的。以下测试具有更简单的语义,这使得更容易精确地描述代码的行为并亲自理解(如果您关心这样的事情):

if ("v" in window) {
   // global variable v is defined
} else {
   // global variable v is not defined
}

当然,这假定您正在浏览器中运行(其中window是全局对象的名称)。但是,如果您想像这样的全局变量,则可能是在浏览器中。从主观上讲,using 'name' in window在样式上与window.nameuse引用全局变量一致。通过将全局变量作为属性window而不是变量来访问,可以使您在代码中引用的未声明变量的数量最小化(以利于衬里),并避免全局变量被局部变量覆盖的可能性。另外,如果全局对象使您的皮肤爬行,则仅用此相对较长的棍子,您可能会更舒适地触摸它们。


7
这仅检查变量是否已全局声明。如果您编码正确,那么您将限制全局变量。它将报告本地变量的false:(function(){var sdfsfs = 10; console.log(“ sdfsfs” in window);})()`
Eddie Monge Jr

2
这是最好的f $#^%ing答案。我在此尽力尝试弄清楚如何正确解释这种极端情况。辉煌。不知道你能做到这一点。
临时用户名

1
注意:您的答案已从stackoverflow.com/questions/519145/…
Shog9 2014年

对于Angular用户:不幸的是,在ng-if语句中似乎不允许使用。
qwertzguy

...完善的检查范围蓝图。如果“在窗口中”或“((typeof变量==='未定义'||变量===空)”,您有任何性能指示吗?实际上,我对一个困难的事实测试感兴趣,而对有争议的潜在理由不感兴趣(我可以自己做:第二个子句操作更多->性能更差)
更快

119

在大多数情况下,您将使用:

elem != null

不同于简单的if (elem),它允许0falseNaN'',但是废品null或者undefined,使其成为一个好,一般试验的参数的存在,或对象的属性。


其他检查也不是不正确,只是用途不同:

  • if (elem):如果可以被用于elem保证是一个对象,或者如果false0等被认为是“默认”值(因此等同于undefinednull)。

  • typeof elem == 'undefined'当指定null的变量对未初始化的变量或属性具有不同的含义时,可以使用此命令。

    • 如果未声明(即,没有语句,不是属性或函数参数),这是唯一不会引发错误的检查。在我看来,这是非常危险的,因为它会使错别字误入歧途。为避免这种情况,请参见以下方法。elemvarwindow

undefined以下内容进行严格比较也很有用:

if (elem === undefined) ...

但是,由于undefined可以用另一个值覆盖全局,因此最好undefined在使用前在当前作用域中声明该变量:

var undefined; // really undefined
if (elem === undefined) ...

要么:

(function (undefined) {
    if (elem === undefined) ...
})();

该方法的第二个优点是,JS缩小器可以将undefined变量减少为单个字符,每次都可以节省几个字节。


17
我为您可以覆盖感到震惊undefined。我什至不认为在答案中值得一提。可能是所有Javascript中最差的单个可接受变量名。
Cory Danielson

2
window.如果在全局上下文中使用,这会导致异常并要求您在变量之前使用……这不是最好的方法。
亚历克斯W

4
由于存在上述问题,您应该始终使用void(0)而不是undefined
巴特洛梅耶扎莱夫斯基

+1因为这个答案指出,有时你可能实际上识别false0等成为无效值。
rinogo

76

检查是否windowhasOwnPropertyvarname

大量typeof答案的替代方法;

var varname = value;在全局范围内用语句声明的全局变量

可以作为窗口对象的属性进行访问。

因此,该hasOwnProperty()方法

返回一个布尔值,指示对象是否具有指定的属性作为其自身的属性(而不是继承它)

可以用来确定是否

var“varname的”已在全球宣布是的一个属性window

// Globally established, therefore, properties of window
var foo = "whatever", // string
    bar = false,      // bool
    baz;              // undefined
//  window.qux does not exist

console.log( [
    window.hasOwnProperty( "foo" ), // true
    window.hasOwnProperty( "bar" ), // true
    window.hasOwnProperty( "baz" ), // true
    window.hasOwnProperty( "qux" )  // false
] );

最好的hasOwnProperty()是,在调用它时,我们不会使用尚未声明的变量-当然,这首先是问题的一半。

虽然不是经常完美理想的解决方案,在某些情况下,它只是工作!

笔记

var用于定义变量相比上述情况适用let

声明一个块范围局部变量,可以选择将其初始化为一个值。

var关键字不同,该关键字在全局范围内或整个函数本地定义变量,而与块范围无关。

在程序和函数的顶层let,与不同var,它不会在全局对象上创建属性。

为了完整起见: const从定义上来说,常量实际上不是变量(尽管其内容可以是变量);更相关地:

var变量不同,全局常量不会成为窗口对象的属性。需要一个常量的初始化程序;也就是说,您必须在声明它的同一条语句中指定它的值。

常量的值不能通过重新分配而更改,也不能重新声明。

const声明创建对值的只读引用。这并不意味着它拥有的值是不可变的,只是不能重新分配变量标识符。

由于let变量或const常量绝不是继承该hasOwnProperty()方法的任何对象的属性,因此不能将其用于检查它们的存在。

关于以下产品的可用性和使用hasOwnProperty()

Object派生的每个对象都继承该hasOwnProperty()方法。[...]与in运算符不同,此方法不会检查对象的原型链。


1
这是一个很棒的选择,应该放在这个问题的最前面。请使用返回的有效示例true(例如window.hasOwnProperty('console')var hop = "p";window.hasOwnProperty('hop'))简化答案标题。
CPHPython

2
最后,由于访问不存在的成员而不会引发错误的事物…所有typeof答案都被忽略了。
Zelphir Kaltstahl '17

1
这个答案已经过时了-根据标准ECMAScript,您可以定义变量let,这些变量在window[或任何其他可用]对象的属性中不可用。hasOwnProperty测试属性的存在,而不是变量,因此不能用于检测由定义的变量let
6

1
@amn对于的使用,答案仍然是正确的,var并且在这方面没有过时。但是,我添加了一条注释,概述了的用法以及let与的const区别var。感谢您的启发;我们一起崛起:)
Fred Gandt

1
@amn我重写了答案(希望是最后一次),以便更清楚地表明hasOwnProperty只能以规定的方式检查var变量的存在。对我来说没关系。
Fred Gandt

68

如何检查变量是否存在

这是一个相当不错的解决方案,用于测试变量是否存在并已初始化:

var setOrNot = typeof variable !== typeof undefined;

它最常与三元运算符结合使用,以在未初始化某些变量的情况下设置默认值:

var dark = typeof darkColor !== typeof undefined ? darkColor : "black";

封装问题

不幸的是,您不能简单地将检查封装在函数中。

您可能会想到做这样的事情:

function isset(variable) {
    return typeof variable !== typeof undefined;
}

但是,如果您调用例如,这将产生参考错误。isset(foo)并且foo尚未定义变量,因为您无法将不存在的变量传递给函数:

未捕获的ReferenceError:未定义foo


测试功能参数是否未定义

虽然我们的isset函数不能用于测试变量是否存在(出于上述原因),但它确实允许我们测试函数的参数是否未定义:

var a = '5';

var test = function(x, y) {
    console.log(isset(x));
    console.log(isset(y));
};

test(a);

// OUTPUT :
// ------------
// TRUE
// FALSE

即使没有将值for y传递给function test,我们的isset函数在这种情况下也可以完美运行,因为y在函数中test称为undefined值。


41

当您执行简单的分配和相关检查时,还有另一种简便的方法可以进行检查。只需使用条件(三元)运算符。

var values = typeof variable !== 'undefined' ? variable : '';

当您尝试使用引用变量的实例分配声明全局变量时,这也将有所帮助。

如果要检查变量,则不应为undefinednull。然后执行以下检查。

当声明变量时,如果您想检查该值,这甚至很简单: 它将执行undefinednull一起检查。

var values = variable ? variable : '';

答案是完全错误的。typeof变量始终返回字符串,因此永远不会为假。例如if typeof(booooo)is "undefined"then typeof(typeof boooooo)is "string"and typeof boooooo && truealways true。@ John-Slegers的答案与typeof差不多。
mpag

这是绝对正确的答案这是工作中的小提琴。我不知道您在谈论哪种情况。问题是关于检查变量的存在。
RajeshKdev

@mpag不要说错了。证明它。找到错误真的很容易,相反,您可以在这里提供良好的答案!!!如果答案完全错误,那么不检查我的答案就不会有28位程序员的投票。由于这里有许多著名的答案,所以他们本可以对此表示赞成,而不是这样。
RajeshKdev

其实第二段代码,是不是与上述条件相同。我以为人们会通过此行If you wanted to check variable shouldn't be undefined or null.,通过此注释,其清楚地说明,不执行变量声明检查来理解。这是检查变量值。
RajeshKdev

1
您的第二张支票将以0值失败
Fareed Alnamrouti

32

未声明(未定义)测试变量的简短方法是

if (typeof variable === "undefined") {
  ...
}

我发现它对于检测在浏览器外部运行的脚本(没有声明window变量)很有用。


这是可移植的“规范方式”吗?
杰森

3
错了 window.bar=undefined被定义并设置为一个值。您的答案无法检测到此变量与变量不存在之间的差异。如果您这样做this.hasOwnProperty('bar'),可能会奏效。
oligofren

此代码无效,您可以使用任何浏览器控制台进行验证
ha9u63ar

1
考虑一下const x = 0; (() => console.log(x, this.hasOwnProperty('x')))();x定义了变量,但返回了假...
user2878850

29

这取决于您是否只关心已定义变量,还是希望它具有有意义的值。

检查类型是否未定义将检查变量是否已定义。

=== null!== null仅检查变量的值是否准确null

== null!= null将检查值是否为undefinednull

if(value)将检查变量是undefinednull0,或一个空字符串。


12

最高答案是正确的,请使用typeof。

但是,我想指出的是,JavaScript undefined是可变的(出于某些不敬虔的原因)。因此,简单地进行检查varName !== undefined有可能不会总是按预期返回,因为其他库可能已更改为未定义。一些答案(@skalee的答案)似乎更喜欢不使用typeof,这可能会给您带来麻烦。

处理此问题的“旧”方法是将undefined声明为var,以抵消的任何可能的静音/覆盖undefined。但是,最好的方法仍然是使用,typeof因为它将忽略任何undefined其他代码的替代。尤其是如果您正在编写要在野外使用的代码,那么谁又知道该页面上可能还会运行什么……


1
这是有争议的,因为如果未定义varName,则varName !== undefined只会导致ReferenceError。的可变性undefined无关紧要。
Wutaz 2014年


1
在较新的Javascript版本undefined中,只读属性。但是要防弹,您可以使用typeof mvVar === typeof void 0。总是void 0返回undefined
kwarnke

11
if (typeof console != "undefined") {    
   ...
}

或更好

if ((typeof console == "object") && (typeof console.profile == "function")) {    
   console.profile(f.constructor);    
}

适用于所有浏览器


3
为什么您认为后者更好?
skalee

3
@skalee我同意后者更好。出于简单的原因,您需要在使用类型之前检查类型是否是您想要的类型。
Broxzier 2013年


9

为了促进辩论,如果我知道变量应该是字符串或我总是喜欢的对象if (!variable),请检查其是否虚假。这样可以带来更简洁的代码,例如:

if (typeof data !== "undefined" && typeof data.url === "undefined") {
    var message = 'Error receiving response';
    if (typeof data.error !== "undefined") {
        message = data.error;
    } else if (typeof data.message !== "undefined") {
        message = data.message;
    }
    alert(message); 
}

..可以简化为:

if (data && !data.url) {
  var message = data.error || data.message || 'Error receiving response';
  alert(message)
} 


这不是OP所要求的。如果data.url等于''您的解决方案,则将其视为未定义,而实际上它被定义为包含空字符串。
Demonblack

我同意这不是要求的内容,而您是正确的:空字符串''将被视为未定义。但是,我之所以发布此信息,是因为我认为它在不同答案之间引发的辩论中可能会很有用。在该示例以及其他许多情况下,如果实际存在内容,您只想打印一个字符串,因此可以利用JavaScript认为空字符串和未定义都是虚假的事实
de3

8

很难区分undefined和null。Null是一个值,您可以在要指示变量没有特定值时将其分配给该变量。未定义 是一个特殊值,它将是未分配变量的默认值。


var _undefined;
var _null = null;

alert(_undefined); 
alert(_null); 
alert(_undefined == _null);
alert(_undefined === _null);


1
内联显示每个警报的输出将很有帮助。
demisx

@demisx同意,但是为什么不建议编辑,而不建议编辑?该选项在那里是有原因的。有些人可能认为这很粗鲁。我认为这很有效-因此请自行编辑答案(待审核)。
Fred Gandt 2015年

1
@Fred-我查看了编辑历史记录,可以猜测为什么您的编辑被拒绝...而不是像demisx所建议的那样仅添加行以显示输出内容,而是您显着更改了Jith发布的内容。
史蒂芬·P

8

Null是JavaScript中的值并typeof null返回"object"

因此,如果您传递空值,则可接受的答案将不起作用。如果传递空值,则需要对空值进行额外检查:

if ((typeof variable !== "undefined") && (variable !== null))  
{
   // the variable is defined and not null
}

7

最强大的“是否已定义”检查是使用typeof

if (typeof elem === 'undefined')

如果您只是在检查已定义的变量以分配默认值,那么为了易于阅读,您通常可以这样做:

elem = elem || defaultElem;

通常使用起来很好,请参见:在javascript中设置默认值的惯用方式

还有一种使用typeof关键字的衬板:

elem = (typeof elem === 'undefined') ? defaultElem : elem;


7

为了检查变量是否已经声明/设置,我做了这个肮脏的把戏。

我什至没有找到一种将代码提取到函数中的方法eval

"use strict";

// var someVar;

var declared;
try {
  someVar;
  declared = true;
} catch(e) {
  declared = false;
}

if (declared) {
  console.log("someVar is declared; now has the value: " + someVar);
} else {
  console.log("someVar is not declared");
}

“将代码提取到函数”是什么意思?
Melab

7

这些答案(除了Fred Gandt解决方案之外)都是不正确或不完整的。

假设我需要variableName;携带一个undefined值,因此已经以某种方式声明了var variableName;它,这意味着它已经被初始化了;-如何检查它是否已经声明?

甚至更好-如何通过一次调用立即检查“ Book1.chapter22.paragraph37”是否存在,但不会出现引用错误?

我们通过使用功能最强大的JasvaScript运算符in来实现

"[variable||property]" in [context||root] 
>> true||false

在AJAX达到顶峰时期,我编写了一个方法isis()(后来称为isNS()),该方法可以确定名称空间是否存在,包括对属性名称(例如“ Book1.chapter22.paragraph37”)的深入测试等等。

但是,由于它以前已经发布过,并且由于它的重要性,它值得在单独的线程中发布,因此我不会在此处发布,而是会提供关键字(javascript + isNS),它将帮助您找到源代码,并附带所有必要的解释。


1
in操作仅测试了财产的存在,而不是所有的变量是性质- constlet声明是没有(const甚至没有,那么,变量)。
AMN

1
constlet用ECMAScript的2015年,这是3年多前发表,并通过通常的嫌疑人已经因为看到良好的通过和今天使用相当普遍地规范,我敢说- 有在Github上超过200万起“常量”的在JS文件中
AMN

是的,“变量”-完全正确。这就是为什么我评论您的答案的原因,指出您不能使用in运算符来一般地测试变量是否存在,因为“ const和let不是[properties]”- const实际上可以说引入了常量引用,例如另一方面,与变量引用相反let,它实际上引入了变量引用-换句话说,无论如何,它是一个变量,并且您的答案不正确,暗示您可以测试用定义的变量是否let存在通过使用in运算符-您不能。
amn

ECMAScript 6规范定义了JavaScript语言,而不是您或Web浏览器。这就是为什么它被称为规范 -它明确地指定了语言。您的答案充其量是过时的,最坏的情况是有意忽略了认为不相关的内容,而它却非常相关。引用链接的规范,“ let和const声明定义变量”。这些构造不能作为window对象的属性访问,我不知道如何使您更清楚。
6

答案并不涵盖所有变量情况。具体来说,它不涵盖使用let关键字定义的变量。这就是我所指出的。
上午

6

在问题概述的特定情况下,

typeof window.console === "undefined"

等同于

window.console === undefined

我更喜欢后者,因为它更短。

请注意,我们console仅在全局范围(window所有浏览器中的对象)中查找。在这种特殊情况下,这是可取的。我们不想console在其他地方定义。

@BrianKelley在他的出色回答中解释了技术细节。我仅添加了缺少的结论,并将其摘要为更易于阅读的内容。



2
假。后者在我的控制台中引发异常。
约翰·克特吉克

6

我根据对象使用两种不同的方式。

if( !variable ){
  // variable is either
  // 1. '';
  // 2. 0;
  // 3. undefined;
  // 4. null;
  // 5. false;
}

有时我不想将空字符串评估为falsey,所以我使用这种情况

function invalid( item ){
  return (item === undefined || item === null);
}

if( invalid( variable )){
  // only here if null or undefined;
}

如果需要相反的功能,则第一个实例中!variable变为!! variable,而在无效函数中===变为!=,并且函数名称更改为notInvalid。


5

我的偏好是typeof(elem) != 'undefined' && elem != null

无论您选择哪种方式,都可以考虑将支票放入这样的功能中

function existy (x) {
    return typeof (x) != 'undefined' && x != null;
}

如果您不知道变量已声明,则继续 typeof (x) != 'undefined' && x != null;

如果您知道变量已声明但可能不存在,则可以使用

existy(elem) && doSomething(elem);

您正在检查的变量有时可能是嵌套属性。您可以使用道具|| {}向下检查相关属性是否存在:

var exists = ((((existy(myObj).prop1||{}).prop2||{}).prop3||{})[1]||{}).prop4;

在每个属性之后使用(...'|| {}')。nextProp,以便缺少的属性不会引发错误。

或者你可以像 existy(o) && existy(o.p) && existy(o.p.q) && doSomething(o.p.q)


如果将其放在函数中,则是多余的。typeof (x) != 'undefined' && x != null等同于x != null何时x声明。
Ry-

3

这取决于实际情况。如果要检查某些可能在代码之外全局定义的东西(也许是jQuery),则需要:

if (typeof(jQuery) != "undefined")

(在那里不需要严格的相等性,typeof总是返回一个字符串。)但是,如果您对某个函数的参数进行了传递,则可能会始终将它们定义,但如果省略则将其定义为null。

function sayHello(name) {
    if (name) return "Hello, " + name;
    else return "Hello unknown person";
}
sayHello(); // => "Hello unknown person"

3

试着抓

如果根本没有定义变量,则可以使用try-catch块按如下所示检查此代码,而无需执行中断代码(无需进行use strict模式设置)

奖励:(参考其他答案)为什么=====来源)更清楚

如果(a == b)

在此处输入图片说明

如果(a === b)

在此处输入图片说明


1
仅供参考,放在生命游戏网格上的(a == b)并不是那么令人兴奋。
johnsnails

0

我很惊讶尚未提及...

这是使用 this['var_name']

使用此方法的好处是可以在定义变量之前使用它。

if (this['elem']) {...}; // less safe than the res but works as long as you're note expecting a falsy value
if (this['elem'] !== undefined) {...}; // check if it's been declared
if (this['elem'] !== undefined && elem !== null) {...}; // check if it's not null, you can use just elem for the second part

// these will work even if you have an improper variable definition declared here
elem = null; // <-- no var here!! BAD!

错了 window.bar=undefined被定义并设置为一个值。您的答案无法检测到此变量与变量不存在之间的差异。如果您这样做this.hasOwnProperty('bar'),可能会奏效。
oligofren
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.