检测未定义的对象属性

如何检查JavaScript中的对象属性是否未定义?

1439792 次浏览
if (somevariable == undefined) {alert('the variable is not defined!');}

你也可以把它变成一个函数,如图这里所示:

function isset(varname){return(typeof(window[varname]) != 'undefined');}

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

  • 未定义表示变量值尚未定义;不知道值是什么。
  • null表示变量值已定义并设置为null(没有值)。

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

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

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

if (something == undefined)

对象属性应该以相同的方式工作。

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

解决方案不正确。在JavaScript中,

null == undefined

将返回true,因为它们都被“强制转换”为布尔值并且为false。正确的方法是检查

if (something === undefined)

也就是身份操作符…

检查属性值是否为特殊值undefined的通常方法是:

if(o.myProperty === undefined) {alert("myProperty value is the special value `undefined`");}

检查一个对象是否实际上没有这样的属性,因此在您尝试访问它时默认返回undefined

if(!o.hasOwnProperty('myProperty')) {alert("myProperty does not exist");}

检查与标识符关联的值是否为特殊值undefined,如果该标识符尚未声明,则为

if(typeof myVariable === 'undefined') {alert('myVariable is either the special value `undefined`, or it has not been declared');}

注意:最后一个方法是引用未申报标识符而不会出现早期错误的唯一方法,这与值undefined不同。

在ECMAScript 5之前的JavaScript版本中,全局对象上名为“untex”的属性是可写的,因此,如果意外地重新定义了简单的检查foo === undefined,则可能会出现意外的行为。在现代JavaScript中,该属性是只读的。

然而,在现代JavaScript中,“未定义”不是关键字,因此函数内的变量可以命名为“未定义”并隐藏全局属性。

如果你担心这种(不太可能的)边缘情况,你可以使用空操作符来获取特殊的undefined值本身:

if(myVariable === void 0) {alert("myVariable is the special value `undefined`");}
function isUnset(inp) {return (typeof inp === 'undefined')}

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

然后使用:

if (isUnset(var)) {// initialize variable here}
if ( typeof( something ) == "undefined")

这对我有用,而其他人没有。

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

正确代码

执行此测试的最健壮方法是:

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未声明的情况下引发错误。

我不确定使用===typeof的起源是从哪里来的,并且按照惯例,我看到它在许多库中使用,但是typeof运算符返回一个字符串文字,我们已经知道了,所以为什么你也想要类型检查它呢?

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

这个问题归结为三个案例:

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

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

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

但不幸的是,typeof obj.foo没有告诉我们我们有这三个案例中的哪一个。然而,我们可以将其与"foo" in obj结合起来来区分案例。

                               |  typeof obj.x === 'undefined' | !("x" in obj)1.                     { x:1 } |  false                        | false2.    { x : (function(){})() } |  true                         | false3.                          {} |  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); }

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

如果你这么做

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

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

因为窗口对象在函数之外有一个全局范围(默认对象),所以声明将“附加”到窗口对象。

例如:

var myvar = 'test';

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

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

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

一个变量是否真的存在并不重要,它的值是不正确的。否则,用untex初始化变量是愚蠢的,最好用false初始化。当你知道你声明的所有变量都是用false初始化的时,你可以简单地检查它的类型或依靠!window.myvar来检查它是否有正确/有效的值。所以即使变量没有定义,!window.myvarmyvar = undefinedmyvar = falsemyvar = 0也是一样的。

当你期望特定类型时,测试变量的类型。要加快测试条件,你最好这样做:

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

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

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

(y)

您可以使用以下代码获取一个带有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链接

Object.hasOwnProperty(o, 'propertyname');

然而,这并没有通过原型链进行查找。

我没有看到(希望我没有错过)有人在属性之前检查对象。所以,这是最短和最有效的(尽管不一定是最清楚的):

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

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

更新:(7/2/2021)

最新版本的JavaScript引入了一个新的运算符可选链接:?.

这可能是检查对象属性是否存在的最明确和最有效的方法。

参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

从相关问题如何检查JavaScript中的“未定义”?交叉如何检查JavaScript中的“未定义”?4305002">我的答案。

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


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

(请注意,在作用域包装器中使用var进行in测试会有所不同)

参考代码:

(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: truedefinedAndInitialized in window: falsesomeObject.firstProp in window: falsesomeObject.secondProp in window: falsesomeObject.undefinedProp in window: truenotDefined 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: falsetypeof definedButNotInitialized == "undefined": truetypeof definedButNotInitialized === typeof undefined: truedefinedButNotInitialized === undefined: true! definedButNotInitialized: true!! definedButNotInitialized: falsetypeof definedAndInitialized == "undefined": falsetypeof definedAndInitialized === typeof undefined: falsedefinedAndInitialized === undefined: false! definedAndInitialized: false!! definedAndInitialized: truetypeof someObject.firstProp == "undefined": falsetypeof someObject.firstProp === typeof undefined: falsesomeObject.firstProp === undefined: false! someObject.firstProp: false!! someObject.firstProp: truetypeof someObject.secondProp == "undefined": falsetypeof someObject.secondProp === typeof undefined: falsesomeObject.secondProp === undefined: false! someObject.secondProp: true!! someObject.secondProp: falsetypeof someObject.undefinedProp == "undefined": truetypeof someObject.undefinedProp === typeof undefined: truesomeObject.undefinedProp === undefined: true! someObject.undefinedProp: true!! someObject.undefinedProp: falsetypeof notDefined == "undefined": truetypeof notDefined === typeof undefined: truenotDefined === undefined: Exception--ReferenceError: notDefined is not defined! notDefined: Exception--ReferenceError: notDefined is not defined!! notDefined: Exception--ReferenceError: notDefined is not defined

"未定义对象属性"是什么意思?

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

var o = { a: undefined }

o.a未定义吗?是的!它的值未定义。o.b未定义吗?当然!根本没有属性'b'!好的,现在看看不同方法在这两种情况下的行为:

typeof o.a == 'undefined' // truetypeof o.b == 'undefined' // trueo.a === undefined // trueo.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

备注:

  • 您不能同时检查一个对象及其属性。例如,如果未定义x,则此x.a === undefined或此typeof x.a == 'undefined'会引发ReferenceError: x is not defined
  • 变量undefined是一个全局变量(所以实际上它在浏览器中是window.undefined)。从ECMAScript第1版开始就支持它,从ECMAScript 5开始它是只读。所以在现代浏览器中,它不可能是重新定义为true,因为许多作者喜欢用它来吓唬我们,但对于旧浏览器来说仍然如此。

决战:obj.prop === undefined vstypeof 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作为global.undefined(它也可以在没有“全局”前缀的情况下使用)。我不知道服务器端JavaScript的其他实现。

以下是我的情况:

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

我需要为一个错误辩护。如果REST调用的参数不正确,就用户指定参数错误而言,REST调用基本上是空的。

在使用这篇文章来帮助我防御这一点时,我尝试了这个:

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

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

我要说的是,就我的情况而言,这篇文章中之前的所有建议都不起作用。我不是说我是对的,每个人都是错的。我根本不是JavaScript大师,但希望这能帮助某人。

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

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

void 0相比,为了简洁。

if (foo !== void 0)

它不像if (typeof foo !== 'undefined')那样冗长

如果(windows. x){}是错误安全的

这个检查是安全的,即使x没有被声明(var x;)-浏览器不会抛出错误。

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

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

这是如何工作的:

窗口是一个包含所有全局变量作为其成员的对象,尝试访问一个不存在的成员是合法的。如果x未被声明或未被设置,则window.x返回未定义未定义导致虚假if()计算它时。

尽管这里有许多其他答案强烈推荐,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'检查为特定于Common JS环境的代码中的一个步骤),当用于变量时,typeof是一个有害的选择,正确的选择是直接比较值:

var foo = …;
if (foo === undefined) {⋮}

对此的一些常见误解包括:

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

  • undefined可以被覆盖。的确,undefined不是关键字,但它是只读且不可配置的。还有其他内置组件,尽管它们的状态为非关键字(ObjectMathNaN…),但你可能不会避免它们。实用的代码通常不是在积极恶意的环境中编写的,所以这不是担心undefined的好理由。(但是如果你正在编写代码生成器,请随时使用void 0。)

关于变量是如何工作的,是时候解决实际问题了:对象属性。没有理由对对象属性使用typeof。前面关于特征检测的例外在这里不适用——typeof只对变量有特殊行为,引用对象属性的表达式不是变量。

这个:

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

总是完全等价到这个〇:

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

考虑到上面的建议,为了避免让读者混淆你为什么使用typeof,因为使用===来检查是否相等是最有意义的,因为它可以被重构为稍后检查变量的值,因为它看起来更好,你也应该在这里使用#2

当涉及到对象属性时,需要考虑的另一件事是您是否真的想要检查undefined。给定的属性名称可以在对象上不存在(读取时产生值undefined),以值undefined存在于对象本身,以值undefined存在于对象的原型上,或者以非undefined值存在于其中任何一个上。'key' in obj会告诉您键是否位于对象原型链上的任何位置,Object.prototype.hasOwnProperty.call(obj, 'key')会告诉您它是否直接位于对象上。不过,我不会在这个答案中详细介绍原型和使用对象作为字符串键控映射,因为它主要是为了反驳其他答案中的所有糟糕建议,无论对原始问题的可能解释如何。

示例变量名的不寻常选择?这是来自Firefox的NoScript扩展的真正死代码。
²不要假设不知道范围内的内容在一般情况下是可以的,不过。滥用动态范围引起的额外漏洞:Project Zero 1225
再一次假设ES5+环境,undefined指的是全局对象的undefined属性。

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

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

if (!variable){// Do it if the variable is undefined}

if (variable){// Do it if the variable is defined}

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

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 1hasUndefinedProperty(a, 'c'); // true: c is defined as undefinedhasUndefinedProperty(a, 'd'); // false: d is undefinedhasUndefinedProperty(a, 'e'); // false: e is defined as null
// And now...delete a.c ;hasUndefinedProperty(a, 'c'); // false: c is undefined

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

所以,对于任何路过的人,我会免费给你未定义的!!

var undefined ; undefined ; // undefined({}).a ;                    // undefined[].a ;                      // undefined''.a ;                      // undefined(function(){}()) ;          // undefinedvoid(0) ;                   // undefinedeval() ;                    // undefined1..a ;                      // undefined/a/.a ;                     // undefined(true).a ;                  // undefined

浏览评论,对于那些想要检查两者的人来说,它是未定义的还是它的值为null:

//Just in JavaScriptvar s; // Undefinedif (typeof s == "undefined" || s === null){alert('either it is undefined or value is null')}

如果您使用的是jQuery Library,那么jQuery.isEmptyObject()对这两种情况都足够了,

var s; // UndefinedjQuery.isEmptyObject(s); // Will return true;
s = null; // Defined as nulljQuery.isEmptyObject(s); // Will return true;
//Usageif (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 valuejQuery.isEmptyObject(s); // Will return false;

我想向您展示一些我用来保护undefined变量的东西:

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

这禁止任何人更改window.undefined值,从而破坏基于该变量的代码。如果使用"use strict",任何试图更改其值的东西都将以错误结束,否则它将被静默忽略。

如果您使用Angular:

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

Underscore.js:

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

读到这里,我很惊讶我没有看到这一点。我发现了多种算法可以解决这个问题。

从未定义

如果对象的值从未定义过,如果它被定义为nullundefined,这将阻止返回true。如果您希望将值设置为undefined返回true,这很有帮助

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

定义为未定义或从未定义

如果您希望它对使用undefined定义的值的结果为true,或者从未定义过,您可以简单地使用=== undefined

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

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

通常情况下,人们会问我要一个算法来判断一个值是false sy、undefined还是null

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

我使用if (this.variable)来测试它是否已定义。简单的if (variable)在以前的回答中推荐对我来说失败了。

事实证明,只有当变量是某个对象的字段时,它才有效,obj.someField检查它是否在字典中定义。但是我们可以使用thiswindow作为字典对象,因为任何变量都是当前窗口中的字段,据我所知。因此这里是一个测试:

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

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

用途:

检查属性是否未定义:

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

检查属性是否未定义:

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

从lodash.js.

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

它创建了一个名为undefined当地变量,该变量使用默认值——真正的undefined进行初始化,然后将value与变量undefined进行比较。


更新9/9/2019

我发现Lodash更新了它的实现。见我的问题的代码

要防弹,只需使用:

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

有一种漂亮而优雅的方法可以将已定义的属性分配给新变量(如果已定义),或者将默认值分配给它(如果未定义)作为后备。

var a = obj.prop || defaultValue;

如果你有一个函数,它接收一个额外的配置属性:

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

现在正在执行

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

我很惊讶我还没有看到这个建议,但它比用typeof测试更具体。如果你需要知道一个对象属性是用undefined初始化的,还是从未初始化过,请使用#1

// to test someObject.somePropertyvar 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}

这可能是确定现有属性名称是否具有显式和预期值undefined的唯一显式形式;尽管如此,这是一种JavaScript类型。

"propertyName" in containerObject && ""+containerObject["propertyName"] == "undefined";>> true \ false

只有当给定上下文的属性名存在(真实存在)并且其预期值显式为undefined时,此表达式才会返回true

不会有误报,就像空或空字符串零、空值或空数组等。这正是这样做的。检查,即确保属性名称存在(否则它将是误报),而不是它明确检查它的值是否为undefined,例如在它的字符串表示形式中的未定义JavaScript类型(字面意思是“未定义”),因此==而不是===,因为不可能进行进一步的转换。并且这个表达式只有在两者都满足的情况下才会返回true,这就是所有条件。例如,如果属性名称不存在,-它将返回false。这是唯一正确的返回,因为不存在的属性不能有值,甚至连未定义的都不能。

示例:

containerObject = { propertyName: void "anything" }>> Object { propertyName: undefined }
// Now the testing
"propertyName" in containerObject && ""+containerObject["propertyName"] == "undefined";>> true
/* Which makes sure that nonexistent property will not return a false positive* unless it is previously defined  */
"foo" in containerObject && ""+containerObject["foo"] == "undefined";>> false

简单地说,JavaScript中没有定义任何东西,就是未定义,不管它是对象/数组中的属性还是只是一个简单的变量…

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

只需检查typeof whatever === 'undefined',它将返回一个布尔值。

这就是AngularJs v.1x中著名的函数isUndefined()的写法:

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

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

所以让我们看看当我们传递值时会有什么结果,包括如下所示的对象属性,这是我们拥有的变量列表:

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

我们检查它们如下,您可以在它们前面看到结果作为注释:

isUndefined(stackoverflow); //falseisUndefined(stackoverflow.javascipt); //falseisUndefined(today); //trueisUndefined(self); //falseisUndefined(num); //falseisUndefined(list); //falseisUndefined(y); //falseisUndefined(stackoverflow.java); //trueisUndefined(stackoverflow.php); //trueisUndefined(stackoverflow && stackoverflow.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中定义…

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

其他JavaScript框架,如下划线,也有类似的定义检查,但如果你还没有使用任何框架,我建议你使用typeof

我还从MDN中添加了这一部分,它获得了有关typeof、untex和val(0)的有用信息。

严格平等和未定义
您可以使用未定义以及严格相等和不等式运算符来确定变量是否具有一个值。在以下代码中,变量x未定义,并且如果语句计算为true。

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

注意:严格等号操作符而不是标准等号这里必须使用运算符,因为x==未定义还检查是否x为null,而严格相等不。null不等价于未定义。有关详细信息,请参阅比较运算符。


类型运算符和未定义
或者,可以使用typeof:

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

使用typeof的一个原因是,如果变量尚未声明。

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

但是,应该避免这种技术。JavaScript是一种静态作用域语言,因此知道变量是否被声明可以通过查看它是否在封闭上下文中声明来读取。该唯一的例外是全局作用域,但全局作用域必然全局对象,因此检查变量是否存在全局上下文可以通过检查属性的存在来完成全局对象(例如,使用in运算符)。


无效运算符和未定义

无效运算符是第三种选择。

var x;if (x === void 0) {// these statements execute}
// y has not been declared beforeif (y === void 0) {// throws a ReferenceError (in contrast to `typeof`)}

更多>这里

我假设你也想检查它是要么undefined还是null。如果是这样,我建议:

myVar == null

这是双等于非常有用的情况之一,因为当myVarundefinednull时,它将评估为true,但当它是其他假值(如0false''NaN)时,它将评估为false

这是Lodash的#0方法的实际的源代码

我在这里为那些期待奇怪答案的人提供了三种方法:

function isUndefined1(val) {try {val.a;} catch (e) {return /undefined/.test(e.message);}return false;}
function isUndefined2(val) {return !val && val+'' === 'undefined';}
function isUndefined3(val) {const defaultVal = {};return ((input = defaultVal) => input === defaultVal)(val);}
function test(func){console.group(`test start :`+func.name);console.log(func(undefined));console.log(func(null));console.log(func(1));console.log(func("1"));console.log(func(0));console.log(func({}));console.log(func(function () { }));console.groupEnd();}test(isUndefined1);test(isUndefined2);test(isUndefined3);

是否定义1

尝试获取输入值的属性,并检查错误消息是否存在。如果输入值未定义,则错误消息将为未捕获的TypeError:无法读取未定义的属性“b”

是未定义2:

将输入值转换为字符串以与"undefined"进行比较,并确保它是负值。

是否定义3

在JavaScript中,当输入值恰好为undefined时,可选参数起作用。

您可以像这样使用JavaScript对象函数:

var ojb ={age: 12}
if(ojb.hasOwnProperty('name')){console.log('property exists and is not undefined');}

上面的方法返回true,如果它得到了该属性或该属性不是未定义的。

您也可以使用代理。它可以处理嵌套调用,但需要进行一次额外的检查:

function resolveUnknownProps(obj, resolveKey) {const handler = {get(target, key) {if (target[key] !== null &&typeof target[key] === 'object') {return resolveUnknownProps(target[key], resolveKey);} else if (!target[key]) {return resolveUnknownProps({ [resolveKey]: true }, resolveKey);}
return target[key];},};
return new Proxy(obj, handler);}
const user = {}
console.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }

所以你会像这样使用它:

const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;if (!isUndefined) {// Do something}

Lodash库中有一些小助手:

is未定义-检查是否为undefined

_.isUndefined(undefined) // => true_.isUndefined(null) // => false

已经-检查对象是否包含属性

const object = { 'a': { 'b': 2 } }
_.has(object, 'a.b') // => true_.has(object, 'a.c') // => false

ECMAScript 6中引入,我们现在可以使用代理以新的方式处理undefined。它可用于为任何不存在的属性设置默认值,这样我们就不必每次检查它是否实际存在。

var handler = {get: function(target, name) {return name in target ? target[name] : 'N/A';}};
var p = new Proxy({}, handler);p.name = 'Kevin';console.log('Name: ' +p.name, ', Age: '+p.age, ', Gender: '+p.gender)

将输出以下文本而不会得到任何未定义的。

Name: Kevin , Age: N/A , Gender: N/A

检查密钥是否存在的一个简单方法是使用in

if (key in obj) {// Do something} else {// Create key}
const obj = {0: 'abc',1: 'def'}
const hasZero = 0 in obj
console.log(hasZero) // true

ECMAScript 10引入了一个新特性-可选链接,只有当对象定义如下时,您才能使用该特性来使用对象的属性:

const userPhone = user?.contactDetails?.phone;

仅当定义了user和Contact详细信息时,它才会引用phone属性。

参考。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

我找到了这篇文章,在JavaScript中处理未定义的7个提示,它展示了关于undefined的非常有趣的事情喜欢:

未定义的存在是JavaScript的许可性质的结果,允许使用:

  • 未初始化变量
  • 不存在的对象属性或方法
  • 访问数组元素的越界索引
  • 不返回任何内容的函数的调用结果

在JavaScript中,有TruthyFalsy表达式。如果您想检查属性是否未定义,有一种直接的方法可以使用给定的如果条件,

  1. 使用真/假概念。
if(!ob.someProp){console.log('someProp is falsy')}

然而,还有几种方法可以检查对象是否具有属性,但对我来说似乎很长。

  1. 使用#0签入#1条件
if(ob.someProp === undefined){console.log('someProp is undefined')}
  1. 使用#0

#0作为未定义值和变量是否存在的组合检查。

if(typeof ob.someProp === 'undefined'){console.log('someProp is undefined')}
  1. 使用#0方法

JavaScript对象在对象原型中内置了hasOwnProperty函数。

if(!ob.hasOwnProperty('someProp')){console.log('someProp is undefined')}

不深入,但是1st的方式看起来缩短了,对我来说很好。以下是JavaScript中真/假值的详细信息,undefined是其中列出的false sy值。所以if条件表现正常,没有任何故障。除了undefined,值NaNfalse(显然)、''(空字符串)和数字0也是false sy值。

警告确保属性值不包含任何false sy值,否则#0条件将返回false。对于这种情况,您可以使用#1方法

有一个非常简单和简单的方法。

您可以使用可选链接

x = {prop:{name:"sajad"}}
console.log(x.prop?.name) // Output is: "sajad"console.log(x.prop?.lastName) // Output is: undefined

if(x.prop?.lastName) // The result of this 'if' statement is false and is not throwing an error

您甚至可以对函数或数组使用可选链接。

截至2020年中期,这还没有普遍实施。检查https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining的留档

审查

许多给定的答案给出了错误的结果,因为它们没有区分对象属性不存在的情况和属性值为undefined的情况。这是最流行的解决方案的证明

let obj = {a: 666,u: undefined // The 'u' property has value 'undefined'// The 'x' property does not exist}
console.log('>>> good results:');console.log('A', "u" in obj, "x" in obj);console.log('B', obj.hasOwnProperty("u"),      obj.hasOwnProperty("x"));
console.log('\n>>> bad results:');console.log('C', obj.u === undefined,          obj.x === undefined);console.log('D', obj.u == undefined,           obj.x == undefined);console.log('E', obj["u"] === undefined,       obj["x"] === undefined);console.log('F', obj["u"] == undefined,        obj["x"] == undefined);console.log('G', !obj.u,                      !obj.x);console.log('H', typeof obj.u === 'undefined', typeof obj.x === 'undefined');

在最近的JavaScript版本中引入了新的链接运算符,这可能是检查属性是否存在的最佳方式,否则它会给你未定义

见下面的例子

  const adventurer = {name: 'Alice',cat: {name: 'Dinah'}};
const dogName = adventurer.dog?.name;console.log(dogName);// expected output: undefined
console.log(adventurer.someNonExistentMethod?.());// expected output: undefined

我们可以替换这个旧语法

if (response && response.data && response.data.someData && response.data.someData.someMoreData) {}

用这种简洁的语法

if( response?.data?.someData?.someMoreData) {}

此语法在IE、Opera、Safari和samsund android中不支持

有关详细信息,您可以查看此URL

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

使用动态变量的版本你知道吗?

var boo ='lala';
function check(){if(this['foo']){console.log('foo is here');}else{console.log('have no foo');}
if(this['boo']){console.log('boo is here');}else{console.log('have no boo');}}
check();

处理未定义

function isUndefined(variable,defaultvalue=''){
if (variable == undefined ) return defaultvalue;    
return variable;
}

var obj={und:undefined,notundefined:'hi i am not undefined'}

function isUndefined(variable,defaultvalue=''){
if (variable == undefined ){return defaultvalue;}return variable
}
console.log(isUndefined(obj.und,'i am print'))console.log(isUndefined(obj.notundefined,'i am print'))

我们在ES6可以用!!转换所有值为布尔。使用它,所有Falsy值都变成了虚假

第一个解决方案

if (!(!!variable)) {// Code}

第二种解决方案

if (!variable) {// Code}