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

哪种检查变量是否已初始化的方法更好/正确?(假设变量可以包含任何东西(字符串、int、对象、函数等))

if (elem) { // or !elem

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

if (elem != null) {
2280686 次浏览

你想要#0操作符。具体来说:

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

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

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

=== null!== null只会检查变量的值是否正好是null

== null!= null将检查值是undefined还是null

if(value)将检查变量是undefinednull0还是空字符串。

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

elem != null

与简单的if (elem)不同,它允许0falseNaN'',但拒绝nullundefined,使其成为一个很好的、通用的测试参数或对象属性的存在。


其他检查也不是不正确的,它们只是有不同的用途:

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

  • typeof elem == 'undefined'可用于指定的null对未初始化的变量或属性具有不同含义的情况。

    • 如果elem不是宣布(即没有var语句,不是window的属性,或者不是函数参数),这是不会抛出错误的唯一检查。在我看来,这是相当危险的,因为它允许拼写错误被忽视。为了避免这种情况,请参阅下面的方法。

undefined的严格比较也很有用:

if (elem === undefined) ...

但是,因为全局undefined可以被另一个值覆盖,所以最好在使用变量undefined之前在当前范围内声明它:

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

或:

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

这种方法的第二个优点是JS小型器可以将undefined变量减少到一个字符,每次节省几个字节。

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

var _undefined;var _null = null;
alert(_undefined);alert(_null);alert(_undefined == _null);alert(_undefined === _null);

这取决于具体情况。如果你正在检查一些可能在你的代码之外全局定义的东西(比如jQuery),你想要:

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

(这里不需要严格相等,typeof总是返回一个字符串。)但是如果你有一个函数的参数可能已经传递或可能没有传递,它们总是会被定义,但如果省略,则为null。

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

typeof运算符将检查变量是否真的未定义。

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

与其他运算符不同,typeof运算符在与未声明的变量一起使用时不会引发引用错误异常。

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

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

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

在JavaScript中,可以定义变量,但保留值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是全局对象的名称)。但是如果你像这样摆弄全局变量,你可能在浏览器中。主观上,使用'name' in window与使用window.name引用全局变量在风格上是一致的。将全局变量作为window的属性而不是变量访问,可以让你最大限度地减少代码中引用的未声明变量的数量(为了lint的好处),并避免全局变量被局部变量遮蔽的可能性。此外,如果全局变量让你毛骨悚然,你可能会觉得只有用这根相对较长的棍子触摸它们更舒服。

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

或者更好

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

适用于所有浏览器

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

typeof window.console === "undefined"

window.console === undefined

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

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

@BrianKelley在他的精彩回答中解释了技术细节。我只是添加了缺乏结论的内容,并将其消化成更容易阅读的内容。

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

然而,我想指出的是,在JavaScriptundefined中是可变的(出于某种不合理的原因)。所以简单地检查varName !== undefined有可能并不总是像你期望的那样返回,因为其他库可能已经更改为未定义。一些答案(@skalee的,例如),似乎更喜欢不使用typeof,这可能会给人带来麻烦。

处理这个问题的“旧”方法是声明未定义为var,以抵消undefined的任何潜在静音/覆盖。然而,最好的方法仍然是使用typeof,因为它会忽略其他代码对undefined的任何覆盖。特别是如果你正在编写在野外使用的代码,谁知道页面上还会运行什么…

您可以使用typeof运算符。

例如,

var dataSet;
alert("Variable dataSet is : " + typeof dataSet);

上面的代码片段将返回如下输出

变量dataSet是:未定义。

最健壮的“它定义了”检查是typeof

if (typeof elem === 'undefined')

如果您只是检查定义的变量以分配默认值,则为易于阅读的一行你可以经常这样做:

elem = elem || defaultElem;

它通常很好使用,请参阅:在javascript中设置默认值的惯用方法

还有一个使用typeof关键字的行:

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

检查#0#1"#2"

typeof答案过多的替代品;

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

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

因此,hasOwnProperty()方法,它

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

可用于确定是否

"varname"中的var已被全局声明为window的属性。

// Globally established, therefore, properties of windowvar foo = "whatever", // stringbar = false,      // boolbaz;              // undefined//  window.qux does not exist
console.log( [window.hasOwnProperty( "foo" ), // truewindow.hasOwnProperty( "bar" ), // truewindow.hasOwnProperty( "baz" ), // truewindow.hasOwnProperty( "qux" )  // false] );

hasOwnProperty()的伟大之处在于,在调用它时,我们不使用可能尚未声明的变量-这当然是问题的一半。

虽然不是总是完美理想解决方案,但在某些情况下,这只是工作!

备注

使用#0定义变量时,上述情况为真,而不是#1

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

var关键字不同,它全局定义变量,或本地定义整个函数,而不管块范围如何。

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

为了完整性:#0根据定义,常量实际上不是可变的(尽管它们的内容可以是可变的);更相关的是:

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

常量的值不能通过重新赋值而改变,并且不能重新声明。

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

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

关于hasOwnProperty()的可用性和使用:

对象继承的每个对象都继承了hasOwnProperty()方法。[…]与#1运算符不同,此方法不会检查对象的原型链。

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

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

有时我不想将空字符串评估为false sey,所以我使用这个案例

function invalid( item ){return (item === undefined || item === null);}
if( invalid( variable )){// only here if null or undefined;}

如果你需要相反的东西,那么在第一个实例中!变量变成了!!变量,在无效函数中===变成了!=并且函数名更改为NotIn的。

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

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

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

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

无论你选择什么,考虑将检查放入这样的函数中

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

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

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

existy(elem) && doSomething(elem);

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

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

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

或者你可以像existy(o) && existy(o.p) && existy(o.p.q) && doSomething(o.p.q)一样使用存在

为了促进辩论,如果我知道变量应该是字符串或对象,我总是更喜欢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)} 

当您执行简单的任务和相关检查时,还有另一种简短的方法来检查它。只需使用条件(三元)运算符。

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

当您尝试使用引用变量的实例赋值声明Global变量时,这也会很有帮助。

如果你想检查变量不应该是undefinednull。然后执行下面的检查。

当变量被声明时,如果你想检查值,这甚至很简单:它将同时执行#0和#1检查。

var values = variable ? variable : '';

如何检查变量是否存在

这是一个非常防弹的解决方案,用于测试变量是否存在并已初始化:

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尚未定义,因为您无法将不存在的变量传递给函数:

未捕获的引用错误:foo未定义


测试函数参数是否未定义

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

var a = '5';
var test = function(x, y) {console.log(isset(x));console.log(isset(y));};
test(a);
// OUTPUT :// ------------// TRUE// FALSE

即使没有将y的值传递给函数test,我们的isset函数在这种情况下也能完美工作,因为y在函数test中被称为undefined值。

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

我还没有找到一种方法来提取函数的代码,即使使用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");}

这些答案(除了Fred Gandt的解决方案)要么是不正确的,要么是不完整的。

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

或者更好-我如何立即检查“Book1.chapter22.paragraph37”是否存在一个调用,但不会引起引用错误?

我们通过使用最强大的JasvaScript运算符运算符来做到这一点:

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

在许多情况下,使用:

if (elem) { // or !elem

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

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

所以它会覆盖所有的情况,但总是有一些奇怪的情况,我们也想覆盖,例如,一个带空格的字符串,就像这个' ',这将在javascript中定义,因为它在字符串中有空格……例如,在这种情况下,你使用trim()添加一个检查,比如:

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

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

我创建了下面的图片来显示答案的简要说明:

未定义,空等

我很惊讶这还没有被提及…

这里有一些使用this['var_name']的附加变体

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

if (this['elem']) {...}; // less safe than the res but works as long as you're note expecting a falsy valueif (this['elem'] !== undefined) {...}; // check if it's been declaredif (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 hereelem = null; // <-- no var here!! BAD!

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

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

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

试捕

如果变量根本没有定义(例如:定义全局变量的外部库尚未加载-例如google map),您可以使用try-catch块在不中断代码执行的情况下检查这一点,如下所示(您不需要use strict模式)

try{notDefinedVariable;} catch(e) {console.log('detected: variable not exists');}
console.log('but the code is still executed');
notDefinedVariable; // without try-catch wrapper code stops here
console.log('code execution stops. You will NOT see this message on console');

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

如果(a==b)

在此处输入图片描述

如果(a==b)

在此处输入图片描述

您可以使用try… catch块,如下所示:

var status = 'Variable exists'
try {myVar} catch (ReferenceError) {status = 'Variable does not exist'}
console.log(status)

缺点是你不能把它放在一个函数中,因为它会抛出一个引用错误

function variableExists(x) {var status = truetry {x} catch (ReferenceError) {status = false}  
return status}
console.log(variableExists(x))

编辑:

如果您使用前端Javascript并且需要检查变量是否未初始化(var x = undefined将算作未初始化),您可以使用:

function globalVariableExists(variable) {if (window[variable] != undefined) {return true}  
return false}
var x = undefined
console.log(globalVariableExists("x"))
console.log(globalVariableExists("y"))
var z = 123
console.log(globalVariableExists("z"))

编辑2:

如果您需要检查当前范围中是否存在变量,您可以简单地将this以及字符串中包含的变量名称传递给函数:

function variableExists(variable, thisObj) {if (thisObj[variable] !== undefined) {return true}  
return false}
class someClass {constructor(name) {this.x = 99this.y = 99this.z = 99this.v = 99    
console.log(variableExists(name, this))}}
new someClass('x')new someClass('y')new someClass('z')new someClass('v')new someClass('doesNotExist')

if (variable === undefined) {}

工作正常,只检查未定义。

React JS+React JS+React JS+React JS+React中,事情有点复杂!这是因为它是一个编译环境,从#1(发布2018年10月1日))开始遵循ESLint的#0规则。这里的留档对任何对此问题感兴趣的人都很有帮助…

在JavaScript中,在ES6之前,变量和函数声明被提升到作用域的顶部,因此可以在代码中的正式声明之前使用标识符。

这个[ES6]的[新]规则将在遇到对尚未声明的标识符的引用时发出警告。

因此,虽然可以有一个undefined(或“未初始化”)变量,但在ReactJS中有一个未声明的变量而不关闭eslint规则是不可能

这可能非常令人沮丧——GitHub上有很多项目只是利用了ES6之前的标准;直接编译这些而不进行任何调整基本上是不可能的。

对于ReactJS来说,您可以使用eval()。如果您有未声明的变量,例如…

if(undeclaredvar) {...}

您可以简单地将此部分重写为…

if(eval('typeof undeclaredvar !== "undefined"')) {...}

比如说…

if(eval("false")) {console.log("NO!");}if(eval("true")) {console.log("YEAH!");}

对于那些将GitHub存储库导入ReactJS项目的人来说,这只是检查变量是否声明的唯一方法。在结束之前,我想提醒你如果使用不正确,则#0存在安全问题

您还可以在变量之前使用!!来检查它是否已定义。例如。

let dog = "woof";let chineseCat; // Undefined.console.log("1.");console.log(!!dog && !!chineseCat ? "Both are defined" : "Both are NOT defined");
chineseCat= "mao"; // dog and chineseCat are now defined.console.log("2.");console.log(!!dog && !!chineseCat ? "Both are defined" : "Both are NOT defined");

输出:

1.Both are NOT defined2.Both are defined

我更喜欢这种方法,因为它的准确性和简洁性:

var xif (x === void 0) {console.log(`x is undefined`)} else {console.log(`x is defined`)}

正如在其他评论和答案中提到的,undefined不能保证是未定义的。因为它不是关键字,所以它可以在全局范围以外的范围内重新定义为变量。这里有一个小例子来演示这种细微差别:

var undefined = 'bar'console.log(`In the global scope: ${undefined}`)
function foo() {var undefined = 'defined'var xif (x === undefined) {console.log(`x === undefined`)} else {console.log(`x !== undefined`)}if (x === void 0) {console.log(`x === void 0`)} else {console.log(`x !== void 0`)}}
foo()

有关兼容性,请参阅无效(IE5支持!?!!哇!)。

为了使if条件正常工作,我们必须使用关键字let来创建变量。

let name = undefined;if (name) {alert('valid')};

我想要类似的东西:一个检查变量是否有useful值的函数,其中0很有用,但空字符串、数组和对象不是(对我的应用程序来说)。根据各种答案和评论,我想出了isSet()函数,定义并测试如下;它返回true作为测试值的前半部分,返回false作为第二部分,这就是我想要和需要的:

let fn = [1234, "1234", 0, "0", [1,2], {name: "number"}, "", [], {}, null, NaN, undefined]
console.log(fn)const isSet = (val) => {switch (typeof val) {case 'number': return !isNaN(val); break; // as long as it is a number other than NaN....case 'string': return val.length > 0; break;case 'undefined': return false; break;case 'object':if (val === null) return false;else return Object.keys(val).length > 0;break;}}
for (index in fn) {const item = fn[index];console.log(`ind: ${index}; ${typeof item}; ${isSet(item)}`)}

结果(低于0):

[1234,'1234',0,'0',[ 1, 2 ],{ name: 'number' },'',[],{},null,NaN,undefined]ind: 0; number; trueind: 1; string; trueind: 2; number; trueind: 3; string; trueind: 4; object; trueind: 5; object; trueind: 6; string; falseind: 7; object; falseind: 8; object; falseind: 9; object; falseind: 10; number; falseind: 11; undefined; false