我有一个这样的数据结构:
var someObject = {
'part1' : {
'name': 'Part 1',
'size': '20',
'qty' : '50'
},
'part2' : {
'name': 'Part 2',
'size': '15',
'qty' : '60'
},
'part3' : [
{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
}, {
'name': 'Part 3B',
'size': '5',
'qty' : '20'
}, {
'name': 'Part 3C',
'size': '7.5',
'qty' : '20'
}
]
};
我想使用这些变量访问数据:
var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";
part1name应该用someObject.part1.name的值填充,即“Part 1”。part2quantity也是一样,它的容量是60。
有没有办法实现这与纯javascript或JQuery?
AngularJS有$scope.$eval
在AngularJS中,我们可以使用$scope。$eval方法访问嵌套对象:
$scope.someObject = someObject;
console.log( $scope.$eval("someObject.part3[0].name") ); //Part 3A
有关更多信息,请参见
AngularJS $scope API引用- $eval
演示
angular.module("app",[])
.run(function($rootScope) {
$rootScope.someObject = {
'part2' : {
'name': 'Part 2',
'size': '15',
'qty' : '60'
},
'part3' : [{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
},{
name: 'Part 3B'
}]
};
console.log(
"part3[0].name =",
$rootScope.$eval("someObject.part3[0].name")
);
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app"
</body>
数组可以代替字符串来处理嵌套对象和数组,例如:["my_field", "another_field", 0, "last_field", 10]
下面是一个基于该数组表示方式更改字段的示例。我在react.js中使用类似的东西来控制输入字段,改变嵌套结构的状态。
let state = {
test: "test_value",
nested: {
level1: "level1 value"
},
arr: [1, 2, 3],
nested_arr: {
arr: ["buh", "bah", "foo"]
}
}
function handleChange(value, fields) {
let update_field = state;
for(var i = 0; i < fields.length - 1; i++){
update_field = update_field[fields[i]];
}
update_field[fields[fields.length-1]] = value;
}
handleChange("update", ["test"]);
handleChange("update_nested", ["nested","level1"]);
handleChange(100, ["arr",0]);
handleChange('changed_foo', ["nested_arr", "arr", 3]);
console.log(state);
如果你需要访问不同的嵌套键,而不知道它在编码时(这将是微不足道的),你可以使用数组符号访问器:
var part1name = someObject['part1']['name'];
var part2quantity = someObject['part2']['qty'];
var part3name1 = someObject['part3'][0]['name'];
它们等价于点符号访问器,并且可能在运行时发生变化,例如:
var part = 'part1';
var property = 'name';
var part1name = someObject[part][property];
等于
var part1name = someObject['part1']['name'];
or
var part1name = someObject.part1.name;
我希望这能解决你的问题…
EDIT
我不会使用字符串来维护某种xpath查询来访问对象值。
因为你必须调用一个函数来解析查询和检索值,我会遵循另一条路径(不是:
var part1name = function(){ return this.part1.name; }
var part2quantity = function() { return this['part2']['qty']; }
var part3name1 = function() { return this.part3[0]['name'];}
// usage: part1name.apply(someObject);
或者,如果你不习惯apply方法
var part1name = function(obj){ return obj.part1.name; }
var part2quantity = function(obj) { return obj['part2']['qty']; }
var part3name1 = function(obj) { return obj.part3[0]['name'];}
// usage: part1name(someObject);
函数更短,更清晰,解释器会为你检查语法错误等等。
顺便说一下,我觉得在适当的时候做一个简单的任务就足够了……
受到@webjay的回答的启发:
https://stackoverflow.com/a/46008856/4110122
我做了这个函数,你可以用它来获取/设置/取消设置对象中的任何值
function Object_Manager(obj, Path, value, Action)
{
try
{
if(Array.isArray(Path) == false)
{
Path = [Path];
}
let level = 0;
var Return_Value;
Path.reduce((a, b)=>{
level++;
if (level === Path.length)
{
if(Action === 'Set')
{
a[b] = value;
return value;
}
else if(Action === 'Get')
{
Return_Value = a[b];
}
else if(Action === 'Unset')
{
delete a[b];
}
}
else
{
return a[b];
}
}, obj);
return Return_Value;
}
catch(err)
{
console.error(err);
return obj;
}
}
使用它:
// Set
Object_Manager(Obj,[Level1,Level2,Level3],New_Value, 'Set');
// Get
Object_Manager(Obj,[Level1,Level2,Level3],'', 'Get');
// Unset
Object_Manager(Obj,[Level1,Level2,Level3],'', 'Unset');
AngularJS有$scope.$eval
在AngularJS中,我们可以使用$scope。$eval方法访问嵌套对象:
$scope.someObject = someObject;
console.log( $scope.$eval("someObject.part3[0].name") ); //Part 3A
有关更多信息,请参见
AngularJS $scope API引用- $eval
演示
angular.module("app",[])
.run(function($rootScope) {
$rootScope.someObject = {
'part2' : {
'name': 'Part 2',
'size': '15',
'qty' : '60'
},
'part3' : [{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
},{
name: 'Part 3B'
}]
};
console.log(
"part3[0].name =",
$rootScope.$eval("someObject.part3[0].name")
);
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app"
</body>