Is it a bad practice to use JSON strings as keys of objects?

On languages such as Haskell, most datatypes have instances which allow their values to be used as keys of structures such as Maps. JavaScript has reasonably fast maps, there called objects, but those only accept string keys. Is there any conceptual issue, or anything else to be worried of, in using JSON strings as keys of objects in order to emulate what Haskell does? I.e.,

var point = {"x": 7, "y": 8, "z": 9};
var pointColor = {};
pointColor[JSON.stringify(point)] = "blue";

3

On languages such as Haskell, most datatypes have instances which allow their values to be used as keys of structures such as Maps.

It’s the same in ECMAScript. Any object, including primitives, can be used as the key in a Map. Even NaN, even though NaN !== NaN // true does the right thing and can be reasonably used as the key in a Map.

JavaScript has reasonably fast maps, there called objects, but those only accept string keys.

They also accept Symbol keys.

Plus, ECMAScript does have a native Map data type as well.

Is there any conceptual issue, or anything else to be worried of, in using JSON strings as keys of objects in order to emulate what Haskell does?

Different objects may have the same JSON representation, and the same object may have multiple JSON representations.

The easiest solution would be to use the standard Map data type:

const point = {x: 7, y: 8, z: 9};
const pointColor = new Map();
pointColor.set(point, "blue");

for (let [{x, y, z}, color] of pointColor) console.log(`{x: ${x}, y: ${y}, z: ${z}} = ${color}`);
// {x: 7, y: 8, z: 9} = blue

What you really want is a Map, not an object:
Map

You need to check if the support you need to provide fits with the Map supported browsers, but that´s what you really want as objects only take strings or symbols as keys while a map can take anything

Here is an example of its usage:

  var point1 = {"x": 7, "y": 8, "z": 9};
  var point2 = {"x": 6, "y": 5, "z": 4};

  var pointColor = new Map();
  pointColor.set(point1,'blue');
  pointColor.set(point2,'red');
  console.log(pointColor, pointColor.get(point1))

2

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *