2010-10-17 38 views
16

我从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 
}; 

的JSON这么想的始终返回 “freeOfChargeProduct” 属性。所以,如果我想要得到的“freeOfChargeProduct”的价格,那么我必须做到以下几点:

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

没有问题。但是检查对象中的每个属性都非常烦人,所以我创建了一个函数来检查对象中的属性是否被定义。

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

var price = getValue('json.response.freeOfChargeProduct.details.price'); 
// Price is null if no such object exists. 

现在我的问题:这是一个好或坏的方法来检查,如果在一个对象存在的属性?任何更好的建议/方法?

编辑:

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

:)谢谢!

+1

我有一个[类似的问题](http://stackoverflow.com/questions/2631001/javascript-test-for-existence-of-nested-object-key)回来。您可能对某些回复感兴趣。 – user113716 2010-10-17 18:32:46

+0

谢谢你的回答!我找到了一个答案(由肯尼贝克发布),并给了它+1 :) – nekman 2010-10-17 18:42:27

回答

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

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

if(x && isDefined(x.y)) { 
    ... 
} 

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

19

使用保护模式:

if (json.response && json.response.freeOfChargeProduct && json.response.freeOfChargeProduct.details) { 
    // you can safely access the price 
} 

这是保护模式是如何工作的。

if (a && a.b && a.b.c) { ... } else { ... } 

第一个检查是“物业a是否存在?”。否则,else分支被执行。如果是,则进行下一个检查,即“对象a是否包含属性b?”。如果否,则执行else分支。如果是,则最终检查发生:“对象a.b是否包含属性c?”。如果否,则执行else分支。如果是(并且只有那样),则执行if分支。

更新:为什么叫做“守卫模式”?

var value = a && b; 

在本例中,构件b(右操作数)由操作者&&把守。只有成员a(左操作数)是真的(“值得”),才会返回成员b。但是,如果成员a是虚假的(“不值得”),那么它本身被返回。

顺便说一句,大家都falsy如果他们返回这些值:nullundefined0""falseNaN。在所有其他情况下,会员都很好。

+9

你叫它后卫?我称之为合乎逻辑的......以前从未听说过*警卫操作员*,但也许有人可以指给我一个资料来源? – 2010-10-17 18:42:31

+0

是的,我可以使用&& - 操作符。但是我想使用一个通用的解决方案,我可以重新使用任何对象。 – nekman 2010-10-17 18:45:06

+0

守卫是他的绰号。 (因为它保护第二个操作数:如果第一个操作数是虚假的,它将返回第一个操作数,如果第一个操作数是truthy,则返回第二个操作数。) – 2010-10-17 18:45:27

0

你可以做这样的事情:

try{ 
    var focp = json.response.freeOfChargeProduct 
    var text = "You get " + focp.qty + " of " + 
     focp.productName + 
     " for only $" + (focp.qty-focp.details.focQuantity)*focp.details.price + 
     ", You save $" + focp.details.focQuantity*focp.details.price; 
    $("order_info").innerText = text; 
} catch(e) { 
    // woops, handle error... 
} 

它会在你的问题产生,从所提供的数据这样的消息,如果字段存在:

你得到XYZ的6只$ 277,5,您节省$ 55.5

如果数据不存在,您将最终进入catch块。如果你不能想出处理错误的方法(也许会对数据做一个新的AJAX请求?),你总是可以试试,抓住,忘记这里。

1

这不是一个语法问题,因为它是设计模式问题。

问题答。 *您是否拥有对json服务器的控制权?

如果答案是否定的,我认为,情况将全部在客户端。

请仔细阅读本: http://martinfowler.com/eaaDev/PresentationModel.html

由于服务器是源,在这种情况下,它会提供模型。 此模式指定了其他工件:演示模型(PM)。在JavaScript中,我会建议两个工件,一个额外的转换器代码。

根据此设计模式,PM负责将模型转换为PM,并在必要时再返回。在你的情况下,永远不会发生从PM到M的转换。

这意味着一个js对象有一个方法或构造函数来消化模型并在转换器(下面)的帮助下转换自己。

这样做,你会最终有一个PM看起来像这样:

var OrderlinePM = { 
    "hasFreeOfCharge": false | true, 
    "freeOfCharge" : {...} 

enter code here this.getFreeOfCharge =函数(){ ... } this.fromModel =功能(jsonEntry,转换器) {// 转换此与转换器)到对于这个特定视图可用OrderlinePM //也inwith ... } “orderLineId”:0, “totalOrderLinePrice”: “741.36”, “吨otalOrderPrice“:”1,314.92“, ”totalQty“:17 };

function mySpecialFunctionPMConvertor { this.fromModel = functiono(){//对模型做一些奇怪的事情,并用它挖掘一个PM。 }}

好吧,我放弃了试图格式代码在这个富文本编辑器:(

  • 你可以有几个PM:献给所有因同一模型对象不同势任务
  • 此外,这将使转换器对象可测试的东西,可以自动执行.... ERR OK莫比手动,但无论如何。

那么繁琐的反射代码的问题真的不是proble米但凝聚力在JavaScript中是一个问题。

相关问题