Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 检查是否定义了对象,这是最佳做法。_Javascript - Fatal编程技术网

Javascript 检查是否定义了对象,这是最佳做法。

Javascript 检查是否定义了对象,这是最佳做法。,javascript,Javascript,我有一个ajax请求的JSON响应 var json = { "response": { "freeOfChargeProduct": { "description": "Product", "orderQty": 5, "productName": "XYZ", "qty": 6, "details": { "price": 55.5,

我有一个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并不总是返回“freefChargeProduct”属性。因此,如果我想得到“免费产品”的价格,那么我必须做以下几点:

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

使用防护模式:

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
(左操作数)为truthy(“worthy”),才返回成员
b
。但是,如果成员
a
是falsy(“不值得”),则返回该成员本身


顺便说一句,如果成员返回以下值,则它们是错误的:
null
未定义的
0
错误
NaN
。在所有其他情况下,成员都是真实的。

您可以这样做:

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...
}
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.
    }
}
如果字段存在,它将根据您问题中提供的数据生成如下消息:

只需277.5美元,您就可以获得6个XYZ,节省55.5美元

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


这将适用于JavaScript中的任何数据类型,即使是零。如果您正在检查对象或字符串,只需在If语句中使用
x&&x.y
,或者如果您已经知道x是一个对象,
If(x.y).
这不是语法问题,因为它是一个设计模式问题

问题A。 *您可以控制json服务器吗

如果答案是否定的,我认为,情况将完全取决于客户

请阅读:

由于服务器是源,因此在本例中,它将提供模型。 此模式指定了另一个工件:表示模型(PM)。在javascript中,我建议使用两个构件,一个用于转换器代码的附加构件

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

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

这样做,您将得到一个如下所示的PM:

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...
}
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
  • 此外,这将使转换器对象可以在一些可以自动执行的东西中进行测试…err ok maby manually,但无论如何

因此,繁琐的反射代码的问题其实不是问题。但是内聚性是一个问题,尤其是在JavaScript中。

我有一段时间了。您可能对其中一些响应感兴趣。谢谢您的回答!我找到了一个答案(由kennebec发布)并给出了+1:)您称之为guard?我称之为逻辑和。。。。以前从未听说过guard操作符,但也许有人能给我指出一个来源?是的,我可以使用&&操作符。但是我想使用一个通用的解决方案,我可以对任何对象重复使用。嗯,我会小心使用这些昵称。您的解释可能在JavaScript中“起作用”,但在例如PHP中不起作用。我想说它可以像一个守卫一样。。。不管怎样,这可能会让人毛骨悚然,所以别担心!谢谢你的链接!Crockford在他的书中还告诉我们不要以这种方式使用它们,并补充说在这种情况下使用
typeof
和那些
&
是非常重要的。看见JS:好的部分。仅供参考:这不是“防护/模式”,也不仅仅是和操作员的正常行为。逻辑运算符(AND、OR、…)的这种行为称为快捷方式求值,它的根源远在C/C++中,甚至更早。并不是每种语言都是这样的-例如VisualBasic(我讨厌它)没有快捷方式:a&&a.b&&a.b.c会在“a”为空时抛出,因为VB计算所有子表达式,然后才执行逻辑and…首先感谢您花时间回答。我相信这个问题是希望得到关于检查对象中是否存在属性的最佳实践的答案。您的回答虽然很深入,但没有回答问题,也没有提供如何检查对象和查看特定属性是否存在的最佳实践。