我注意到如果我们在数据库中插入一个对象{a:1,b:2,c:3},它将被存储为{c:3,b:2,a:1}。为什么MongooseJS会这样做?
是否为性能增益(或)其他逻辑?
有人可以向我详细解释一下吗?
答案 0 :(得分:1)
对象中没有属性顺序。如果订单对您很重要,请使用数组。
for ... in语句以原始插入顺序迭代对象的可枚举属性。对于每个不同的财产[...]
然而,这似乎是实现(浏览器)依赖 在对象中,您不能依赖属性的顺序,因为即使各种迭代方法也可能给出各种结果。
答案 1 :(得分:0)
对象中属性的排序很复杂,因为这个答案解释了:https://stackoverflow.com/a/38218582/893780
即使标准中未指定,普通属性键也按插入顺序存储。
在内部,Mongoose在克隆对象时使用更快的代码路径,从而反转属性顺序。它基本上是这样做的:
let oldObject = { a: 1, b: 2, c: 3 };
let newObject = {};
let keys = Object.keys(oldObject);
let i = keys.length;
while (i--) {
let k = keys[i];
let val = oldObject[k];
newObject[k] = val;
}
由于普通密钥按插入顺序存储,newObject
将与oldObject
相反:
{ c: 3, b: 2, a: 1 }
但是,由于这可能会导致查询出现问题,因此Mongoose添加了一个选项retainKeyOrder
来阻止这种反转。
但是,根据我上面提到的相同答案,您仍然无法依赖使用Object.keys()
或for..in
时强加的任何订单。