用于返回Javascript对象中深层属性值的方法的比较

用于返回Javascript对象中深层属性值的方法的比较,javascript,Javascript,考虑以下公司目标: var雇员={ empID:45435, 工资:44000, 职务:看门人, 名字:Richard, 姓:史泰尔曼 } var部门={ 名称:维修,, 建筑:H, 房间:404, 部门领导:员工 } var公司={ 名称:Bluth原汁原味的冷冻香蕉摊, 收入:“始终”, 维修部门:部门 } 如果我想访问employee对象的title属性,我可以使用以下内容引用它: var title = company.maintenanceDept.departmentLead.tit

考虑以下公司目标:

var雇员={ empID:45435, 工资:44000, 职务:看门人, 名字:Richard, 姓:史泰尔曼 } var部门={ 名称:维修,, 建筑:H, 房间:404, 部门领导:员工 } var公司={ 名称:Bluth原汁原味的冷冻香蕉摊, 收入:“始终”, 维修部门:部门 } 如果我想访问employee对象的title属性,我可以使用以下内容引用它:

var title = company.maintenanceDept.departmentLead.title;
但是,如果departmentLead未定义,将抛出TypeError。所以,在访问标题之前,我必须编写一个测试:

这是最好的方法吗?显然,这个例子是人为的,因为我在使用它之前定义了company,所以我知道title是存在的。对于从AJAX调用返回的company对象,情况并非如此。我一直在使用的一个方法是:

//编辑:我被告知向Object.prototype添加属性不是一件明智的事情…所以不要这样做 Object.prototype.propertyWithPath=函数路径{ var keys=path.split'; var parent=此; var-child; 对于变量i=0;i除了对性能的影响,使用这种方法与替代方法相比还有什么缺点吗?

您可以选择进行内联测试或使用类似于您所展示的功能。但请参见关于这个问题的评论:永远不要将可枚举属性添加到Object.prototype。改用非原型函数

请注意,测试不必是if,您可以执行以下操作:

var title = company && 
            company.maintenanceDept && 
            company.maintenanceDept.departmentLead &&
            company.maintenanceDept.departmentLead.title;

title要么是未定义的,要么是另一个假值,或者是title,因为JavaScript的&&运算符是:如果左侧的值是假值,则返回该值;否则,它将返回右侧的值。它并不总是像在许多其他语言中那样返回true或false。所以5&&7是7;0&&7是0。

除了您提到的明显的性能影响之外,这足以避免它,这里还有另一个缺点:

Object.prototype.propertyWithPath = function (path) {
    var keys = path.split('.');
    var parent = this;
    var child;

    for (var i = 0; i < keys.length; i++) {
        child = keys[i];

        if (parent[child] === undefined) {
            return undefined;
        }
        parent = parent[child];
    }
    return parent;
};

var foo = { bar: 1 };

for(var prop in foo)
    console.log(prop); //bar, propertyWithPath

如果要扩展Object.prototype,请使用并使其不可枚举。

您只需将其包装在一个try块中即可:

try {
    company.maintenanceDept.departmentLead.title
} catch (e) {
    // You can run a regex on e.message to get the child property that caused the issue
}

可以使用工厂方法生成对象。这样,属性将始终存在:

var employee = function(params){
    return {
        empID: params.empID || false,
      salary: params.salary || false,
      title: params.title || '',
      firstName: params.firstName || '',
      lastName: params.lastName || ''
    };
}



var department = function(params){
    return {
        name: params.name || '',
        building: params.building || '',
        room: params.room || 0,
        departmentLead: params.employee || employee({})
    }
}

var emp1 = employee({
    empID: 45435,
    salary: 44000,
    title: "Janitor",
    firstName: "Richard",
    lastName: "Stallman"
})

var emp2 = employee({});

var dep1 = department({
    name: "Maintenance",
    building: "H",
    room: 404,
    departmentLead: emp1
})

var dep2 = department({});

console.log(dep2.departmentLead.firstName);

Object.prototype.propertyWithPath=的可能重复项。。。切勿将可枚举属性添加到Object.prototype。因此,您将破坏的代码数量之大令人震惊。通常,不要使用Object.prototype。如果必须添加,请仅通过Object.defineProperty添加不可枚举的属性,并注意Object.defineProperty不能在IE8等ES5之前的引擎上正确填充。@T.J.Crowder你说得对,这是一件令人头疼的事情。try/catch对编译器优化有什么影响?当然,这是,在未找到的情况下速度较慢有时在找到的情况下,我也有点惊讶地看到。但99%的时候,你根本不在乎速度。顺便说一句,这不是我的反对票。谢谢你的回答,但我的问题更多地集中在我自己没有创建的对象上。例如:从API调用返回的JSON对象。
var employee = function(params){
    return {
        empID: params.empID || false,
      salary: params.salary || false,
      title: params.title || '',
      firstName: params.firstName || '',
      lastName: params.lastName || ''
    };
}



var department = function(params){
    return {
        name: params.name || '',
        building: params.building || '',
        room: params.room || 0,
        departmentLead: params.employee || employee({})
    }
}

var emp1 = employee({
    empID: 45435,
    salary: 44000,
    title: "Janitor",
    firstName: "Richard",
    lastName: "Stallman"
})

var emp2 = employee({});

var dep1 = department({
    name: "Maintenance",
    building: "H",
    room: 404,
    departmentLead: emp1
})

var dep2 = department({});

console.log(dep2.departmentLead.firstName);