Javascript 有多少对null的检查是合适的?

Javascript 有多少对null的检查是合适的?,javascript,coding-style,Javascript,Coding Style,当一个变量缺少一个字段,用户看到这个或那个变量没有这个或那个属性的警告时,我就遇到了这个问题。在简单的情况下,这是非常直接的 if(field) doSomething(field.subField); 然而,在实证的情况下,我发现自己陷入了这种荒谬的过度检查 if(!data || !data.records || !data.records[0] || !data.records[0].field || !data.records[0].field.id)

当一个变量缺少一个字段,用户看到这个或那个变量没有这个或那个属性的警告时,我就遇到了这个问题。在简单的情况下,这是非常直接的

if(field)
  doSomething(field.subField);
然而,在实证的情况下,我发现自己陷入了这种荒谬的过度检查

if(!data 
  || !data.records 
  || !data.records[0] 
  || !data.records[0].field 
  || !data.records[0].field.id)
    return null;
doSomething(data);

我的意思是,得了吧,如果我是一个水管工,而不是开发人员的话,这玩意儿看起来就像是管子一样。所以,我有一种非常强烈的感觉,我的支票虽然足够,但可能有点过火了。JS中是否有关于何时执行检查的约定?

通常,您会确保如果对象存在,它总是有一组基本的属性使其可用

例如,如果变量
data
有一个值,那么它将是一个对象,该对象具有
记录
属性,该属性始终是一个数组,即使它是空的。如果数组包含任何内容,则它应该始终是具有
字段
属性的对象,该属性是始终具有
id
属性的对象。这将把支票减少到:

if (!data || data.records.length == 0) {
  return null;
}

我将提出一个有争议的观点

在JavaScript中,不要在实际不应该出现这种情况的地方检查
null
值。换句话说,检查每个嵌套属性是否为null的想法有点过分,只会使脚本复杂化

根据我的经验,我学会了让脚本错误发生。对于编写C代码或数据库代码的人来说,这有点违反直觉,因为未经处理的
null
可能会导致服务器崩溃或数据损坏,但是在脚本世界中,最好尽早发现错误。如果您的页面继续加载,而没有任何迹象表明发生了意外情况,那么稍后当用户单击按钮或提交表单时,它将以奇怪的错误的形式出现

我的建议


只有在您愿意采取措施的情况下,才检查
null
。如果您的web服务在出现问题时可能返回
null
,请检查并显示错误消息。如果返回一个非空值,则假定它是有效值并继续。没有理由在整个脚本中乱扔空值检查,因为空值检查实际上不会给您的程序带来任何实际好处。

如果您需要经常这样做,您的代码可能会遇到比您想象的更多的问题。有一个库可能会有所帮助:不如改用?+1@Blazemonger。我认为Python有支持这一点的理由,但我不记得它叫什么。从您的代码来看,您似乎在验证JSON或类似的结构。如果您真的需要这样做,我建议将您的验证代码重构为一个单独的函数。当客户厌倦了获取错误消息并判断每一条消息都是世界末日时,问题就会出现。现在,我已经接管了其他人的代码,所以我将不得不带着常量“再次出现错误”离开——我头上的云。不过,总的来说,我喜欢你的想法。我可能只会抛出一个try/catch,只向我报告错误,这样用户就不会受到错误消息的重击。谢谢大多数浏览器也支持
窗口.onerror
事件,因此您可以捕获此事件并安静地进行日志记录。我不知道这一点。你的意思是我可以进入
window.onerror=function(){…}
内部
window.onload
method?!还是应该把它放在同一水平面上,与之平行?它能保证捕获所有的错误吗?或者我仍然需要使用try-catch吗?是的,与它并行可能是最好的。我不知道它是否保证捕获所有错误,每个浏览器对它的支持都不同。如果您需要捕获所有内容,可能需要使用
try/catch
。我喜欢这个主意。然而,正如我在下面评论的那样,我很高兴在一个不那么精明的程序员之后接管了这个项目,而库索姆特不愿意为重新开发买单。他们只付我们“修理和修补”的钱。在回顾中,我不应该同意这个项目,但我在想“嘿,这只是JS,修复一些bug有多难?”。现在我站在这里像个傻瓜…根据我的经验,Javascript是最容易出现疯狂方法、疯狂代码、功能错误理解的环境,当然,如果。。。调试非常困难。如果未定义
记录
,此方法将导致未捕获的错误。如果您确实需要捕获所有错误,请使用
try/catch
@KubaHoluj:您没有抓住要点。如果使用答案中给出的方法,
记录
属性永远不会未定义。