检查对象是否已定义,最佳做法.

nek*_*man 19 javascript

我有一个来自ajax请求的以下JSON响应.

var json = {
    "response": {
        "freeOfChargeProduct": {  
        "description": "Product",  
        "orderQty": 5,
        "productName": "XYZ",
        "qty": 6,
        "details": {
            "price": 55.5, 
            "instock": "true",
            "focQuantity": 1
        }
    }, 
    "orderLineId": 4788,
    "totalOrderLinePrice": "741.36",
    "totalOrderPrice": "1,314.92",
    "totalQty": 17
};
Run Code Online (Sandbox Code Playgroud)

JSON并不总是返回"freeOfChargeProduct"属性.因此,如果我想获得"freeOfChargeProduct"价格,那么我必须执行以下操作:

var getFreeOfChargeProductPrice = function() { 
   var r = json.response;
   if (r && r.freeOfChargeProduct && r.freeOfChargeProduct.details) {
      return r.freeOfChargeProduct.details.price;         
   }
   return null;
};
Run Code Online (Sandbox Code Playgroud)

没问题.但是检查对象中的每个属性都非常烦人,因此我创建了一个函数来检查对象中的属性是否已定义.

var getValue = function (str, context) {
    var scope = context || window,
        properties = str.split('.'), i;
    for(i = 0; i < properties.length; i++) {
      if (!scope[properties[i]]) {                       
         return null;
      } 
      scope = scope[properties[i]];        
    }
    return scope;
};
Run Code Online (Sandbox Code Playgroud)
var price = getValue('json.response.freeOfChargeProduct.details.price');
// Price is null if no such object exists.
Run Code Online (Sandbox Code Playgroud)

现在问我的问题:这是检查对象中是否存在属性的好方法还是坏方法?有更好的建议/方法吗?

编辑:

我不想使用&& - 运算符.我很懒,我正在寻找一种可重用的方法来检查是否定义了一个对象(或对象的属性).

:) 谢谢!

Šim*_*das 22

使用保护模式:

if (json.response && json.response.freeOfChargeProduct && json.response.freeOfChargeProduct.details) {
    // you can safely access the price
}  
Run Code Online (Sandbox Code Playgroud)

这就是防护模式的工作原理.

if (a && a.b && a.b.c) { ... } else { ... }
Run Code Online (Sandbox Code Playgroud)

第一项检查是"财产是否a存在?".如果没有,则执行else分支.如果是,则进行下一次检查,即"对象是否a包含属性b?".如果不是,则执行else分支.如果是,则进行最终检查:"对象是否a.b包含属性c?".如果不是,则执行else分支.如果是(并且只有那时),if分支执行.

更新:为什么称它为"防护模式"?

var value = a && b;  
Run Code Online (Sandbox Code Playgroud)

在此示例中,成员b(右操作数)由&&操作员保护.只有当成员a(左操作数)是真实的("值得")时,才会b返回该成员.但是,如果是会员a是假的("不值得"),那么它本身就会返回.

顺便说一句,大家都falsy如果他们返回这些值:null,undefined,0,"",false,NaN.在所有其他情况下,成员都是真实的.

  • 你称之为守卫?我把它称为合乎逻辑的......之前从未听说过*警卫操作员*但也许有人可以指点我的来源? (10认同)
  • 仅供参考:这不是"保护/模式",而不仅仅是AND运算符的正常行为.逻辑运算符(AND,OR,...)的这种行为被称为**快捷方式评估**,它的根源远在C/C++和之前.并非每种语言都有这样的行为 - 例如VisualBasic(我讨厌它)不会快捷方式:如果'a'为null,则&& ab && abc将抛出,因为VB评估所有子表达式,然后才执行逻辑AND ... (5认同)
  • 嗯,我会小心这些绰号.您的解释可能在JavaScript中"起作用",但在PHP中则不行.我会说它可以*像一个守卫*......无论如何,这可能是分裂的头发,所以没关系!谢谢你的链接! (3认同)
  • Crockford在他的书中也告诉他们不要以这种方式使用它们,并补充说在这种情况下使用`typeof`和'&&'是非常重要的.看到.**JS:好零件**. (3认同)

Ple*_*and 16

if(x && typeof x.y != 'undefined') {
    ...
}

// or better
function isDefined(x) {
    var undefined;
    return x !== undefined;
}

if(x && isDefined(x.y)) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

这适用于JavaScript中的任何数据类型,甚至是零的数字.如果要检查对象或字符串,只需x && x.y在if语句中使用,或者如果您已经知道x是对象,if(x.y) ...