我有一个从服务器这样调用API的功能:
getDataSet(callback) {
request.open('POST', `${apiPath}`);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.onreadystatechange = function () {
if (request.readyState === XMLHttpRequest.DONE && request.status === 200) {
return callback(null, JSON.parse(request.responseText));
}
};
request.send();
}
dataSetDetail.getDataSet((err, response) => {
if (err) return (console.log(err));
if (response.success) {
let data = response.data.dataSetDetails.slice(0, 10);
}
});
这是服务器端:
router.post('/:projectid/data/:id', isAuthenticated, (req, res, next) => {
let dataSetId = parseInt(req.params.id);
dataSet.getDataSet(dataSetId)
.then(dataSet => {
if (!lodash.isNull(dataSet)) {
res.setHeader('Content-Type', 'application/json');
return res.json({
data: dataSet,
success: true,
});
} else {
logger.error('Cannot find data set with id: ' + dataSetId);
res.redirect('../data');
}
})
.catch(e => {
logger.error(e);
res.redirect('../data');
})
});
服务器的响应是:
[
{
"left": "2",
"right": "3",
"operator": "+"
},
{
"left": "6",
"right": "4"
"operator": "-"
}
]
但是在客户端,我有时收到类似于服务器端的结果,有时如下所示:
[
{
"operator": "+",
"right": "3",
"left": "2",
},
{
"operator": "-",
"right": "4",
"left": "6"
}
]
因为我需要在UI上显示正确的数据位置。请给我建议
答案 0 :(得分:5)
为您提供两个选择:
JSON对象表示法没有顺序。来自http://json.org:
对象是一组无序的名称/值对。
(我的重点。)
尽管JavaScript对象现在具有顺序(自ES2015起),但通常不是最佳实践。
如果您需要订单,特别是如果需要通过JSON保留订单,请使用数组:
[
["2", "3", "+"],
["6", "4", "-"]
]
如果需要属性名称,也发送它们:
{
names: ["left", "right", "operator"],
data: [
["2", "3", "+"],
["6", "4", "-"]
]
}
我强烈推荐此方法,而不是方法2。
dataSet
如果您对使用对象和依赖属性顺序一无所知(建议不),并且两端都使用了JavaScript(看起来好像是这样),并且您在dataSet
上的属性是“自有”属性(未继承),并且它们没有integer index names(您的示例属性没有),然后:
确保按照要序列化属性的顺序在dataSet
中创建对象,例如:
const dataSet = [];
dataSet.push({
left: "2",
right: "3",
operator: "+"
});
或
const dataSet = [];
let entry = {};
entry.left = "2";
entry.right = "3";
entry.operator = "+";
dataSet.push(entry);
// ...
不
const dataSet = [];
let entry = {};
entry.operator = "+"; // *** These are
entry.right = "3"; // *** in the
entry.left = "2"; // *** wrong order
dataSet.push(entry);
// ...
请勿使用for-in
或Object.keys
,未指定它们遵循属性顺序。如果需要按顺序排列属性名称数组,请使用Object.getOwnPropertyNames
。
这些属性将按照您想要的顺序排列,JSON.stringify
被指定为遵循该顺序,并且JSON.parse
被指定为以其顺序在结果中创建对象。因此,即使JSON不能保证顺序,JavaScript的JSON.stringify
和JSON.parse
都只能在非常有限的上下文中使用。
再次,但:不推荐。
但是在客户端,我有时会收到类似于服务器端的结果,有时会如下所示
服务器发送的内容更有可能发生变化(可能基于代码中的分支),并且发生这种情况的原因是,您只是查看了想要的顺序。如果服务器发送了您显示的JSON,则JSON.parse
将保留该顺序(有关原因,请参见上文)。
答案 1 :(得分:1)
实际上,如果您使用(。)点运算符调用值,则JSON属性的顺序将无关紧要。但是您可以使用stringify函数自定义排列。请参阅代码
var output=[
{
"operator": "+",
"right": "3",
"left": "2",
},
{
"operator": "-",
"right": "4",
"left": "6"
}
];
var custom = JSON.parse(JSON.stringify( output, ["left","right","operator"] , 4));
console.log(custom);