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


检查变量是否被初始化的哪种方法是更好的还是正确的? (假设变量可以容纳任何东西(string,int,object,function等))

if (elem) { // or !elem

要么

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

要么

if (elem != null) {


Answers


你想要typeof运算符 。 特别:

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
}

有关使用严格比较===而不是简单的等式==更多信息,请参阅:
应该在JavaScript比较中使用哪个等于运算符(== 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使用'name' in window与使用window.name来引用全局window.name在风格上是一致的。 将全局变量作为window属性而不是变量访问,可以使代码中引用的未声明变量的数量最小化(为了linting),并避免全局被局部变量覆盖的可能性。 另外,如果全局变形使你的皮肤爬行,你可能会感觉更舒服,只有用这个比较长的棒才能触摸它们。




在大多数情况下,你会使用:

elem != null

不像一个简单的if (elem) ,它允许0falseNaN'' ,但是拒绝null或者undefined ,这是对一个参数或者一个对象属性的一个很好的通用测试。

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

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

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

    • 这是唯一的检查, 不会抛出一个错误,如果elem没有声明 (即没有var声明,不属于window ,或不是一个函数参数)。 在我看来,这是相当危险的,因为它可以让人误入歧途。 为了避免这种情况,请参阅下面的方法。

另外有用的是严格比较undefined

if (elem === undefined) ...

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

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

要么:

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

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




如何检查一个变量是否存在

这是一个很好的解决方案,用于测试变量是否存在并被初始化:

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没有被定义,因为你不能把一个不存在的变量传递给一个函数:

Uncaught 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值。




检查一个对象hasOwnProperty()

另一种类型的答案,是使用hasOwnProperty()当然检查一个对象(几乎所有在JS)有一个属性, 变量(等)。

hasOwnProperty()方法返回一个布尔值,指示对象是否具有指定的属性作为自己的(未继承)属性。

每个Object的继承对象都继承hasOwnProperty()方法。 此方法可用于确定对象是否具有指定的属性作为该对象的直接属性; 与in运算符不同,此方法不检查对象的原型链。

// 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
    { foo: [], bar: 0 }.hasOwnProperty( "bar" ) // true
] );

hasOwnProperty()在于,在调用它的时候,我们不使用一个可能还没有定义的变量 - 这当然是第一个问题的一半。

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




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

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

当你尝试用引用变量的实例分配来声明全局变量时,这也是有帮助的。

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

当变量被声明时,如果你想检查值,这甚至是简单的: 它将执行undefinednull检查在一起。

var values = variable ? variable : '';



未定义,布尔,字符串,数字功能

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

}

对象,数组

if( foo instanceof Array ) { 

}



这取决于你是否在意这个变量已经被定义,或者你是否希望它有一个有意义的值。

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

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

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

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




在许多情况下,使用:

if (elem) { // or !elem

会为你做这个工作...这将检查下面这些情况:

  1. undefined :如果这个值没有被定义,并且是undefined
  2. null :如果它为空,例如,如果DOM元素不存在...
  3. 空字符串''
  4. 0 :数字零
  5. NaN :不是一个数字

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

if(elem) {

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

我也创建下面的图像来快速简要回答一下答案:




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

然而,我想指出的是,在JavaScript中, undefined是可变的(出于某些不合理的原因)。 所以简单地做一个varName !== undefined的检查有可能不会总是如你所期望的那样返回,因为其他库可能已经改变了undefined。 一些答案(@ skalee的,一个),似乎更喜欢不使用typeof ,这可能会让人陷入困境。

处理这个“旧”的方法是宣布未定义为一个变量来抵消任何潜在的静音/ undefined 。 但是,最好的方法仍然是使用typeof因为它会忽略任何其他代码的undefined重写。 特别是如果你正在编写野外使用的代码,谁知道什么可以在网页上运行...




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

或更好

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

适用于所有浏览器




区分undefined和null是很困难的。 Null是一个值,当你想表示变量没有特殊的值时,你可以赋值给一个变量。 Undefined是一个特殊值,它是未赋值变量的默认值。


var _undefined;
var _null = null;

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




最强大的“是它定义”检查与typeof

if (typeof elem === 'undefined')

如果你只是检查一个定义的变量来指定一个默认的,为了方便阅读一个班轮,你可以经常这样做:

elem = elem || defaultElem;

这通常很好用,请参阅: javascript中设置默认值的习惯用法

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

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



你可以使用typeof运算符。

例如,

var dataSet;

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

上面的代码片段将返回类似的输出

变量dataSet是:undefined。




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

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

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



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

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

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

我们通过使用最强大的JasvaScript运算符( in运算符)来实现:

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

在AJAX高峰流行的时候,我写了一个方法(后来命名)是NS(),它能够确定名称空间是否存在,包括属性名称的深度测试,如“Book1.chapter22.paragraph37”等等。

但由于它以前已经发表,因为它的重要性值得在一个单独的线程发表,我不会在这里发表,但会提供关键字( JavaScript + ISNS ),这将帮助您找到源代码,支持所有的必要的解释。




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

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);

你正在检查的变量有时可能是一个嵌套的属性。 你可以使用prop || {}去检查存在问题的财产线:

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

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

或者你可以使用existy existy(o) && existy(op) && existy(opq) && doSomething(opq)




这取决于实际情况。 如果你正在检查的东西可能或可能不是全局定义在你的代码之外(如jQuery),你想要的:

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

(不需要严格的平等,typeof总是返回一个字符串。)但是如果你有一个函数的参数可能被传递或者不被传递,它们总是被定义的,但是如果被省略,则为空。

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



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



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

if( !variable ){
  // variable is either
  // 1. empty string i.e. '';
  // 2. Integer 0;
  // 3. undefined;
  // 4. null;
}

有时我不想评估一个空字符串为falsey,那么我使用这种情况

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

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

如果你需要相反的话,那么在第一个实例中变量变成!!变量,并且在无效函数===成为!=而函数名称变为notInvalid。




多一点功能和易于使用:

function exist(obj)
{
    return (typeof obj !== 'undefined');
}

如果存在,函数将返回true ,否则返回false




如果你想要定义的块做某事然后使用这个

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

如果你想要未定义的块做某事或分配或定义变量,那么使用这个

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



那么简单一点:

if(!!variable){
  //the variable is defined
}



要检查一个变量是否已被声明/设置,我做了这个肮脏的伎俩。

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



不确定这是否有帮助,我需要检查是否在运行相关的脚本之前检测到页面上定义的Var是否被拾取,下面的工作适合我。

if (window.myvar) { // run scripts here }

这是一个简单,但罚款一个或喜欢。




我在上面的答案中看不到这个,所以我想在这里推荐一下。

function isDefined(x) { return !!x }

if( isDefined(x) ) {
    //The variable is defined
}

!x将返回true如果x是nullundefined ,那么!! x只会返回true,如果f既不是undefined也是null。

我意识到这也是空的情况,但这是公正的警告。