什么';在处理多个级别的对象时,确保JavaScript对象已设置且未定义的最佳实践是什么?
我是一名js开发人员,工作环境是我们进行API调用并返回一些数据。返回的数据的结构高度不一致,因此我们不能对返回的数据做任何假设 想象一下以下场景:什么';在处理多个级别的对象时,确保JavaScript对象已设置且未定义的最佳实践是什么?,javascript,jquery,Javascript,Jquery,我是一名js开发人员,工作环境是我们进行API调用并返回一些数据。返回的数据的结构高度不一致,因此我们不能对返回的数据做任何假设 想象一下以下场景: $.ajax({ success: function(data){ // Now I want to access a property 4 levels in var length = data.results.users.length; doSomeStuffWithLength(leng
$.ajax({
success: function(data){
// Now I want to access a property 4 levels in
var length = data.results.users.length;
doSomeStuffWithLength(length);
}
})
确保未定义数据.results.users.length
的正确方法是什么?由于API的不一致性,返回对象的每个级别都可能被破坏/未定义。我真的必须做以下事情吗:
if (data && data.results && data.results.users && data.results.users.length){
var length = data.results.users.length;
doSomeStuffWithLength(length);
}
function getPropByPath(obj, path){
var parts = path.split('.'),
root = obj;
for(var i=0; i<parts.length; i++) {
if(root[parts[i]] !== 'undefined') {
root = root[parts[i]]
} else {
return false;
}
}
return root;
}
难道没有更优雅的解决方案吗?如果在所有级别上都有未定义的内容,您应该检查所有级别,例如:
var length = data &&
data.results &&
data.results.users &&
data.results.users.length || 0;
您还可以使用一些辅助函数。这里有一个:
function getPropValue ( path, defaultIfNotExisting ) {
defaultIfNotExisting = defaultIfNotExisting || 0;
path = path.split('.'), test = this;
while (path.length) {
test = test[path.shift()];
if (!test) {
return defaultIfNotExisting;
}
}
return test;
}
// usage in your case:
if ( getPropValue.call(data, 'results.users', []).length) { /* do stuff */}
如果所有级别都有未定义的内容,则应检查所有级别,例如:
var length = data &&
data.results &&
data.results.users &&
data.results.users.length || 0;
您还可以使用一些辅助函数。这里有一个:
function getPropValue ( path, defaultIfNotExisting ) {
defaultIfNotExisting = defaultIfNotExisting || 0;
path = path.split('.'), test = this;
while (path.length) {
test = test[path.shift()];
if (!test) {
return defaultIfNotExisting;
}
}
return test;
}
// usage in your case:
if ( getPropValue.call(data, 'results.users', []).length) { /* do stuff */}
您可以像这样创建助手函数。 预期对象的结构如下:
var someObj = {
some: {
other: {
third: 'bingo',
qwe: 'test'
}
}
};
如果有这样的东西就太好了
getPropByPath(someObj, 'some.other.qwe');
因此,getPropByPath
的实现可能如下所示:
if (data && data.results && data.results.users && data.results.users.length){
var length = data.results.users.length;
doSomeStuffWithLength(length);
}
function getPropByPath(obj, path){
var parts = path.split('.'),
root = obj;
for(var i=0; i<parts.length; i++) {
if(root[parts[i]] !== 'undefined') {
root = root[parts[i]]
} else {
return false;
}
}
return root;
}
函数getPropByPath(obj,路径){
var parts=path.split('.'),
根=obj;
对于(var i=0;i,您可以像这样创建helper函数。 预期对象的结构如下:
var someObj = {
some: {
other: {
third: 'bingo',
qwe: 'test'
}
}
};
如果有这样的东西就太好了
getPropByPath(someObj, 'some.other.qwe');
因此,getPropByPath
的实现可能如下所示:
if (data && data.results && data.results.users && data.results.users.length){
var length = data.results.users.length;
doSomeStuffWithLength(length);
}
function getPropByPath(obj, path){
var parts = path.split('.'),
root = obj;
for(var i=0; i<parts.length; i++) {
if(root[parts[i]] !== 'undefined') {
root = root[parts[i]]
} else {
return false;
}
}
return root;
}
函数getPropByPath(obj,路径){
var parts=path.split('.'),
根=obj;
对于(var i=0;i向帮助程序提供空数组作为参数的原因是什么?再加上检查
length
-if函数返回数如何?@evgeny:这是因为检查涉及检查返回值的length
属性。如果length
为0,则表达式的计算结果为fals(e/y)
因此,如果getPropValue retursn int 4,您将尝试检查int length并接收未定义的作为结果,尽管函数返回值作为属性doessent existYep进行处理,在本例中为true。请阅读答案中的注释://在您的情况下使用*
。创建/使用帮助器方法不会改变改变程序员需要考虑如何使用它们的事实。为什么要将空数组作为参数提供给帮助程序?再加上检查length
-if函数返回数如何?Evgeniy:这是因为检查涉及检查返回值的length
属性。iflength
是0,表达式的计算结果为fals(e/y)
因此,如果getPropValue retursn int 4,您将尝试检查int length并接收未定义的作为结果,尽管函数返回值作为属性doessent existYep进行处理,在本例中为true。请阅读答案中的注释://在您的情况下使用*
。创建/使用帮助器方法不会改变改变程序员需要考虑如何使用它们的事实。对于您的解决方案-在OPs情况下,他/她需要做:if(getPropByPath(数据,'results.users')&&getPropByPath(数据,'results.users').length)
?看起来有点多余。@KooiInc-hm,不确定你的观点是否正确。我的助手只返回属性值is exists或false。在中描述的情况下,var-value=getPropByPath(数据,'results.users')| |[]//或者您需要作为默认值的任何其他数据类型,lng=value.length
@Evgeniy在for循环中不应该是i=1吗?否则您将从主对象开始。@web潜伏,不,我们应该从0开始。如果我们从1开始,将在主对象中检查第一个属性,它将是其他
,但它不存在。想法是获取>root
object,检查第一个属性是否存在,然后深入并将root
移动到此嵌套属性或返回False以获取解决方案-在OPs情况下,他/她需要执行:if(getPropByPath(data,'results.users')&&getPropByPath(data,'results.users')。length)
?看起来有点多余。@KooiInc-hm,不确定你的观点是否正确。我的助手只返回属性值is exists或false。在中描述的情况下,var-value=getPropByPath(数据,'results.users')| |[]//或者您需要作为默认值的任何其他数据类型,lng=value.length
@Evgeniy在for循环中不应该是i=1吗?否则您将从主对象开始。@web潜伏,不,我们应该从0开始。如果我们从1开始,将在主对象中检查第一个属性,它将是其他
,但它不存在。想法是获取>root
对象,检查第一个属性是否存在,然后深入并将root
移动到此嵌套属性或返回false