JQuery/Javascript: 检查变量是否存在

79

可能是重复问题:
如何检查JavaScript中的变量是否已定义?
在JavaScript中,有没有标准函数可以检查null、undefined或空变量?

我的脚本由两部分组成。

第一部分设置一个变量:

var pagetype = "textpage";
第二部分是一个简单的if语句:
if(pagetype == "textpage") {
//do something
};

现在是第二部分,if语句,在我的网站所有页面上都会显示。但是第一部分,声明变量的部分,只会出现在我的一些页面上。

在没有该变量的页面上,我自然会得到这个错误:

Uncaught ReferenceError: pagetype is not defined
所以我的问题是:是否有一种使用JavaScript或JQ来检测变量是否存在的方法(不仅仅是它是否被分配数据)?
我想我只需要使用另一个if语句,例如:
if ("a var called pagetypes exists")....

1
typeof,window.hasOwnProperty,if(var x)... - John Dvorak
1
你会得到很多关于这个问题的答案,其中大部分我认为都是正确的...我投了这个问题的赞成票,因为看到一个“适当”的错误处理尝试是很好的。 - Zak
6个回答

136

我怀疑在 Stack Overflow 上有很多这样的答案,但是这里是你要的:

if ( typeof pagetype !== 'undefined' && pagetype == 'textpage' ) {
  ...
}

10
@JanDvorak: 我相当确定那不是有效的JS代码... - elclanrs
2
这并不测试 pagetype 是否已被声明,只是测试其值的类型是否未定义。 - RobG
1
问题特别要求测试一个变量是否已经被声明,即使它没有被赋值。因此,即使只声明了var pagetype;而没有给它赋值,if语句也应该返回true。目前它并没有这样做。 - Bruno
我认为在2021年我们应该使用undefined而不是'undefined' - Fauzan Edris
@FauzanEdris 在2021年这仍然是正确的答案。undefined实际上只是一个值为undefined的变量。检查typeof'undefined'相比不仅检查值,还检查_存在性_。 - elclanrs
显示剩余3条评论

22
您可以使用 typeof:
if (typeof pagetype === 'undefined') {
    // pagetype doesn't exist
}

9

对于您的情况,以及99.9%的其他情况,elclanrs的答案是正确的。

但是因为undefined是一个有效的值,如果有人测���未初始化的变量,则会出现问题。

var pagetype; //== undefined
if (typeof pagetype === 'undefined') //true

唯一可靠的确定变量是否存在的方法是捕获异常;

var exists = false;
try { pagetype; exists = true;} catch(e) {}
if (exists && ...) {}

但我绝不会这样写。

1
如果您给答案投反对票,请证明答案是错误的。 - jermel
如果(typeof pagetype === 'undefined')//false - elclanrs
1
叹气...打错字了 :-),尽管它仍然评估为true。 - jermel
其实你说得对。我会在可以的时候点赞。 - elclanrs
'prop' in this怎么样?为什么这还不够? - Bart Calixto
它并不检查所有范围...试试这个...var o = { exists: function(){ var prop = 'here'; console.log('prop' in this); }}; o.exists(); - jermel

4

为了测试存在性,有两种方法。

a. "property" in object

这种方法会检查原型链中是否存在该属性。

b. object.hasOwnProperty( "property" )

这种方法不会沿着原型链向上检查属性的存在性,它必须存在于你调用该方法的对象中。

var x; // variable declared in global scope and now exists

"x" in window; // true
window.hasOwnProperty( "x" ); //true

如果我们使用以下表达式进行测试,它将返回false。
typeof x !== 'undefined'; // false

1
只有在全局范围内定义了“pagetype”时,此方法才有效。 - Paul S.
2
这仅适用于浏览器,例如Node.js则不行。尝试使用“this”而不是“window”。 - John Dvorak
@Bruno——你的方法a没有检查变量的存在性,方法b只对全局属性有用,其中一些可能是变量。 - RobG
全局变量不是用户定义的属性,而是添加到全局对象中的吗?但是,你说得对。 - Bruno
@Bruno 如果你在函数内部声明一个变量,那么它不会被添加到全局对象中... - Ian

3

除了使用try..catch来引发错误,以确定变量是否已声明外,无法确定变量是否已声明。测试如下:

if (typeof varName == 'undefined') 

该代码并不告诉你varName是否在作用域内,只是测试typeof返回undefined。例如:

var foo;
typeof foo == 'undefined'; // true
typeof bar == 'undefined'; // true

在上面的代码中,你不能确定foo被声明了而bar没有。你可以使用in来测试全局变量:
var global = this;
...
'bar' in global;  // false

然而,全局对象是您唯一可以访问的变量对象*,您无法访问任何其他执行上下文的变量对象。

解决方案是始终在适当的上下文中声明变量。

  • 全局对象实际上并不是变量对象,它只有与全局变量匹配并提供对它们的访问权限的属性,因此它只是一个看起来像变量对象的东西。

1
又是一个不明白为什么的“路过踩票”者的案例。 - RobG

3

在每个条件语句之前,您可以执行以下操作:

var pagetype = pagetype || false;
if (pagetype === 'something') {
    //do stuff
}

假设您不介意将pagetype定义为副作用,当然。 - John Dvorak
这只是一种方法。这样做至少会默认为未满足条件,如果它不存在的话。 - Jason
如果 pagetype 具有 falsey 值,如 "", 0 等,则此方法根本无法工作。如果已经声明并将 pagetype 设置为这些值之一,您会用 false 覆盖它,并导致不正确的比较。 - Ian
实际上不会。如果您希望在条件不匹配特定字符串时失败(正如OP的情况),那么""0false都是等效的。 - Jason

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