有没有一种方法可以确保以特定方式对javascript对象属性进行排序?

时间:2019-02-06 16:48:04

标签: javascript properties

我有一个如下所示的JavaScript对象:

Const data = {
x: 1,
y: 2,
z: 3
a: 4,
b: 5,
c: 6
};

我们在Angular 6应用程序中提供了一个签名服务,该服务对这个对象进行字符串化处理,对字符串进行哈希处理,然后为其添加签名。然后将其保存到Firestore数据库。数据库喜欢按字母顺序对属性进行排序,因此最终看起来像这样:

{
a: 4,
b: 5,
c: 6,
x: 1,
y: 2,
z: 3
}

当我们从数据库中检索此对象并尝试验证签名时,它会失败。之所以失败,是因为当您对 this 对象进行字符串化处理时,与我们对其进行签名时相比,属性的字母顺序会导致生成不同的字符串。这将导致产生与原始签名不匹配的其他哈希值。

我们当前解决此问题的方法是,我们在代码中按字母顺序写出属性的顺序,但是我们想做一个简单的证明(例如,如果另一个开发人员出现并在底部添加了一个属性,说d,但没有意识到它应该按字母顺序排列)。一位同事告诉我,有一种方法可以告诉Javascript根据其自己的算法对属性进行排序。如果可以做到,则在进行字符串化,散列和签名之前,应根据该算法对属性进行排序,然后从数据库中检索对象时,请执行相同的操作:根据Javascript的算法对属性进行排序,对字符串进行字符串化处理,哈希和验证。

有人知道这个Javascript顺序是什么以及如何执行吗?

2 个答案:

答案 0 :(得分:1)

创建一个自定义的stringify函数,该函数可按正确的顺序处理对象。

const data = {
 a: 4,
 b: 5,
 c: 6,
 x: 1,
 y: 2,
 z: 3
}

function customStringify(d){
  return '{'+Object
  .entries(d)
  .sort(([,v1],[,v2])=>v1-v2)
  .map(([k,v])=>`${k}:${v}`)
  .join(",")+'}';
}

const res = customStringify(data);

console.log(res);

答案 1 :(得分:1)

JS无法自然地订购对象,您必须自己动手修改它。

我想到的最简单的方法是使用数组并从那里排序。

这将返回以下数组...

Object.entries(test).sort((a, b) => a[1] - b[1])

返回

[ [ 'x', 1 ],
  [ 'y', 2 ],
  [ 'z', 3 ],
  [ 'a', 4 ],
  [ 'b', 5 ],
  [ 'c', 6 ] ]

如果要将其放回对象中,

Object.assign({}, ...Object.entries(test).sort((a, b) => a[1] - b[1]).map(([key, value]) => ({[key]: value})) )

返回

{ x: 1, y: 2, z: 3, a: 4, b: 5, c: 6 }