Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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 如何检查对象链中的任何内容,并在未定义返回false时进行救援?_Javascript - Fatal编程技术网

Javascript 如何检查对象链中的任何内容,并在未定义返回false时进行救援?

Javascript 如何检查对象链中的任何内容,并在未定义返回false时进行救援?,javascript,Javascript,如果您有如下javascript链: user.status.lastOnline ## cannot read property 'status' of undefined 然后,这只是一个错误,你不能做类似的事情 user.status.lastOnline ? 'today' : 'never' 是否有一种优雅的方式来链接在链中任何一点返回false的对象?有什么方便的方法吗 例如: attempt(user.status.lastOnline) ? 'today' : 'never'

如果您有如下javascript链:

user.status.lastOnline ## cannot read property 'status' of undefined
然后,这只是一个错误,你不能做类似的事情

user.status.lastOnline ? 'today' : 'never'
是否有一种优雅的方式来链接在链中任何一点返回false的对象?有什么方便的方法吗

例如:

attempt(user.status.lastOnline) ? 'today' : 'never'

如果status未定义,它的计算结果将为false。

没有内置函数来实现这一点,但您可以编写自己的函数或使用库

在本例中,您将路径元素作为数组而不是虚线字符串传递,因为处理包含点的对象键更容易

function get(rootObject, path) {
  var result = rootObject;

  // use .every instead of .forEach to control when the loop stops
  path.every(function(nextName) {
    var next = result[nextName];
    if(next !== "undefined") {
        result = next;
    }

    return next;
  });

  // return false on incomplete path, as per question
  return result || false;
}

var obj = var obj = { a: 1, b: { c: 2}, d: { "e.f": "g" }, h: [ { first: true }] } 
get(obj, ["a", "x"]); // false
get(obj, ["b", "c"]); // 2
get(obj, ["d", "e.f]) // "g"
get(obj, ["h", 0, "first"]) // true
如果您愿意使用库,那么from可以很好地工作:

获取(用户,“status.lastOnline”)

npm提供了一个独立的软件包,
\uuuGet
,因此您不需要依赖整个lodash来使用它

它经过很好的测试,效率很高,可以处理虚线键等边缘情况。然而,它远远大于上述功能。文件大小约为12kb,或者缩小并压缩了4kb。

尝试以下方法:

var attempt = function( object, path ) {
    var last = object,
        is_exists = true;

    path.split( '.' ).forEach( function( key ) {
        if ( is_exists && last[ key ] !== undefined ) {
            last = last[ key ];
        } else {
            is_exists = false;
        }
    } );

    return is_exists ? last : false;
};

var obj = {
    a: {
        b: {
            c: 1
        }
    }
};

attempt( obj, 'a.b.c' );// returns 1
attempt( obj, 'a.b' );// returns {c: 1}
attempt( obj, 'a.z' );// returns false

前提:我认为规范化数据并确保设置了所有预期属性(可能为null,但设置为set)更方便

如果这是不可能的,我认为唯一可以做你想做的事情,正如在其他答案中所说的,就是通过对象的字符串表示。没有别的办法。但我同意这有点令人讨厌,因为我们的IDE中缺少自动完成和语法突出显示

因此,一种可能的中间方法是,如果未设置完整路径,则创建一个自动构建嵌套对象的函数。在块的开始(但在声明之后)调用此函数,然后在不进行其他检查的情况下执行操作:

var user = {
    say : {
        hello: {
            world : 1
        }
    }
};

ensure("user.status", window);
ensure("user.say.hello", window); //useless here but must not break

console.log(user.status.lastOnline? 1 : 0); // 0
console.log(user.say.hello.world? "yes" : "no"); // yes
console.log(user.say.hello.baby? "yes" : "no"); // no

// closure with a trick
(function() {
    var user = {say:{hello:{world:1}}};

    user = ensure("user.status", {user:user} );

    console.log(user.status.lastOnline? "yes" : "no");
    console.log(user.say.hello.world? "yes" : "no");

})();
确保以以下方式定义

function ensure(obj, root) {
    var parts = obj.split("."), k;
    k = parts.shift();
    if(typeof root[k] === "undefined") {
        root[k] = {};
    }
    if(parts.length > 0) {
        ensure(parts.join("."), root[k]);
    }
    // for closure
    return root[k];
}

另一个解决方案是创建一个静态对象
user
,并设置所有属性,然后使用类似于
jQuery.extend的函数(手工制作并不复杂)来覆盖属性。

您必须创建自己的方法-这不是一种优雅的检查方法。您知道怎么做吗@tymeJVWhat关于尝试。。。抓住。。。?