Javascript 如何检查对象链中的任何内容,并在未定义返回false时进行救援?
如果您有如下javascript链: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'
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关于尝试。。。抓住。。。?