代码之家  ›  专栏  ›  技术社区  ›  nekman

检查是否定义了对象,最佳实践。

  •  19
  • nekman  · 技术社区  · 14 年前

    我有以下来自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
    };
    

    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.
    

    编辑:

    :)谢谢!

    4 回复  |  直到 11 年前
        1
  •  16
  •   PleaseStand    14 年前
    if(x && typeof x.y != 'undefined') {
        ...
    }
    
    // or better
    function isDefined(x) {
        var undefined;
        return x !== undefined;
    }
    
    if(x && isDefined(x.y)) {
        ...
    }
    

    这将适用于JavaScript中的任何数据类型,甚至是零。如果要检查对象或字符串,请使用 x && x.y if(x.y) ...

        2
  •  22
  •   Å ime Vidas Zim84    14 年前

    使用保护图案:

    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分支。如果是,则进行下一个检查,即“Does object 包含属性 b a.b 包含属性 c ?". 如果否,则执行else分支。如果是(并且只有在那时),则执行If分支。

    var value = a && b;  
    

    在本例中,成员 (右操作数)由 && 接线员。只有当成员 (左操作数)是真的(“有价值”),只有当成员 被退回。但是,如果 是虚假的(“不值得”),那么它本身就是回报。

    null , undefined , 0 "" , false , NaN

        3
  •  0
  •   Frank    14 年前

    你可以这样做:

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

    如果字段存在,它将根据问题中提供的数据生成这样的消息:

    如果数据不存在,则最终会出现在catch块中。如果您不能想出处理错误的方法(可能对数据执行一个新的AJAX请求),那么您可以尝试、捕捉、忘记这里。

        4
  •  -2
  •   coderdark    5 年前

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

    问题A。 *您是否控制了json服务器?

    如果这个问题的答案是否定的,我想,情况将完全取决于客户。

    http://martinfowler.com/eaaDev/PresentationModel.html

    由于服务器是源,在本例中,它将提供模型。

    根据这种设计模式,项目经理负责将模型转换为项目经理,并在必要时返回。在您的情况下,不会发生从PM到M的转换。

    这意味着js对象有一个方法或构造函数,该方法或构造函数在转换器的帮助下消化模型并转换自身(如下所示)。

    这样做的话,你会得到一个这样的下午:

    var OrderlinePM = {
        "hasFreeOfCharge": false | true,
        "freeOfCharge" : {...}
    
        `enter code here`
    
        this.getFreeOfCharge = function() {
            ...
        }
    
        this.fromModel = function(jsonEntry, convertor) {
            //convert this with the convertor ;) to a for this specific view usable OrderlinePM
           // also inwith 
           ...
        }
    
        enter code here
        "orderLineId":0, 
        "totalOrderLinePrice":"741.36", 
        "totalOrderPrice":"1,314.92", 
        "totalQty":17
    };
    
    function mySpecialFunctionPMConvertor {
        this.fromModel = function() {
            ... //do strange stuff with the model and poulate a PM with it.
        }
    }
    

    • 对于不同的任务,可以有几个PM:s,这都取决于同一个模型对象。

    所以笨重的反射代码的问题其实不是问题。但内聚性是个问题,尤其是在JavaScript中。