检测未定义的对象属性

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


#1楼

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

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

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


#2楼

我从相关问题中交叉回答我的答案 如何在JavaScript中检查“未定义”?

特定于此问题,请参见someObject.<whatever>测试用例。


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

(请注意,在范围内的包装器中, in测试中使用var会有所不同)

参考代码:

(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

#3楼

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

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

var o = { a: undefined }

oa是未定义的吗? 是! 其值是不确定的。 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它是只读的 。 因此,在现代浏览器中,不能像许多作者喜欢的那样将其重新定义为true ,但是对于较旧的浏览器来说,这仍然是正确的。

最后一战: 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支持将undefinedglobal.undefined (也可以不使用'global'前缀使用)。 我不知道服务器端JavaScript的其他实现。


#4楼

这是我的情况:

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

我需要捍卫一个错误。 如果就用户指定的args错误而言,rest调用的args不正确,则rest调用基本上返回为空。

在使用这篇文章帮助我进行防御时,我尝试了一下。

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

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

我的意思是,就我的情况而言,本文中以上所有建议均无效。 我并不是说我是对的,每个人都是错误的。 我根本不是JavaScript大师,但希望这会对某人有所帮助。


#5楼

在《 探索JavaScript中的Null和Undefined的深渊》一文中,我读到像Underscore.js之类的框架使用此函数:

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

#6楼

void 0比较,简洁。

if (foo !== void 0)

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


#7楼

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

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

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

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

工作原理:

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


#8楼

尽管这里的许多其他答案都强烈建议typeoftypeof 是一个不好的选择 。 永远不要将其用于检查变量是否具有值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 = 5而不是抛出。 但是,由于它不是关键字,因此可以使用undefined名称声明变量,并且可以更改这些变量,从而形成以下常见的模式:

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

    比使用全局undefined 危险。 如果必须与ES3兼容,请将undefined替换为void 0 –请勿使用typeof 。 ( void一直是一元运算符,其任何操作数的计算结果均为未定义值。)

随着变量如何发挥作用,是时候解决一个实际问题:对象属性。 没有理由将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')会告诉您Object.prototype.hasOwnProperty.call(obj, 'key')是否直接在对象上。 不过,我不会在这个答案中详细介绍关于原型以及将对象用作字符串键映射的原因,因为它主要是为了抵消其他答案中的所有不良建议,而与原始问题的可能解释无关。 阅读有关MDN的对象原型的更多信息!

¹示例变量名称的异常选择?这是来自Firefox的NoScript扩展的真正的死代码。
²不过,不要以为总体上不知道范围是可以的。动态范围滥用引起的额外漏洞: 零项目1225
³再次假定为ES5 +环境,并且undefined是指全局对象的undefined属性。否则将void 0替换为void 0


#9楼

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

#10楼

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

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

要么

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

#11楼

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

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

不幸的是,这是正确的答案却被错误的答案掩盖了> _ <

因此,对于任何路过的人,我将免费为您提供未定义的内容!!

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

#12楼

通过注释,对于那些想同时检查这两个注释的对象,它是未定义的还是其值为null:

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

如果您使用的是jQuery库,则jQuery.isEmptyObject()足以满足这两种情况,

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;

#13楼

我想向您展示一些我正在使用的东西,以保护undefined变量:

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

这禁止任何人更改window.undefined值,因此会破坏基于该变量的代码。 如果使用"use strict" ,则任何试图更改其值的操作都将以错误结尾,否则将被忽略。


#14楼

如果您使用的是Angular:

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

Underscore.js:

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

#15楼

在JavaScript中,为null ,没有定义 。 它们具有不同的含义。

  • 未定义表示尚未定义变量值; 目前尚不清楚该值是多少。
  • null表示已定义变量值并将其设置为null(无值)。

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

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

因此,我认为检查某些内容是否未定义的最佳方法是:

if (something == undefined)

希望这可以帮助!

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

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

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

#16楼

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

null == undefined

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

if (something === undefined)

这是身份运算符...


#17楼

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

从未定义

如果从未定义对象的值,则如果将其定义为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");

定义为虚假值,未定义,空值或从未定义。

通常,人们要求我提供一种算法来判断值是伪造的, undefined还是null 。 以下作品。

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

#18楼

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

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

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


#19楼

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

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

然后使用:

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

#20楼

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

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


#21楼

来自lodash.js。

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

它创建一个名为undefined的LOCAL变量,该变量将使用默认值-实数undefined进行初始化,然后将value与变量undefined进行比较。


更新9/9/2019

我发现lodash更新了其实现。 请参阅我的问题代码

要防弹,只需使用:

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

#22楼

我相信对此主题有许多不正确的答案。 与通常的看法相反,“未定义” 不是 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的情况下, myVar === undefined将引发错误。


#23楼

如果定义了新变量,则有一种很好的方法来给新变量分配已定义的属性;如果未定义,则可以为其分配默认值作为后备。

var a = obj.prop || defaultValue;

如果您有一个函数,它会收到一个附加的config属性,则它是合适的:

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

#24楼

我不确定在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

#25楼

采用:

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

如果对象变量具有某些属性,则可以使用类似的方法:

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

#26楼

只是没有在JavaScript中定义的任何东西都是未定义的 ,无论是对象/数组中的属性还是简单变量都没有关系...

JavaScript具有typeof ,可以很容易地检测到未定义的变量。

只需检查typeof whatever === 'undefined'是否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); //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

如您所见,我们可以在代码中使用类似这样的内容进行检查,如上所述,您可以在代码中简单地使用typeof ,但是如果您一遍又一遍地使用它,请创建一个函数,例如我共享并继续重复使用的angular示例如下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,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不等于未定义。 有关详细信息,请参见比较运算符。


Typeof运算符和未定义
另外,可以使用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运算符是第三种选择。

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

更多> 这里


#27楼

对于那些期望得到怪异答案的人,我在这里提供了三种方法:

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

isUndefined1:

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

isUndefined2:

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

isUndefined3:

在js中,当输入值完全undefined时,可选参数有效。


#28楼

您还可以使用Proxy,它将与嵌套调用一起使用,但需要额外检查一下:

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 someting
}

#29楼

问题归结为三种情况:

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

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

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

但是typeof obj.foo是, 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); }

但是如上所述,它们并不完全相同(但足以满足我的需求)。


#30楼

如果你这样做

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

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

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

(y)


#31楼

您可以使用以下代码获取所有未定义路径的数组。

 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链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值