检查变量是否已初始化的哪种方法更好/正确? (假设变量可以保存任何东西(字符串、整数、对象、函数等))
if (elem) { // or !elem
或者
if (typeof elem !== 'undefined') {
或者
if (elem != null) {
foo
,则为 typeof foo === 'undefined'
或 typeof foo === typeof undefined
undefined
的变量。正确答案是这个:stackoverflow.com/a/36432729/772035
hasOwnProperty('bar')
的版本与其他版本没有相同的缺陷,但需要对 Node 进行一些调整(将 window
替换为 global
)。
你想要the typeof
operator。具体来说:
if (typeof variable !== 'undefined') {
// the variable is defined
}
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
}
有关使用严格比较 ===
而不是简单相等 ==
的详细信息,请参阅:
Which equals operator (== vs ===) should be used in JavaScript comparisons?
some_object.a_member
中的点符号来访问它们。
variable != null
它似乎也可以捕获“未定义”变量
在许多情况下,使用:
if (elem) { // or !elem
将为您完成工作!...这将检查以下情况:
undefined:如果该值未定义且未定义 null:如果为 null,例如,如果 DOM 元素不存在... 空字符串:'' 0:数字零 NaN:不是数字 false
所以它会涵盖所有情况,但总有一些奇怪的情况我们也想涵盖,例如,一个带空格的字符串,就像这个 ' '
一样,这将在 javascript 中定义,因为它有字符串中的空格...例如,在这种情况下,您可以使用 trim() 添加一项检查,例如:
if(elem) {
if(typeof elem === 'string' && elem.trim()) {
///
此外,这些检查仅针对 值,因为对象和数组在 Javascript 中的工作方式不同,空数组 []
和空对象 {}
始终为 true。
我创建了下面的图像以显示答案的简要说明:
https://i.stack.imgur.com/UTBcN.png
if(elem)
检查未定义(虽然它返回未定义错误)时,答案会产生误导,不是吗?
在 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
的属性而不是变量来访问,可以最大限度地减少代码中引用的未声明变量的数量(为了 linting),并避免全局变量被局部变量遮蔽的可能性。此外,如果全局变量让您的皮肤爬行,您可能会觉得只用这个相对较长的棍子触摸它们会更舒服。
const
或 let
变量
在大多数情况下,您会使用:
elem != null
与简单的 if (elem)
不同,它允许 0
、false
、NaN
和 ''
,但拒绝 null
或 undefined
,使其成为一个很好的通用测试参数是否存在,或对象的属性。
其他检查也不是不正确的,它们只是有不同的用途:
if (elem):如果 elem 被保证是一个对象,或者如果 false、0 等被认为是“默认”值(因此等同于 undefined 或 null),则可以使用。
typeof elem == 'undefined' 可以在指定的 null 对未初始化的变量或属性具有不同含义的情况下使用。如果没有声明 elem(即没有 var 语句,不是 window 的属性,或者不是函数参数),这是唯一不会引发错误的检查。在我看来,这是相当危险的,因为它会让错别字在不知不觉中溜走。为避免这种情况,请参阅以下方法。
如果没有声明 elem(即没有 var 语句,不是 window 的属性,或者不是函数参数),这是唯一不会引发错误的检查。在我看来,这是相当危险的,因为它会让错别字在不知不觉中溜走。为避免这种情况,请参阅以下方法。
与 undefined
进行严格比较也很有用:
if (elem === undefined) ...
但是,因为全局 undefined
可以用另一个值覆盖,所以最好在使用之前在当前范围内声明变量 undefined
:
var undefined; // really undefined
if (elem === undefined) ...
或者:
(function (undefined) {
if (elem === undefined) ...
})();
此方法的第二个优点是 JS 缩小器可以将 undefined
变量减少为单个字符,每次可以节省几个字节。
undefined
。我什至认为答案中不值得一提。可能是所有 Javascript 中唯一可接受的最差变量名。
window.
...这不是最好的方法。
void(0)
而不是 undefined
。
false
、0
等标识为无效值。
检查 window.hasOwnProperty("varname")
大量 typeof
答案的替代方案;
Global 变量在全局范围内用 var varname = value;
语句声明
可以作为窗口对象的属性访问。
因此,hasOwnProperty()
方法,它
返回一个布尔值,指示对象是否具有指定的属性作为它自己的属性(而不是继承它)可用于确定是否
“varname” 的 var
已被全局声明ie 是 window
的属性。
// 因此,全局建立窗口的属性 var foo = "whatever", // string bar = false, // bool baz; // undefined // window.qux 不存在 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 运算符不同,此方法不会检查对象的原型链。
true
(例如 window.hasOwnProperty('console')
或 var hop = "p";window.hasOwnProperty('hop')
)的工作示例简化答案标题。
typeof
答案都忽略了。
let
定义变量,其中这些变量不可用作 window
[或任何其他可用] 对象的属性。 hasOwnProperty
测试是否存在 properties,而不是变量,因此不能用于检测 let
定义的变量。
var
的答案仍然正确,并且在这方面没有过时。然而,我添加了一个注释,概述了 let
和 const
的使用与 var
的不同之处。感谢您的启发;我们一起崛起:)
hasOwnProperty
只能以规定的方式用于检查 var
变量的存在。我读起来没问题。
如何检查变量是否存在
这是一个非常安全的解决方案,用于测试变量是否存在并已初始化:
var setOrNot = typeof variable !== typeof undefined;
它最常与 ternary operator 结合使用以设置默认值,以防某个变量尚未初始化:
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
即使没有将 y
的值传递给函数 test
,我们的 isset
函数在这种情况下也能完美运行,因为 y
在函数 test
中被称为 undefined
值。
未声明(未定义)测试变量的简短方法是
if (typeof variable === "undefined") {
...
}
我发现它对于检测在浏览器外部运行的脚本很有用(没有声明 window
变量)。
window.bar=undefined
已定义并设置为一个值。您的答案无法检测到此变量与变量不存在之间的区别。如果您执行 this.hasOwnProperty('bar')
,它可能会奏效。
const x = 0; (() => console.log(x, this.hasOwnProperty('x')))();
。变量 x
已定义但返回 false...
当您执行简单的分配和相关检查时,还有另一种简便的检查方法。只需使用条件(三元)运算符。
var values = typeof variable !== 'undefined' ? variable : '';
当您尝试使用引用变量的实例赋值来声明全局变量时,这也会很有帮助。
如果你想检查变量不应该是 undefined
或 null
。然后执行以下检查。
声明变量时,如果要检查值,这甚至很简单: 它会同时执行 undefined
和 null
检查。
var values = variable ? variable : '';
typeof(booooo)
是 "undefined"
,则 typeof(typeof boooooo)
是 "string"
并且 typeof boooooo && true
始终是 true
。 @John-Slegers 的答案与 typeof 一样简略。
If you wanted to check variable shouldn't be undefined or null.
理解,通过这个注释,它清楚地说明,它不执行变量声明检查。那是检查变量值。
这取决于您是否只关心变量是否已定义,或者您是否希望它具有有意义的值。
检查类型是否未定义将检查变量是否已定义。
=== null
或 !== null
只会检查变量的值是否正好是 null
。
== null
或 != null
将检查值是 undefined
还是 null
。
if(value)
将检查变量是 undefined
、null
、0
还是空字符串。
试着抓
如果根本没有定义变量(例如:尚未加载定义全局变量的外部库 - 例如谷歌地图),您可以使用 try-catch 块检查这一点而不会中断代码执行,如下所示(您不需要 { 1}模式)
尝试{ notDefinedVariable; } catch(e) { console.log('检测到:变量不存在'); } console.log('但代码仍在执行');未定义变量; // 没有 try-catch 包装代码在这里停止 console.log('代码执行停止。你不会在控制台上看到这个消息');
奖励:(参考其他答案)为什么 ===
比 ==
更清楚(source)
如果(a == b)
https://i.stack.imgur.com/nkpj6.png
如果(a === b)
https://i.stack.imgur.com/7MeG6.png
最高的答案是正确的,使用 typeof。
然而,我想指出的是,在 JavaScript 中 undefined
是可变的(出于某种不虔诚的原因)。因此,简单地检查 varName !== undefined
可能不会总是按您的预期返回,因为其他库可能已更改为未定义。一些答案(一个是@skalee 的),似乎更喜欢不使用 typeof
,这可能会给一个人带来麻烦。
处理此问题的“旧”方法是将 undefined 声明为 var 以抵消 undefined
的任何潜在静音/覆盖。但是,最好的方法仍然是使用 typeof
,因为它会忽略其他代码对 undefined
的任何覆盖。特别是如果您正在编写用于野外使用的代码,谁知道页面上还可以运行什么......
varName !== undefined
只会导致 ReferenceError。 undefined
的可变性无关紧要。
undefined
是只读属性。但是,为了防弹,您可以使用 typeof mvVar === typeof void 0
。 void 0
总是返回 undefined
。
if (typeof console != "undefined") {
...
}
或更好
if ((typeof console == "object") && (typeof console.profile == "function")) {
console.profile(f.constructor);
}
适用于所有浏览器
为了有助于辩论,如果我知道变量应该是字符串或对象,我总是更喜欢 if (!variable)
,所以检查它是否虚假。这可以带来更干净的代码,例如:
if (typeof data !== "undefined" && typeof data.url === "undefined") { var message = '接收响应错误'; if (typeof data.error !== "undefined") { message = data.error; } else if (typeof data.message !== "undefined") { message = data.message; } 警报(消息); }
..可以简化为:
if (data && !data.url) { var message = data.error ||数据.消息 || '接收响应错误';警报(消息)}
''
您的解决方案会认为它未定义,而实际上它被定义为包含一个空字符串。
最强大的“是否已定义”检查是使用 typeof
if (typeof elem === 'undefined')
如果您只是检查定义的变量以分配默认值,那么为了便于阅读一个衬里,您通常可以这样做:
elem = elem || defaultElem;
它通常很好用,请参阅:Idiomatic way to set default value in javascript
还有一个使用 typeof 关键字的衬里:
elem = (typeof elem === 'undefined') ? defaultElem : elem;
Null 是 JavaScript 中的一个值,typeof null
返回 "object"
因此,如果您传递空值,接受的答案将不起作用。如果传递空值,则需要为空值添加额外检查:
if ((typeof variable !== "undefined") && (variable !== null))
{
// the variable is defined and not null
}
为了检查变量是否已被声明/设置,我做了这个肮脏的把戏。
即使使用 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");
}
function isDefined(x){...}
,然后调用 isDefined(myVar)
。但是没有办法安全地将一个可能未定义的变量传递给 isDefined
因为在变量可以传递给函数之前,它必须被评估,如果它不存在,那么它会抛出(外部try/catch
块,它是 in 函数)。您必须直接在 try/catch
块内评估变量,因此您不能将测试包装在函数中。
很难区分 undefined 和 null。 Null 是当您想指示变量没有特定值时可以分配给变量的值。 Undefined 是一个特殊值,它将是未分配变量的默认值。
var _undefined;
var _null = null;
alert(_undefined);
alert(_null);
alert(_undefined == _null);
alert(_undefined === _null);
您可以使用 typeof
运算符。
例如,
var dataSet;
alert("Variable dataSet is : " + typeof dataSet);
上面的代码片段将返回类似的输出
变量数据集是:未定义。
我根据对象使用两种不同的方式。
if( !variable ){
// variable is either
// 1. '';
// 2. 0;
// 3. undefined;
// 4. null;
// 5. false;
}
有时我不想将空字符串评估为假,所以我使用这种情况
function invalid( item ){
return (item === undefined || item === null);
}
if( invalid( variable )){
// only here if null or undefined;
}
如果您需要相反的情况,则在第一个实例中 !variable 变为 !!variable,并且在无效函数中 === 变为 != 并且函数名称更改为 notInvalid。
在问题中概述的特定情况下,
typeof window.console === "undefined"
等同于
window.console === undefined
我更喜欢后者,因为它更短。
请注意,我们仅在全局范围内查找 console
(在所有浏览器中都是 window
对象)。在这种特殊情况下,这是可取的。我们不希望在其他地方定义 console
。
@BrianKelley 在他的精彩回答中解释了技术细节。我只是添加了缺乏结论并将其消化成更易于阅读的内容。
我的偏好是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)
的存在
x
时,typeof (x) != 'undefined' && x != null
等效于 x != null
。
if (variable === undefined) {}
工作得很好,只检查未定义。
这取决于实际情况。如果您正在检查可能或可能未在您的代码之外全局定义的内容(可能像 jQuery),您想要:
if (typeof(jQuery) != "undefined")
(不需要严格相等,typeof 总是返回一个字符串。)但是如果你有一个函数的参数可能已经或可能没有被传递,它们总是被定义,但如果省略则为 null。
function sayHello(name) {
if (name) return "Hello, " + name;
else return "Hello unknown person";
}
sayHello(); // => "Hello unknown person"
您可以使用 try...catch 块,如下所示:
var status = '变量存在' try { myVar } catch (ReferenceError) { status = '变量不存在' } console.log(status)
一个缺点是你不能把它放在一个函数中,因为它会抛出一个 ReferenceError
函数 variableExists(x) { var status = true try { 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
以及包含在字符串中的变量的名称传递给函数:
函数 variableExists(variable, thisObj) { if (thisObj[variable] !== undefined) { return true } return false } class someClass { constructor(name) { this.x = 99 this.y = 99 this.z = 99 this .v = 99 console.log(variableExists(name, this)) } } new someClass('x') new someClass('y') new someClass('z') new someClass('v') new someClass('doesNotExist ')
这些答案(除了 Fred Gandt 解决方案)要么不正确,要么不完整。
假设我需要我的 variableName;
携带一个 undefined
值,因此它已以 var variableName;
之类的方式声明,这意味着它已经初始化; - 我如何检查它是否已经声明?
甚至更好 - 我如何通过一次调用立即检查“Book1.chapter22.paragraph37”是否存在,但不会引发参考错误?
我们通过使用最强大的 JasvaScript 运算符 in 运算符来做到这一点:
"[variable||property]" in [context||root]
>> true||false
我很惊讶这还没有被提及...
这里有几个使用 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')
,它可能会奏效。
我更喜欢这种方法,因为它的准确性和简洁性:
var x if (x === void 0) { console.log(`x is undefined`) } else { console.log(`x is defined`) }
正如其他评论和答案中提到的那样,不能保证 undefined
是未定义的。因为它不是关键字,所以它可以在全局范围以外的范围内重新定义为变量。这是一个展示这种细微差别的小例子:
var undefined = 'bar' console.log(`在全局范围内:${undefined}`) function foo() { var undefined = 'defined' var x if (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()
请参阅 void 了解兼容性(在 IE5 中受支持!?!!哇!)。
在 ReactJS 中,事情有点复杂!这是因为它是一个编译环境,自 react-scripts@2.0.3
(发布 Oct. 1st, 2018))遵循 ESLint's no-undef
规则。此处的文档对任何对此问题感兴趣的人都有帮助...
在 JavaScript 中,在 ES6 之前,变量和函数声明被提升到作用域的顶部,因此可以在代码中的正式声明之前使用标识符....这个 [new] rule [of 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 项目的人来说,这只是检查变量是否被声明的唯一方法。在结束之前,我想提醒您there are security issues with eval()
if use incorrectly。
为了使 if
条件正常工作,我们必须使用关键字 let
来创建变量。
let name = undefined;
if (name) {
alert('valid')
};