javascript - undefined判断 - undefined什么意思




检测未定义的对象属性 (20)

' if(window.x){} '是错误安全的

你最想要的if (window.x) 。 即使未声明var x;var x; ),此检查也是安全的 - 浏览器不会抛出错误。

示例:我想知道我的浏览器是否支持History API

if (window.history) {
    history.call_some_function();
}

这是如何工作的:

window是一个将所有全局变量保存为其成员的对象,尝试访问不存在的成员是合法的。 如果x尚未声明或尚未设置,则window.x将返回undefined 。 当if()计算它时, undefined会导致false

检查JavaScript中的对象属性是否未定义的最佳方法是什么?


从相关问题中删除我的answer 如何在JavaScript中检查“未定义”?

具体到这个问题,请参阅someObject.<whatever>测试用例。

一些场景说明了各种答案的结果: http://jsfiddle.net/drzaus/UVjM4/http://jsfiddle.net/drzaus/UVjM4/

(请注意, in测试包装中使用var for test会有所不同)

代码参考:

(function(undefined) {
    var definedButNotInitialized;
    definedAndInitialized = 3;
    someObject = {
        firstProp: "1"
        , secondProp: false
        // , undefinedProp not defined
    }
    // var notDefined;

    var tests = [
        'definedButNotInitialized in window',
        'definedAndInitialized in window',
        'someObject.firstProp in window',
        'someObject.secondProp in window',
        'someObject.undefinedProp in window',
        'notDefined in window',

        '"definedButNotInitialized" in window',
        '"definedAndInitialized" in window',
        '"someObject.firstProp" in window',
        '"someObject.secondProp" in window',
        '"someObject.undefinedProp" in window',
        '"notDefined" in window',

        'typeof definedButNotInitialized == "undefined"',
        'typeof definedButNotInitialized === typeof undefined',
        'definedButNotInitialized === undefined',
        '! definedButNotInitialized',
        '!! definedButNotInitialized',

        'typeof definedAndInitialized == "undefined"',
        'typeof definedAndInitialized === typeof undefined',
        'definedAndInitialized === undefined',
        '! definedAndInitialized',
        '!! definedAndInitialized',

        'typeof someObject.firstProp == "undefined"',
        'typeof someObject.firstProp === typeof undefined',
        'someObject.firstProp === undefined',
        '! someObject.firstProp',
        '!! someObject.firstProp',

        'typeof someObject.secondProp == "undefined"',
        'typeof someObject.secondProp === typeof undefined',
        'someObject.secondProp === undefined',
        '! someObject.secondProp',
        '!! someObject.secondProp',

        'typeof someObject.undefinedProp == "undefined"',
        'typeof someObject.undefinedProp === typeof undefined',
        'someObject.undefinedProp === undefined',
        '! someObject.undefinedProp',
        '!! someObject.undefinedProp',

        'typeof notDefined == "undefined"',
        'typeof notDefined === typeof undefined',
        'notDefined === undefined',
        '! notDefined',
        '!! notDefined'
    ];

    var output = document.getElementById('results');
    var result = '';
    for(var t in tests) {
        if( !tests.hasOwnProperty(t) ) continue; // bleh

        try {
            result = eval(tests[t]);
        } catch(ex) {
            result = 'Exception--' + ex;
        }
        console.log(tests[t], result);
        output.innerHTML += "\n" + tests[t] + ": " + result;
    }
})();

结果:

definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined

使用:

if (typeof something === "undefined") {
    alert("something is undefined");
}

如果具有某些属性的对象变量可以使用如下所示的相同内容:

if (typeof my_obj.someproperties === "undefined"){
    console.log('the property is not available...'); // print into console
}

同样的事情可以写得更短:

if (!variable){
    //do it if variable is Undefined
}

要么

if (variable){
    //do it if variable is Defined
}

在JavaScript中有null并且未定义 。 它们有不同的含义。

  • undefined表示尚未定义变量值; 不知道它的价值是多少。
  • null表示定义变量值并设置为null(没有值)。

Marijn Haverbeke在他的免费在线书“ Eloquent JavaScript ”(强调我的)中说:

还有一个类似的值null,其含义是“此值已定义,但它没有值”。 undefined和null之间的意义差异主要是学术性的,通常不是很有趣。 在实际程序中,通常需要检查某些东西是否“有价值”。 在这些情况下,可以使用表达式== undefined,因为即使它们不是完全相同的值,null == undefined也会产生true。

所以,我想检查某些内容是否未定义的最佳方法是:

if (something == undefined)

希望这可以帮助!

编辑:为了响应您的编辑,对象属性应该以相同的方式工作。

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined

如果你这样做

if (myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

当变量myvar不存在时它会失败,因为没有定义myvar,所以脚本被破坏而且测试没有效果。

由于窗口对象在函数外部具有全局范围(默认对象),因此声明将“附加”到窗口对象。

例如:

var myvar = 'test';

全局变量myvarwindow.myvarwindow ['myvar']相同

为避免在存在全局变量时测试错误,最好使用:

if(window.myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

变量确实存在的问题无关紧要,其值不正确。 否则,使用undefined初始化变量是愚蠢的,最好使用值false来初始化。 当您知道所声明的所有变量都使用false初始化时,您只需检查其类型或依赖于!window.myvar来检查它是否具有正确/有效的值。 因此,即使未定义变量,对于myvar = undefinedmyvar = falsemyvar = 0 !window.myvar也是相同的。

当您需要特定类型时,请测试变量的类型。 为了加快测试条件,您最好:

if( !window.myvar || typeof window.myvar != 'string' )
{
    alert('var does not exists or is not type of string');
}

当第一个和简单条件为真时,解释器会跳过下一个测试。

最好使用变量的实例/对象来检查它是否具有有效值。 它更稳定,是一种更好的编程方式。

(y)的


如果您使用的是Angular:

angular.isUndefined(obj)
angular.isUndefined(obj.prop)

Underscore.js:

_.isUndefined(obj) 
_.isUndefined(obj.prop) 

尽管在这里被许多其他答案强烈推荐,但typeof 是一个糟糕的选择 。 它永远不应该用于检查变量是否具有undefined的值,因为它作为undefined值和变量是否存在的组合检查。 在绝大多数情况下,您知道变量何时存在,并且如果您在变量名称或字符串文字'undefined'中输入拼写错误,则typeof将仅引入静默失败的可能性。

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

因此,除非你正在进行特征检测²,否则给定名称是否在范围内是不确定的(比如检查类型typeof module !== 'undefined'作为特定于CommonJS环境的代码中的一步), typeof在使用时是一个有害的选择在变量上,正确的选项是直接比较值:

var foo = …;

if (foo === undefined) {
    ⋮
}

一些常见的误解包括:

  • 读取“未初始化”变量( var foo )或参数( function bar(foo) { … } ,称为bar() )将失败。 这根本不是真的 - 没有显式初始化的变量和未给定值的参数总是变得undefined ,并且始终在范围内。

  • undefined可以被覆盖。 这还有很多。 undefined不是JavaScript中的关键字。 相反,它是具有Undefined值的全局对象上的属性。 但是,从ES5开始,此属性是只读不可配置的 。 没有现代浏览器允许更改undefined属性,并且从2017年开始就是这种情况很长一段时间。 缺乏严格模式也不会影响undefined的行为 - 它只是使undefined = 5类的语句不做任何事情而不是抛出。 但是,由于它不是关键字,因此可以声明名称为undefined变量,并且可以更改这些变量,从而形成这种曾经常见的模式:

    (function (undefined) {
        // …
    })()
    

    比使用全局undefined 危险。 如果你必须与ES3兼容,用void 0替换undefined - 不要求助于typeof 。 ( void始终是一元运算符,其值为任何操作数的Undefined值。)

通过变量如何解决问题,是时候解决实际问题了:对象属性。 没有理由对对象属性使用typeof 。 关于特征检测的早期例外在这里不适用 - typeof仅对变量有特殊行为,而引用对象属性的表达式不是变量。

这个:

if (typeof foo.bar === 'undefined') {
    ⋮
}

总是完全等同于这个:

if (foo.bar === undefined) {
    ⋮
}

并考虑上面的建议,以避免让读者混淆你为什么使用typeof ,因为使用===检查相等性是最有意义的,因为它可以重构为稍后检查变量的值,并且因为它只是看起来更好看,所以你也应该总是使用=== undefined

在涉及对象属性时要考虑的其他事项是你是否真的想要检查undefined 。 给定的属性名称可以在对象上不存在(在读取时产生undefined的值),在对象本身上显示undefined的值,在对象的原型上显示值undefined ,或者出现在具有undefined任何一个上值。 'key' in obj将告诉你一个键是否在对象的原型链上的任何地方,而Object.prototype.hasOwnProperty.call(obj, 'key')将告诉你它是否直接在对象上。 我不会在这个关于原型和使用对象作为字符串键映射的答案中详细说明,因为它主要是为了对抗其他答案中的所有不良建议,而不管原始问题的可能解释如何。 在MDN上阅读对象原型以获取更多信息!

¹异常选择示例变量名称? 这是来自Firefox的NoScript扩展的真正死代码。
²不要以为不知道一般情况下不知道范围是什么。 滥用动态范围造成的奖金漏洞: Project Zero 1225
³再次假设一个ES5 +环境, undefined指的是全局对象的undefined属性。 否则替换void 0


我不确定使用===typeof的起源来自哪里,并且作为一种惯例,我看到它在许多库中使用,但是typeof运算符返回一个字符串文字,我们知道这个,所以你为什么要这样做还想打字检查一下吗?

typeof x;                      // some string literal "string", "object", "undefined"
if (typeof x === "string") {   // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") {    // sufficient

我没有看到(希望我没有错过)任何人在物业前检查物体。 所以,这是最短和最有效的(虽然不一定是最清楚的):

if (obj && obj.prop) {
  // Do something;
}

如果obj或obj.prop未定义,null或“falsy”,则if语句将不执行代码块。 这通常是大多数代码块语句(在JavaScript中)中所需的行为。


这是什么意思: “未定义的对象属性”

实际上它可能意味着两件完全不同的东西! 首先,它可以表示从未在对象中定义的属性,其次,它可以表示具有未定义值属性 。 我们来看看这段代码:

var o = { a: undefined }

oa undefined? 是! 它的价值是不确定的。 ob undefined? 当然! 根本没有属性'b'! 好的,现在看看两种情况下不同方法的表现如何:

typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

我们可以清楚地看到typeof obj.prop == 'undefined'obj.prop === undefined是等价的,并且它们不区分这些不同的情况。 'prop' in obj可以在没有定义属性时检测到这种情况,并且不会注意可能未定义的属性值。

那么该怎么办?

1)您想知道属性是否由第一个或第二个含义(最典型的情况)定义。

obj.prop === undefined // IMHO, see "final fight" below

2)您只想知道对象是否具有某些属性而不关心其值。

'prop' in obj

笔记:

  • 您无法同时检查对象及其属性。 例如,此xa === undefined或此类型的typeof xa == 'undefined'引发ReferenceError: x is not defined如果typeof xa == 'undefined' ReferenceError: x is not defined x。
  • 变量undefined是一个全局变量(实际上它在浏览器中是window.undefined )。 它自ECMAScript第1版以来一直受到支持,因此ECMAScript 5 只读它。 所以在现代浏览器中,它不能被重新定义为真实,因为许多作者喜欢用我们来吓唬我们,但对于旧浏览器来说这仍然是正确的。

最后的战斗: obj.prop === undefined vs typeof obj.prop == 'undefined'

obj.prop === undefined

  • 它有点短,看起来更漂亮
  • 如果你拼错了undefined ,JavaScript引擎会给你一个错误

obj.prop === undefined

  • undefined可以在旧浏览器中覆盖

多种类型的typeof obj.prop == 'undefined'

  • 它真的很普遍! 它适用于新旧浏览器。

typeof obj.prop == 'undefined'

  • 'undefned'拼写错误 )这里只是一个字符串常量,所以如果你像我刚才拼错了那么JavaScript引擎无法帮助你。

更新(对于服务器端JavaScript):

Node.js支持全局变量undefined as global.undefined (它也可以在没有'global'前缀的情况下使用)。 我不知道服务器端JavaScript的其他实现。


这是我的情况:

我正在使用REST调用的结果。结果应该从JSON解析为JavaScript对象。

我需要保护一个错误。如果用户指定args错误,其余调用的args是不正确的,则其余的调用基本上是空的。

虽然使用这篇文章来帮助我防范这个,但我尝试了这个。

if( typeof restResult.data[0] === "undefined" ) { throw  "Some error"; }

对于我的情况,如果restResult.data [0] ===“对象”,那么我可以安全地开始检查其余的成员。如果未定义,则抛出上述错误。

我所说的是,就我的情况而言,本文上面的所有建议都没有用。我不是说我是对的,每个人都错了。我根本不是JavaScript大师,但希望这会对某人有所帮助。


通过阅读,我很惊讶我没有看到这一点。 我发现了多种适用于此的算法。

永不定义

如果从未定义对象的值,则如果将其定义为nullundefined ,则将阻止返回true 。 如果您希望为设置为的值返回true,这将非常有用 undefined

if(obj.prop === void 0) console.log("The value has never been defined");

定义为未定义或从未定义

如果您想要true使用值undefined或从未定义的值定义的结果,您可以简单地使用=== undefined

if(obj.prop === undefined) console.log("The value is defined as undefined, or never defined");

定义为假值,未定义,null或从未定义。

通常,人们问我一个算法,以确定一个值是否是假的undefined,或null。以下作品。

if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
    console.log("The value is falsy, null, or undefined");
}

问题可归结为三种情况:

  1. 该对象具有该属性,其值undefined
  2. 该对象具有该属性,其值undefined
  3. 该对象没有该属性。

这告诉我们一些我认为重要的事情:

未定义的成员与具有未定义值的已定义成员之间存在差异。

但不幸的是, typeof obj.foo并没有告诉我们这三种情况中的哪一种。 但是我们可以将它与"foo" in obj结合起来以区分这些情况。

                               |  typeof obj.x === 'undefined' | !("x" in obj)
1.                     { x:1 } |  false                        | false
2.    { x : (function(){})() } |  true                         | false
3.                          {} |  true                         | true

值得注意的是,这些测试对于null条目也是相同的

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

我认为在某些情况下更有意义(并且更清楚)检查属性是否存在,而不是检查它是否未定义,并且唯一的情况是这种检查将是不同的是案例2,这是罕见的情况具有未定义值的对象中的实际条目。

例如:我刚刚重构了一堆代码,这些代码检查对象是否具有给定属性。

if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

在没有检查未定义的情况下编写时更清楚。

if( "x" in blob ) { fn(blob.x); }

但正如已经提到的,这些并不完全相同(但对我的需求来说已经足够好了)。


任何事情都没有在JavaScript中定义未定义,如果它是Object / Array中的属性或仅仅是一个简单的变量也无关紧要......

JavaScript typeof使得检测未定义的变量非常容易。

只需检查是否typeof whatever === 'undefined'会返回布尔值。

这就是isUndefined()AngularJs v.1x中的着名函数的编写方式:

function isUndefined(value) {return typeof value === 'undefined';} 

因此,当您看到函数接收到一个值时,如果定义了该值,它将返回false,否则返回未定义的值true

因此,让我们看看当我们传递值时会产生什么结果,包括下面的对象属性,这是我们拥有的变量列表:

var  = {};
.javascipt = 'javascript';
var today;
var self = this;
var num = 8;
var list = [1, 2, 3, 4, 5];
var y = null;

我们检查它们如下,你可以看到它们前面的结果作为评论:

isUndefined(); //false
isUndefined(.javascipt); //false
isUndefined(today); //true
isUndefined(self); //false
isUndefined(num); //false
isUndefined(list); //false
isUndefined(y); //false
isUndefined(.java); //true
isUndefined(.php); //true
isUndefined( && .css); //true

如你所见,我们可以在我们的代码中使用类似的东西来检查任何内容,如上所述,您可以在代码中使用typeof,但如果您反复使用它,请创建一个类似我分享的角度样本的函数并继续重用如下面的DRY代码模式。

还有一件事,为了检查实际应用程序中的对象的属性,你甚至不确定对象是否存在,检查对象是否存在。

如果检查对象上的属性并且该对象不存在,则会抛出错误并停止整个应用程序的运行。

isUndefined(x.css);
VM808:2 Uncaught ReferenceError: x is not defined(…)

如此简单,你可以在if语句中包装如下:

if(typeof x !== 'undefined') {
  //do something
}

这也等于Angular 1.x中的isDefined ...

function isDefined(value) {return typeof value !== 'undefined';}

另外其他javascript框架如下划线也有类似的定义检查,但我建议你使用,typeof如果你已经没有使用任何框架。

我还从MDN添加了这一部分,其中包含有关typeof,undefined和void(0)的有用信息。

严格相等和未定义
您可以使用undefined和严格相等和不等运算符来确定变量是否具有值。在以下代码中,未定义变量x,if语句的计算结果为true。

var x;
if (x === undefined) {
   // these statements execute
}
else {
   // these statements do not execute
}

注意:此处必须使用严格相等运算符而不是标准相等运算符,因为x == undefined也会检查x是否为null,而严格相等则不会。null不等于undefined。请参阅比较运算符了解详细

Typeof运算符和undefined
或者,可以使用typeof:

var x;
if (typeof x === 'undefined') {
   // these statements execute
}

使用typeof的一个原因是,如果未声明变量,它不会抛出错误。

// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
   // these statements execute
}

if (x === undefined) { // throws a ReferenceError

}

但是,应该避免这种技术。JavaScript是一种静态范围的语言,因此可以通过查看是否在封闭的上下文中声明来了解是否声明了变量。唯一的例外是全局范围,但全局范围绑定到全局对象,因此可以通过检查全局对象上是否存在属性来检查全局上下文中是否存在变量(使用in运算符,例如)。

Void运算符和undefined

void操作符是第三种选择。

var x;
if (x === void 0) {
   // these statements execute
}

// y has not been declared before
if (y === void 0) {
   // throws a ReferenceError (in contrast to `typeof`)
}

更多> here


我很惊讶我还没有看到这个建议,但它比测试更具特异性typeof。使用Object.getOwnPropertyDescriptor(),如果你需要知道一个对象的属性是否与初始化undefined,或者如果它从未被初始化:

// to test someObject.someProperty
var descriptor = Object.getOwnPropertyDescriptor(someObject, 'someProperty');

if (typeof descriptor === 'undefined') {
  // was never initialized
} else if (typeof descriptor.value === 'undefined') {
  if (descriptor.get || descriptor.set) {
    // is an accessor property, defined via getter and setter
  } else {
    // is initialized with `undefined`
  }
} else {
  // is initialized with some other value
}

我用if (this.variable)它来测试它是否已定义。简单if (variable),上面推荐,对我来说失败了。事实证明,它仅在变量是某个对象的字段时起作用,obj.someField以检查它是否在字典中定义。但我们可以使用thiswindow作为字典对象,因为任何变量都是当前窗口中的字段,据我所知。因此这是一个测试

if (this.abc) alert("defined"); else alert("undefined");

abc = "abc";
if (this.abc) alert("defined"); else alert("undefined");

它首先检测到变量abc未定义,并在初始化后定义。


所有答案都不完整。这是知道某个属性“定义为未定义”的正确方法:

var hasUndefinedProperty = function hasUndefinedProperty(obj, prop){
  return ((prop in obj) && (typeof obj[prop] == 'undefined')) ;
} ;

例:

var a = { b : 1, e : null } ;
a.c = a.d ;

hasUndefinedProperty(a, 'b') ; // false : b is defined as 1
hasUndefinedProperty(a, 'c') ; // true : c is defined as undefined
hasUndefinedProperty(a, 'd') ; // false : d is undefined
hasUndefinedProperty(a, 'e') ; // false : e is defined as null

// And now...
delete a.c ;
hasUndefinedProperty(a, 'c') ; // false : c is undefined

太糟糕了,这是正确的答案埋没在错误的答案> _ <

所以,对于任何经过的人,我都会免费给你undefined!

var undefined ; undefined ; // undefined
({}).a ;                    // undefined
[].a ;                      // undefined
''.a ;                      // undefined
(function(){}()) ;          // undefined
void(0) ;                   // undefined
eval() ;                    // undefined
1..a ;                      // undefined
/a/.a ;                     // undefined
(true).a ;                  // undefined

"propertyName" in obj //-> true | false

function isUnset(inp) {
  return (typeof inp === 'undefined')
}

如果设置了变量,则返回false;如果未定义,则返回true。

然后使用:

if (isUnset(var)) {
  // initialize variable here
}






undefined