Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.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_Node.js_Coffeescript - Fatal编程技术网

用于检查未定义值的优雅Javascript代码

用于检查未定义值的优雅Javascript代码,javascript,node.js,coffeescript,Javascript,Node.js,Coffeescript,所以我有一个回调函数,它提供了一个json对象: function(object){ var data=object.packet.link.ip.tcp.data; console.log(data.toString()); } 我遇到的问题是,任何packet/link/ip/tcp/data都可能是“未定义的”——我的node.js程序每次遇到未定义的变量都会崩溃 我尝试将“数据”声明放在try/catch中,但是我不断得到“未定义”错误-我猜我需要将object/obj

所以我有一个回调函数,它提供了一个json对象:

function(object){
    var data=object.packet.link.ip.tcp.data;
    console.log(data.toString());
}
我遇到的问题是,任何packet/link/ip/tcp/data都可能是“未定义的”——我的node.js程序每次遇到未定义的变量都会崩溃

我尝试将“数据”声明放在try/catch中,但是我不断得到“未定义”错误-我猜我需要将object/object.packet/object.packet.link/object.packet.link.ip/etc.放在try/catch中

所以,我找到了一些优雅的咖啡脚本:

if object?.packet?.link?.ip?.tcp?.data? then doStuff()
其汇编目的是:

var _ref, _ref1, _ref2, _ref3;

if ((typeof object !== "undefined" && object !== null ? (_ref = object.packet) != null ? (_ref1 = _ref.link) != null ? (_ref2 = _ref1.ip) != null ? (_ref3 = _ref2.tcp) != null ? _ref3.data : void 0 : void 0 : void 0 : void 0 : void 0) != null) {
       //doStuff:
       var data = object.packet.link.ip.tcp.data;
       console.log(data.toString());
}
恶心


现在它工作得非常完美,但我只是想知道是否有一种更优雅(可读)的方法可以在纯Javascript中实现这一点?

如果它足以检查您是否在处理真实值,您可能会

var data = object && object.packet && object.packet.link && object.packet.link.ip; // etc.
仍然没有美丽,但很可能是你能追求的最好的。当然,您始终可以选择引入好的ol'
try..catch
子句

try {
    var data = object.packet.link.ip.tcp.data;
} catch( ex ) { }
任何比“优雅”更好的东西(无论是谁定义的)都需要一个自定义编写的函数,它一步一步地遍历对象属性,检查是否存在。

你可以这样做

["packet", "link", "ip", "tcp", "data"]
  .reduce(function (m, i) { if (m) return m[i]; }, object);
您可以将
reduce
移动到一个函数中,并使
get(对象、“数据包”、“链接”、“ip”、“tcp”、“数据”)
。虽然简单的
&&
解决方案可能更明智,但它可能很漂亮

function A(object)
{
 var data = object?object.packet?object.packet.link?object.packet.link.ip?object.packet.link.ip.tcp?  object.packet.link.ip.tcp.data:null:null:null:null:null;
 console.log(data);
}
  • 注意

    如果数据为null,则不能在null上调用toString,因为null(以及未定义的)是仅有的两个原语,它们没有对象包装器,随后也没有toString()函数


Hi,我尝试了try/catch——尽管我在深度嵌套方面遇到了问题,并且不断出现“未定义”错误……coffeescript中存在运算符的优点在于它具有上下文感知能力(因为编译步骤)。但我认为这是一个代码气味链深。我非常喜欢这种简化解决方案。在工作中我做了这样一个:
get(object,'packet.link.ip.tcp.data')
。它与您的几乎相同,只是有一个
.split('.')
调用。@Cory,这很好,直到您需要使用对象
{“packet.link.ip.tcp.data”:…}
。是的,我们通常不允许使用此类密钥。如果出现类似的情况,我们确实有另一种方法,它采用数组。因为这与您的方法相同,所以在您指出在某些情况下这是必要的之前,它似乎不值得一提。