提问人:Samuel Liew 提问时间:2/25/2011 最后编辑:John SlegersSamuel Liew 更新时间:12/11/2022 访问量:2495784
JavaScript 检查变量是否存在(已定义/初始化)
JavaScript check if variable exists (is defined/initialized)
问:
哪种检查变量是否已初始化的方法更好/正确? (假设变量可以容纳任何内容(字符串、int、对象、函数等))
if (elem) { // or !elem
或
if (typeof elem !== 'undefined') {
或
if (elem != null) {
答:
您需要 typeof
运算符。具体说来:
if (typeof variable !== 'undefined') {
// the variable is defined
}
评论
这取决于你是否只关心变量是否已定义,或者你是否希望它有一个有意义的值。
检查类型是否未定义将检查变量是否已定义。
=== null
或者只会检查变量的值是否完全正确。!== null
null
== null
或将检查该值是否为 或 。!= null
undefined
null
if(value)
将检查变量是 、 、 还是空字符串。undefined
null
0
在大多数情况下,您会使用:
elem != null
与简单的 不同,它允许 、 和 ,但拒绝 或 ,使其成为对参数或对象属性存在的一个很好的、通用的测试。if (elem)
0
false
NaN
''
null
undefined
其他检查也没有不正确,它们只是有不同的用途:
if (elem)
:如果保证为对象,或者 、 等被视为“默认”值(因此等价于 或 )。elem
false
0
undefined
null
typeof elem == 'undefined'
可用于指定对象对未初始化的变量或属性具有不同含义的情况。null
- 这是唯一不会在未声明时抛出错误的检查(即没有语句,不是 的属性,或者不是函数参数)。在我看来,这是相当危险的,因为它允许错别字在不被注意的情况下溜走。为避免这种情况,请参阅以下方法。
elem
var
window
- 这是唯一不会在未声明时抛出错误的检查(即没有语句,不是 的属性,或者不是函数参数)。在我看来,这是相当危险的,因为它允许错别字在不被注意的情况下溜走。为避免这种情况,请参阅以下方法。
同样有用的是与以下各项的严格比较:undefined
if (elem === undefined) ...
但是,由于全局变量可以被另一个值覆盖,因此最好在使用变量之前在当前作用域中声明该变量:undefined
undefined
var undefined; // really undefined
if (elem === undefined) ...
艺术
(function (undefined) {
if (elem === undefined) ...
})();
这种方法的第二个优点是 JS 压缩器可以将变量减少到单个字符,每次都为您节省几个字节。undefined
评论
undefined
window.
void(0)
undefined
false
0
很难区分 undefined 和 null。Null 是要指示变量没有特定值时可以分配给变量的值。Undefined 是一个特殊值,它将是未赋值变量的默认值。
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
}
与其他运算符不同,该运算符在与未声明的变量一起使用时不会引发 ReferenceError 异常。typeof
但是,请注意,将返回 .我们必须小心避免将变量初始化为 的错误。为了安全起见,我们可以改用以下方法:typeof null
"object"
null
if (typeof variable === 'undefined' || variable === null) {
// variable is undefined or null
}
有关使用严格比较而不是简单相等的更多信息,请参阅:
JavaScript 比较中应使用哪个等于运算符 (== vs ===)?===
==
评论
some_object.a_member
variable != null
if (typeof variable == 'undefined')
在 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
}
当然,这是假设您在浏览器中运行(其中是全局对象的名称)。但是,如果你正在处理这样的全局变量,你可能在浏览器中。主观上,using 在风格上与 using 引用全局变量是一致的。通过将全局变量作为属性而不是变量访问,可以最大程度地减少在代码中引用的未声明变量的数量(为了进行 linting),并避免全局变量被局部变量遮蔽的可能性。此外,如果全局物让你的皮肤爬行,你可能会觉得只有用这根相对较长的棍子触摸它们会更舒服。window
'name' in window
window.name
window
评论
const
let
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。
然而,我想指出的是,在 JavaScript 中是可变的(出于某种不敬虔的原因)。因此,简单地进行检查有可能并不总是像您预期的那样返回,因为其他库可能已经更改了未定义。一些答案(例如@skalee)似乎更喜欢不使用 ,这可能会给人带来麻烦。undefined
varName !== undefined
typeof
处理此问题的“旧”方法是将 undefined 声明为 var,以抵消任何潜在的静音/覆盖。但是,最好的方法仍然是使用,因为它将忽略其他代码的任何覆盖。特别是如果你正在编写在野外使用的代码,谁知道页面上还能运行什么......undefined
typeof
undefined
评论
varName !== undefined
undefined
undefined
typeof mvVar === typeof void 0
void 0
undefined
您可以使用运算符。typeof
例如
var dataSet;
alert("Variable dataSet is : " + typeof dataSet);
上面的代码片段将返回如下输出
变量 dataSet 为 : undefined。
评论
最健壮的“是否定义”检查是使用 typeof
if (typeof elem === 'undefined')
如果您只是检查一个定义的变量来分配默认值,那么为了一个易于阅读的衬里 您通常可以这样做:
elem = elem || defaultElem;
通常使用起来没问题,请参阅:在 javascript 中设置默认值的惯用方法
还有这个使用 typeof 关键字的衬里:
elem = (typeof elem === 'undefined') ? defaultElem : elem;
检查是否窗口
。hasOwnProperty
(“变量名称
”)
过多答案的替代方案;typeof
在全局范围内使用语句声明的全局变量var varname = value;
可以作为 Window 对象的属性进行访问。
因此,该方法,其中hasOwnProperty()
返回一个布尔值,指示对象是否将指定的属性作为其自己的属性(而不是继承它)
可用于确定是否
“varname”的 a 已全局声明,即 是 的属性。var
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
which:
声明块作用域局部变量,可以选择将其初始化为值。
与关键字不同,关键字全局定义变量,或局部定义整个函数的变量,而不管块范围如何。
var
在程序和函数的顶层,与 不同,它不会在全局对象上创建属性。
let
var
为了完整起见:根据定义,常量
实际上不是可变的(尽管它们的内容可以是可变的);更相关的是:
与变量不同,全局常量不会成为窗口对象的属性。常量的初始值设定项是必需的;也就是说,您必须在声明它的同一语句中指定其值。
var
常量的值不能通过重新赋值而更改,也不能重新声明。
const 声明创建对值的只读引用。这并不意味着它所持有的值是不可变的,只是变量标识符不能重新赋值。
由于变量或常量从来都不是继承该方法的任何对象的属性,因此不能使用它来检查它们是否存在。let
const
hasOwnProperty()
关于 hasOwnProperty()
的可用性和使用:
从 Object 派生的每个对象都继承了该方法。[...]与
In
运算符不同,此方法不会检查对象的原型链。hasOwnProperty()
评论
true
window.hasOwnProperty('console')
var hop = "p";window.hasOwnProperty('hop')
typeof
let
window
hasOwnProperty
let
var
let
const
var
hasOwnProperty
var
根据对象的不同,我使用两种不同的方式。
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;
}
如果你需要相反的东西,那么首先!变量变为!!变量,在无效函数中 === 变为 !=,函数名称更改为 notInvalid。
Null 是 JavaScript 中的一个值,返回typeof null
"object"
因此,如果传递 null 值,则接受的答案将不起作用。如果传递 null 值,则需要为 null 值添加额外的检查:
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 likeexisty(o) && existy(o.p) && existy(o.p.q) && doSomething(o.p.q)
评论
typeof (x) != 'undefined' && x != null
x != null
x
为了促进辩论,如果我知道变量应该是字符串或对象,我总是更喜欢,所以检查它是否是假的。这可以带来更干净的代码,例如: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 : '';
此外,当您尝试使用引用变量的实例赋值来声明全局变量时,这将很有帮助。
如果要检查变量不应为 或 。然后执行以下检查。undefined
null
当声明变量时,如果你想检查值,这甚至是 Simple:它将同时执行 undefined
和 null
检查。
var values = variable ? variable : '';
评论
typeof(booooo)
"undefined"
typeof(typeof boooooo)
"string"
typeof boooooo && true
true
If you wanted to check variable shouldn't be undefined or null.
如何检查变量是否存在
这是一个非常无懈可击的解决方案,用于测试变量是否存在并已初始化:
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
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");
}
评论
function isDefined(x){...}
isDefined(myVar)
isDefined
try/catch
try/catch
这些答案(除了弗雷德·甘特的解决方案)都是不正确的或不完整的。
假设我需要 my 携带一个值,因此它已以一种方式声明,这意味着它已经初始化了;- 如何检查它是否已经声明?variableName;
undefined
var variableName;
或者更好的是 - 我如何通过一次调用立即检查“Book1.chapter22.paragraph37”是否存在,但不会产生引用错误?
我们通过使用最强大的 JasvaScript 运算符 in 运算符来做到这一点。
"[variable||property]" in [context||root]
>> true||false
评论
let
const
var
在许多情况下,使用:
if (elem) { // or !elem
会为你做这项工作...这将检查以下情况:
- undefined:如果值未定义,则为
undefined
- null:如果它为 null,例如,如果 DOM 元素不存在......
- 空字符串:
''
- 0:数字零
- NaN:不是一个数字
- 假
因此,它将涵盖所有情况,但总有一些奇怪的情况,我们也想涵盖这些情况,例如,带有空格的字符串,就像这个一样,这将在 javascript 中定义,因为它在字符串内有空格......例如,在本例中,您使用 trim() 再添加一个检查,例如:' '
if(elem) {
if(typeof elem === 'string' && elem.trim()) {
///
此外,这些检查仅适用于值,因为对象和数组在 Javascript 中的工作方式不同,空数组和空对象始终为 true。[]
{}
我创建了下面的图像来显示答案的简要说明:
评论
if(elem)
我很惊讶这还没有被提及......
以下是一些额外的变体,使用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')
测试变量未声明(不是未定义)的捷径是
if (typeof variable === "undefined") {
...
}
我发现它对于检测在浏览器外运行的脚本(没有声明变量)很有用。window
评论
window.bar=undefined
this.hasOwnProperty('bar')
const x = 0; (() => console.log(x, this.hasOwnProperty('x')))();
x
尝试捕捉
如果根本没有定义变量(例如:尚未加载定义全局变量的外部库 - 例如谷歌地图),您可以使用 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 )
if( a === b )
评论
你可以试一试......catch 块,如下所示:
var status = 'Variable exists'
try {
myVar
} catch (ReferenceError) {
status = 'Variable does not exist'
}
console.log(status)
缺点是你不能把它放在函数中,因为它会抛出一个 ReferenceError
function 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
function 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')
if (variable === undefined) {}
工作正常,只检查未定义。
在 ReactJS 中,事情有点复杂!这是因为它是一个编译环境,自 [email protected]
(2018 年 10 月 1 日发布)以来遵循 ESLint 的 no-undef
规则。这里的文档对任何对这个问题感兴趣的人都很有帮助......
在 JavaScript 中,在 ES6 之前,变量和函数声明被提升到作用域的顶部,因此可以在代码中的正式声明之前使用标识符。
这个 [ES6] 的 [新] 规则在遇到对尚未声明的标识符的引用时会发出警告。
因此,虽然可以有一个(或“未初始化”)变量,但在不关闭 eslint 规则的情况下,不可能在 ReactJS 中有一个未声明的变量。undefined
这可能非常令人沮丧——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 项目的人来说,这只是检查变量是否声明的唯一方法。在结束之前,我想提醒您,如果使用不当,eval()
存在安全问题。
我更喜欢这种方法,因为它的准确性和简洁性:
var x
if (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 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 中受支持?!!哇!
评论
typeof x === 'undefined'
undefined
undefined
typeof x === 'undefined'
undefined
为了使条件正常工作,我们必须使用关键字来创建变量。if
let
let name = undefined;
if (name) {
alert('valid')
};
我想要类似的东西:一个函数来检查变量是否有值,其中 0 很有用,但空字符串、数组和对象没有(对于我的应用程序)。根据各种答案和评论,我想出了下面定义和测试的功能;它返回测试值的前半部分和后半部分,这是我想要和需要的:useful
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)}`)
}
结果(下):node v16.16.0
[
1234,
'1234',
0,
'0',
[ 1, 2 ],
{ name: 'number' },
'',
[],
{},
null,
NaN,
undefined
]
ind: 0; number; true
ind: 1; string; true
ind: 2; number; true
ind: 3; string; true
ind: 4; object; true
ind: 5; object; true
ind: 6; string; false
ind: 7; object; false
ind: 8; object; false
ind: 9; object; false
ind: 10; number; false
ind: 11; undefined; false
评论
foo
typeof foo === 'undefined'
typeof foo === typeof undefined
undefined
hasOwnProperty('bar')
window
global