在 Javascript 中测试未定义的嵌套对象

Testing nested objects as undefined in Javascript

本文关键字:嵌套 对象 未定义 测试 Javascript      更新时间:2023-09-26

可能的重复项:
JavaScript 测试嵌套对象键的存在

我正在尝试通过测试某个对象是否undefined来为formset构建错误消息,如果它不是undefined,那么我最终会用该错误消息填充它。主要问题是我必须验证每个嵌套对象是否undefined,这会导致一些非常丑陋的代码。下面是示例:

errorsForField: function(fieldName, formsetName, formNumber) {
            if (typeof this.model.errors != 'undefined'){
                var fieldError = document.createElement('span');
                $(fieldError).addClass('field-error');
                // THE FOLLOWING LINE THROWS ERROR.
                if (formsetName && _.isUndefined(this.model.errors[formsetName][fieldName]) != true) {
                    $(fieldError).text(this.model.errors[formsetname][fieldName]);
                } else if (typeof this.model.errors[fieldName] != "undefined"){
                    $(fieldError).text(this.model.errors[fieldName]);
                }
                this.errors[fieldName] = fieldError.outerHTML;
                return fieldError.outerHTML; 
            }
            return false; 
        },

收到一个错误,指出我无法确定undefined object this.model.errors[formsetName][fieldName]。换句话说,我必须首先确定this.model.errors[formsetName]是否为空,然后测试[fieldname]是否undefined

这似乎是一个非常繁琐的解决方案。有什么建议可以改变这一点吗?

您可以创建一个库函数,该函数将属性名称作为参数,并返回最终值(如果存在)或 null:

function TryGetPropertyValue(o, propertyName1 /*, ... propertyNameN */) {
    var names = [].slice.call(arguments, 1);
    while (o && names.length) {
        o = o[names.shift()];
    }
    return names.length ? null : o;
}

这样称呼它:

var err = TryGetPropertyValue(this.model.errors, formsetName, fieldName) ||
          TryGetPropertyValue(this.model.errors, fieldName);
if (err != null) {
    $(fieldError).text(err);
}

如果您希望它在找不到字段时返回undefined而不是null,则可以稍微更改函数:

function TryGetPropertyValue(o, propertyName1 /*, ... propertyNameN */) {
    var names = [].slice.call(arguments, 1);
    while (o && names.length) {
        o = o[names.shift()];
    }
    if (names.length == 0) {
        return o;
    }
}

http://jsfiddle.net/HbggQ/

正如Paul所说,这是Javascript的固有限制。 即使是 Coffeescript(它只是 JS 之上的一层语法糖)也不能真正解决问题;它只是将解决方法隐藏在它的语法糖下(诚然,这真的很方便)

如果你想坚持使用Javascript,你基本上有两个选择:使用三元运算符,或者使用布尔运算符。 以下是检查 A.B.C.D 的每个示例(其中 A、B、C 或 D 可能不存在):

// Returns A.B.C.D, if it exists; otherwise returns false (via ternary)
return !A ? false :
            !A.B ? false :
                   !A.B.C ? false :
                            A.B.C.D ? A.B.C.D : false;
// Returns A.B.C.D, if it exists; otherwise returns false (via booleans)
return A && A.B && A.B.C && A.B.C.D;

显然,后者要短得多。 这两种解决方案都依赖于Javascript的"真实性"(即值0""nullundefined算作假)。 这应该适合您的情况,因为这些值都没有 errors 属性。 但是,如果您确实需要区分(例如)0undefined,则可以使用三元样式,并将!A替换为typeof(A) == 'undefined'