[javascript] ES6 맵을 JSON.stringify하는 방법은 무엇입니까?

JS 객체 대신 ES6 Map을 사용하고 싶지만 JSON.stringify ()지도를 만드는 방법을 알 수 없기 때문에 보류되고 있습니다. 내 키는 문자열로 보장되며 내 값은 항상 나열됩니다. 직렬화하려면 래퍼 메서드를 작성해야합니까?



답변

당신은 할 수 없습니다.

지도의 키는 객체를 포함하여 무엇이든 될 수 있습니다. 그러나 JSON 구문은 문자열을 키로 만 허용합니다. 따라서 일반적인 경우에는 불가능합니다.

내 키는 문자열이 보장되고 내 값은 항상 목록이됩니다.

이 경우 일반 개체를 사용할 수 있습니다. 다음과 같은 장점이 있습니다.

  • JSON으로 문자열화할 수 있습니다.
  • 이전 브라우저에서 작동합니다.
  • 더 빠를 수 있습니다.


답변

Map속성이 없기 때문에 인스턴스를 직접 문자열화할 수는 없지만 튜플 배열로 변환 할 수 있습니다.

jsonText = JSON.stringify(Array.from(map.entries()));

반대의 경우

map = new Map(JSON.parse(jsonText));


답변

모두 JSON.stringifyJSON.parse두 번째 인수를 지원합니다. replacer그리고 reviver각각. 아래의 replacer 및 reviver를 사용하면 깊이 중첩 된 값을 포함하여 기본 Map 개체에 대한 지원을 추가 할 수 있습니다.

function replacer(key, value) {
  const originalObject = this[key];
  if(originalObject instanceof Map) {
    return {
      dataType: 'Map',
      value: Array.from(originalObject.entries()), // or with spread: value: [...originalObject]
    };
  } else {
    return value;
  }
}
function reviver(key, value) {
  if(typeof value === 'object' && value !== null) {
    if (value.dataType === 'Map') {
      return new Map(value.value);
    }
  }
  return value;
}

사용법 :

const originalValue = new Map([['a', 1]]);
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);

배열, 객체 및 맵의 조합을 사용한 깊은 중첩

const originalValue = [
  new Map([['a', {
    b: {
      c: new Map([['d', 'text']])
    }
  }]])
];
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);


답변

아직 ecmascript에서 제공하는 메서드는 없지만 을 JavaScript 기본 형식에 JSON.stingify매핑하는 경우 계속 사용할 수 있습니다 Map. 다음은 Map우리가 사용할 샘플 입니다.

const map = new Map();
map.set('foo', 'bar');
map.set('baz', 'quz');

자바 스크립트 개체로 이동

다음 도우미 함수를 사용하여 JavaScript 개체 리터럴로 변환 할 수 있습니다.

const mapToObj = m => {
  return Array.from(m).reduce((obj, [key, value]) => {
    obj[key] = value;
    return obj;
  }, {});
};

JSON.stringify(mapToObj(map)); // '{"foo":"bar","baz":"quz"}'

객체의 JavaScript 배열로 이동

이것에 대한 도우미 기능은 훨씬 더 간결합니다

const mapToAoO = m => {
  return Array.from(m).map( ([k,v]) => {return {[k]:v}} );
};

JSON.stringify(mapToAoO(map)); // '[{"foo":"bar"},{"baz":"quz"}]'

배열 배열로 이동

이것은 더 쉽습니다.

JSON.stringify( Array.from(map) ); // '[["foo","bar"],["baz","quz"]]'


답변

스프레드 구문 맵을 사용하여 한 줄로 직렬화 할 수 있습니다.

JSON.stringify([...new Map()]);

다음을 사용하여 역 직렬화합니다.

let map = new Map(JSON.parse(map));


답변

Map인스턴스 문자열 화 (객체를 키로해도 괜찮음) :

JSON.stringify([...map])

또는

JSON.stringify(Array.from(map))

또는

JSON.stringify(Array.from(map.entries()))

출력 형식:

// [["key1","value1"],["key2","value2"]]


답변

더 나은 솔루션

    // somewhere...
    class Klass extends Map {

        toJSON() {
            var object = { };
            for (let [key, value] of this) object[key] = value;
            return object;
        }

    }

    // somewhere else...
    import { Klass as Map } from '@core/utilities/ds/map';  // <--wherever "somewhere" is

    var map = new Map();
    map.set('a', 1);
    map.set('b', { datum: true });
    map.set('c', [ 1,2,3 ]);
    map.set( 'd', new Map([ ['e', true] ]) );

    var json = JSON.stringify(map, null, '\t');
    console.log('>', json);

산출

    > {
        "a": 1,
        "b": {
            "datum": true
        },
        "c": [
            1,
            2,
            3
        ],
        "d": {
            "e": true
        }
    }

위의 답변보다 덜 까다롭기를 바랍니다.