检测未定义的对象属性

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

使用:

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

如果一个具有一些属性的对象variables可以使用像这样的相同的东西:

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

我相信这个话题有很多不正确的答案。 与普遍的看法相反,“未定义” 不是 JavaScript中的关键字,事实上可以赋予它一个值。

正确的代码

执行此testing的最可靠的方法是:

 if (typeof myVar === "undefined") 

这将始终返回正确的结果,甚至处理未声明myVar的情况。

退化的代码。 不使用。

 var undefined = false; // Shockingly, this is completely legal! if (myVar === undefined) { alert("You have been misled. Run away!"); } 

另外, myVar === undefined会在myVar未声明的情况下引发错误。

在JavaScript中是空的,并没有定义 。 他们有不同的含义。

  • 未定义表示variables值尚未定义; 目前还不知道这个价值是什么。
  • null表示variables值被定义并设置为null(没有值)。

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

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

所以,我想最好的方法来检查是否有未定义的东西是:

 if (something == undefined) 

希望这可以帮助!

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

 var person = { name: "John", age: 28, sex: "male" }; alert(person.name); // "John" alert(person.fakeVariable); // undefined 

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

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

 var o = { a: undefined } 

是不是定义? 是! 它的值是不确定的。 是不是定义? 当然! 根本没有财产'b'! 好的,现在看看在两种情况下不同的方法是如何performance的:

 typeof oa == 'undefined' // true typeof ob == 'undefined' // true oa === undefined // true ob === 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或者这个types的typeof xa == 'undefined'引发了ReferenceError: x is not defined如果ReferenceError: x is not defined x,x就没有被定义。
  • variablesundefined是一个全局variables(实际上它是浏览器中的window.undefined )。 自从ECMAScript第一版以来,它一直受到支持,并且由于ECMAScript 5是只读的 。 所以在现代浏览器中,很多作者都喜欢吓唬我们,所以现在的浏览器不能被重新定义为真实的 ,但是对于老一些的浏览器来说,这仍是一个真实的情况。

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

obj.prop === undefined

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

obj.prop === undefined

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

typeof obj.prop == 'undefined'

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

typeof obj.prop == 'undefined'

  • 'undefned'拼写错误 )在这里只是一个string常量,所以如果你像我刚刚那样拼写错误,那么JavaScript引擎就不能帮助你。

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

Node.js支持undefinedglobal.undefined的全局variables(也可以不使用“全局”前缀)。 我不知道服务器端JavaScript的其他实现。

许多现有的答案充其量是误导。

永远不要使用typeof x === "undefined" 。 (对于这个问题,或者== "undefined" )和所有“从不”一样,有一些例外情况,但大多数情况下呢? 如果您不知道在当前范围内是否定义了真正的variables,那么您做错了事情,可能会使用户处于危险之中 。 如果您想通过input错误来引入大量的错误,那么这种检查方式非常有用。

当然,这个潜力已经存在于对象属性的情况下,这似乎是这个问题的主题。 因此,我们忽略检查的types,因为它会造成更多的伤害,而不是好的,阅读是一种痛苦。 你直观地检查一个值,而不是一个types。

 var hasFoo = obj.foo !== undefined; 

对象属性的“默认值”是undefinedundefined也可以设置为属性的值。 这是您将需要一些时间的支票。

 var hasFoo = 'foo' in obj; 

这将检查沿着obj的原型链的foo属性是否存在,而不pipe值(包括undefined )。

 var hasFoo = obj.hasOwnProperty('foo'); 

这将检查obj的原型链末尾是否存在foo属性,即直接在obj上的属性。

 var hasFoo = Object.prototype.hasOwnProperty.call(obj, 'foo'); 

这和上面的一样,但是在某些情况下obj也有一个名为hasOwnProperty的属性时,会使用规范hasOwnProperty 。 在实践中,如果有人推翻了hasOwnProperty ,他们可能是一堆其他地方的混蛋,并重新undefined范围undefined ,或者改变ObjectObject.prototypeObject.prototype.hasOwnProperty.call

 var hasFoo = obj.foo != undefined; 

这一个也检查null 。 为了更清楚,我build议使用!= null来代替。

 var hasFoo = Boolean(obj.foo); // or !!obj.foo 

这检查其他falsy值(我希望这是显而易见的) – 0NaNfalse和空string。 对于检查function支持肯定是非常有用的:

 if (!Array.prototype.indexOf) { Array.prototype.indexOf = …; } 

总结:不要使用typeof来检查undefined值。 这很容易出错。 如果您在"undefined"部分中input错误,您将得到错误的答案。 如果你在testingvariables中input错误(如果你正在testing一个variables – 你不应该这么做,那么使用全局对象来做这种特性testing),你会得到错误的答案。

如果你是undefined被重新定义的偏执狂,这就是为什么你不应该:

  • undefined在现代浏览器中是只读的。 如果你在严格模式下进行开发,试图分配给它会导致错误。 (即使你没有严格的模式开发,它也不会改变。)它也是一个不可configuration的属性。 如果你通过将undefined传入你的IIFE来进入“安全模式”,你不得不担心。 永远不要这样做,因为在这个要点中列出的原因,以及事实…

  • 任何重新定义undefined都是白痴或者是开玩笑,或者是想要或者应该破坏代码。 (在“值得”的情况下,请注意他们的代码已经非常坏了。)

还是偏执? 与void 0进行比较。 void JavaScript中的一个关键字,它一直是,而且它总是会给你一个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 

值得注意的是这些testing对于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); } 

但正如已经提到的,这些不完全相同(但是足够满足我的需求)。

 if ( typeof( something ) == "undefined") 

这为我工作,而其他人没有。

我不知道在哪里使用typeof来源,并作为一个约定,我看到它在许多库中使用,但typeof运算符返回string文字,我们知道前面,所以为什么你会也想打字检查呢?

 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 

从相关问题交叉回答 如何检查JavaScript中的“undefined”?

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


一些情况说明各种答案的结果: http : //jsfiddle.net/drzaus/UVjM4/

(请注意,在范围包装中使用var fortesting会有所不同)

参考编号:

 (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 (obj && obj.prop) { // Do something; } 

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

如果你这样做

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

当variablesmyvar不存在时,它会失败,因为myvar没有定义,所以脚本被打破,testing没有效果。

由于窗口对象在函数外部具有全局作用域(缺省对象),因此声明将被“附加”到窗口对象。

例如:

 var myvar = 'test'; 

全局variablesmyvarwindow.myvarwindow ['myvar']相同

为避免在全局variables存在时进行错误testing,最好使用:

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

一个variables是否真的存在并不重要,它的值是不正确的。 否则,用undefined初始化variables是愚蠢的,最好使用false来初始化。 当你知道你声明的所有variables都被初始化为false时,你可以简单地检查它的types或者依靠!window.myvar来检查它是否有合适的/有效的值。 所以即使variables没有被定义,那么!window.myvar对于myvar = undefinedmyvar = falsemyvar = 0

当你期望一个特定的types时,testing这个variables的types。 为了加速testing一个条件,你最好做:

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

当第一个简单的条件成立时,解释器跳过下一个testing。

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

(y)的

在文章探索空的深渊和未定义在JavaScript中我读了像Underscore.js这样的框架使用这个函数:

 function isUndefined(obj){ return obj === void 0; } 

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

if (window.x)最有可能你想。 即使x没有被声明,这个检查是安全的( var x; ) – 浏览器不会抛出错误。

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

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

这是如何工作的:

窗口是一个保存所有全局variables作为其成员的对象,尝试访问一个不存在的成员是合法的。 如果x没有被声明或者没有被设置,那么window.x返回undefined如果()评估它, undefined会导致错误

通过阅读,我很惊讶,我没有看到这一点。 我发现了多种algorithm,可以为此工作。

从未定义

如果一个对象的值从来没有定义过,如果它被定义为null或者undefined ,这将防止返回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"); 

定义为falsy值,未定义,null或从不定义。

通常,人们要求我提供一个algorithm来确定某个值是否是虚假的, undefined或为null 。 以下的作品。

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

你可以使用下面的代码获得一个数组,全部未定义的path。

  function getAllUndefined(object) { function convertPath(arr, key) { var path = ""; for (var i = 1; i < arr.length; i++) { path += arr[i] + "->"; } path += key; return path; } var stack = []; var saveUndefined= []; function getUndefiend(obj, key) { var t = typeof obj; switch (t) { case "object": if (t === null) { return false; } break; case "string": case "number": case "boolean": case "null": return false; default: return true; } stack.push(key); for (k in obj) { if (obj.hasOwnProperty(k)) { v = getUndefiend(obj[k], k); if (v) { saveUndefined.push(convertPath(stack, k)); } } } stack.pop(); } getUndefiend({ "": object }, ""); return saveUndefined; } 

jsFiddle链接

这是我的情况:

我正在使用REST调用的结果。 结果应该从JSONparsing到JavaScript对象。

有一个错误,我需要捍卫。 如果用户指定的参数不正确,则其余参数基本上为空。

在使用这个post来帮助我防御这个时,我尝试了这个。

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

对于我的情况,如果restResult.data [0] ===“对象”,那么我可以安全地开始检查其余的成员。 If undefined then throw the error as above.

What I am saying is that for my situation, all the suggestions above in this post did not work. I'm not saying I'm right and everyone is wrong. I am not a JavaScript master at all, but hopefully this will help someone.

Compare with void 0 , for terseness.

 if (foo !== void 0) 

It's not as verbose as if (typeof foo !== 'undefined')

 "propertyName" in obj //-> true | false 
 function isUnset(inp) { return (typeof inp === 'undefined') } 

Returns false if variable is set, and true if is undefined.

Then use:

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

All the answers are incomplete. This is the right way of knowing that there is a property 'defined as undefined' :

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

例:

 var a = { b : 1, e : null } ; ac = ad ; 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 ac ; hasUndefinedProperty(a, 'c') ; // false : c is undefined 

Too bad that this been the right answer is buried in wrong answers >_<

So, for anyone who pass by, I will give you undefineds for free!!

 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 

The solution is incorrect. 在JavaScript中,

 null == undefined 

will return true, because they both are "casted" to a boolean and are false. The correct way would be to check

 if (something === undefined) 

which is the identity operator…

Going through the comments, for those who want to check both is it undefined or its value is null:

 //Just in JavaScript var s; // Undefined if (typeof s == "undefined" || s === null){ alert('either it is undefined or value is null') } 

If you are using jQuery Library then jQuery.isEmptyObject() will suffice for both cases,

 var s; // Undefined jQuery.isEmptyObject(s); // Will return true; s = null; // Defined as null jQuery.isEmptyObject(s); // Will return true; //Usage if (jQuery.isEmptyObject(s)) { alert('Either variable:s is undefined or its value is null'); } else { alert('variable:s has value ' + s); } s = 'something'; // Defined with some value jQuery.isEmptyObject(s); // Will return false; 

If you are using Angular:

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

Underscore.js:

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

There is a nice & elegant way to assign a defined property to a new variable if it is defined or assign a default value to it as a fallback if it´s undefined.

 var a = obj.prop || defaultValue; 

It's suitable if you have a function, which receives an additional config property:

 var yourFunction = function(config){ this.config = config || {}; this.yourConfigValue = config.yourConfigValue || 1; console.log(this.yourConfigValue); } 

Now executing

 yourFunction({yourConfigValue:2}); //=> 2 yourFunction(); //=> 1 yourFunction({otherProperty:5}); //=> 1 

I use if (this.variable) to test if it is defined. Simple if (variable) , recommended above , fails for me. It turns out that it works only when variable is a field of some object, obj.someField to check if it is defined in the dictionary. But we can use this or window as the dictionary object since any variable is a field in current window, as I understand it. Therefore here is a test

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

Also same things can be written shorter:

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

要么

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

I would like to show you something I'm using in order to protect the undefined variable:

 Object.defineProperty(window, 'undefined', {}); 

This forbids anyone to change the window.undefined value therefore destroying the code based on that variable. If using "use strict" , anything trying to change its value will end in error, otherwise it would be silently ignored.

Simply anything not defined in JavaScript, is undefined, doesn't matter if it's a property inside an Object/Array or as just a simple variable…

JavaScript has typeof which make it very easy to detect an undefined variable.

Simply check if typeof whatever === 'undefined' and it will return a boolean.

That's how the famous function isUndefined() in AngularJs v.1x is written:

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

So as you see the function receive a value, if that value is defined, it will return false , otherwise for undefined values, return true .

So let's have a look what gonna be the results when we passing values, including object properties like below, this is the list of variables we have:

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

and we check them as below, you can see the results in front of them as a comment:

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

As you see we can check anything with using something like this in our code, as mentioned you can simply use typeof in your code, but if you are using it over and over, create a function like the angular sample which I share and keep reusing as following DRY code pattern.

Also one more thing, for checking property on an object in real application which you not sure even the object exists or not, check if the object exist first.

If you check a property on an object and the object doesn't exist, will throw an error and stop the whole application running.

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

So simple you can wrap inside an if statement like below:

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

Which also equal to isDefined in Angular 1.x…

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

Also other javascript frameworks like underscore has similar defining check, but I recommend you use typeof if you already not using any frameworks.

I also add this section from MDN which has got useful information about typeof, undefined and void(0).

Strict equality and undefined
You can use undefined and the strict equality and inequality operators to determine whether a variable has a value. In the following code, the variable x is not defined, and the if statement evaluates to true.

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

Note: The strict equality operator rather than the standard equality operator must be used here, because x == undefined also checks whether x is null, while strict equality doesn't. null is not equivalent to undefined. See comparison operators for details.


Typeof operator and undefined
Alternatively, typeof can be used:

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

One reason to use typeof is that it does not throw an error if the variable has not been declared.

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

However, this kind of technique should be avoided. JavaScript is a statically scoped language, so knowing if a variable is declared can be read by seeing whether it is declared in an enclosing context. The only exception is the global scope, but the global scope is bound to the global object, so checking the existence of a variable in the global context can be done by checking the existence of a property on the global object (using the in operator, for instance).


Void operator and undefined

The void operator is a third alternative.

 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`) } 

more > here

From lodash.js.

 var undefined; function isUndefined(value) { return value === undefined; } 

It creates an variable named undefined which is initialized with the default value — the real undefined , then compares value with the variable undefined .

使用:

To check if property is undefined:

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

To check if property is not undefined:

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