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