programing

JSON.stringify가 삭제하지 않은 미정의 보존

lastmemo 2023. 3. 17. 19:33
반응형

JSON.stringify가 삭제하지 않은 미정의 보존

보존 방법undefined할 때의 가치관JSON.stringify(hash)?

다음은 예를 제시하겠습니다.

var hash = {
  "name" : "boda",
  "email" : undefined,
  "country" : "africa"
};

var string = JSON.stringify(hash);

// > '{"name":"boda","country":"africa"}'

에서 이메일이 사라졌습니다.JSON.stringify.

JSON 사양에서는 허용되지 않습니다.undefined값, 단,null가치.

리페이서 기능을 다음에 전달할 수 있습니다.JSON.stringify자동적으로 변환하다undefined에 대한 가치관null다음과 같은 값:

var string = JSON.stringify(
  obj,
  function(k, v) { return v === undefined ? null : v; }
);

이는 어레이 내부의 정의되지 않은 값에도 적용됩니다.JSON.stringify이미 그것들을 로 변환하고 있다.null.

로 변환하면 키를 유지할 수 있습니다.null유효한 JSON 에서는,undefined;

간단한 라이너 1개:

JSON.stringify(obj, (k, v) => v === undefined ? null : v)

이거면 충분할 거야

// Since 'JSON.stringify' hides 'undefined', the code bellow is necessary in
// order to display the real param that have invoked the error.
JSON.stringify(hash, (k, v) => (v === undefined) ? '__undefined' : v)
    .replace(/"__undefined"/g, 'undefined')

사용하다null대신undefined.

var hash = {
  "name" : "boda",
  "email" : null,
  "country" : "africa"
};

var string = JSON.stringify(hash);

> "{"name":"boda","email":null,"country":"africa"}"

여기 행간을 읽고 JSON.parse를 사용할 때 값을 정의하지 않는 것이 좋다고 생각하십니까?

이 경우 다음을 사용할 수 있습니다.

var encodeUndefined = function(obj, undefinedPaths, path) {
  path = path || 'ROOT';
  for (var key in obj) {
    var keyPath = path + '.' + key;
    var value = obj[key];
    if (value === undefined) {
      undefinedPaths.push(keyPath);
    } else if (typeof value == "object" && value !== null) {
      encodeUndefined(obj[key], undefinedPaths, keyPath);
    }
  }
}

var stringifyAndPreserveUndefined = function(obj) {
  var undefinedPaths = [];
  //save all paths that have are undefined in a array.
  encodeUndefined((obj), undefinedPaths);
  return JSON.stringify({
    ROOT: obj,
    undefinedPaths: undefinedPaths
  }, function(k, v) { if (v === undefined) { return null; } return v; });
}

var parseAndRestoreUndefined = function(value) {
  var data = JSON.parse(value);
  var undefinedPaths = data.undefinedPaths;
  var obj = data.ROOT;
  //Restore all undefined values
  for (var pathIndex = 0; pathIndex < undefinedPaths.length; pathIndex++) {
    var pathParts = undefinedPaths[pathIndex].substring(5).split('.');
    var item = obj;
    for (var pathPartIndex = 0; pathPartIndex < pathParts.length - 1; pathPartIndex++) {
      item = item[pathParts[pathPartIndex]];
    }
    item[pathParts[pathParts.length - 1]] = undefined;
  }
  return obj;
}

var input = {
  test1: 'a',
  test2: 'b',
  test3: undefined,
  test4: {
    test1: 'a',
    test2: undefined
  }
};
var result = stringifyAndPreserveUndefined(input);
var result2 = parseAndRestoreUndefined(result);

stringifyAndPreserveUndefined를 호출하면 어레이 내의 정의되지 않은 모든 값이 인코딩됩니다.parseAndRestoreUndefined다시 올바른 위치에 놓이게 됩니다.

한 가지 단점은 json이 개체와 완전히 닮지 않는다는 것입니다.위의 예에서는 다음과 같이 변환됩니다.{"ROOT":{"test1":"a","test2":"b","test4":{"test1":"a"}},"undefinedPaths":["ROOT.test3","ROOT.test4.test2"]}

function stringifyWithUndefined(value: any, space: number): string {
  const str = JSON.stringify(
    value,
    (_k, v) => v === undefined ? '__UNDEFINED__' : v,
    space
  );
  return str.replaceAll('"__UNDEFINED__"', 'undefined');
}

예 1:

const object = {
  name: 'boda',
  email: undefined,
  country: 'africa'
};
console.log(stringifyWithUndefined(object, 2));

결과(문자열):

{
  "name": "boda",
  "email": undefined,
  "country": "africa"
}

예 2:

const array = [object, { object }, [[object]]];
console.log(stringifyWithUndefined(array, 2));

결과(문자열):

[
  {
    "name": "boda",
    "email": undefined,
    "country": "africa"
  },
  {
    "object": {
      "name": "boda",
      "email": undefined,
      "country": "africa"
    }
  },
  [
    [
      {
        "name": "boda",
        "email": undefined,
        "country": "africa"
      }
    ]
  ]
]



주의:undefined유효한 JSON이 아닙니다.JSON.parse()에 실패하다SyntaxError: Unexpected token [...] is not valid JSON라고 하면stringifyWithUndefined()

JSON 에는,undefined회피책을 작성할 수 있습니다.

중첩된 정의되지 않은 값 보존

내부적으로 사용하는 기능 2개를 작성했습니다.JSON.stringify그리고.JSON.parse네스트된 데이터 저장undefined값 자리 표시자를 사용한 값:

등가JSON.stringify:

/**
 * Serialize a POJO while preserving nested `undefined` values.
 */
function serializePOJO(value, undefinedPlaceholder = "[undefined]") {
  const replacer = (key, value) => (value === undefined ? undefinedPlaceholder : value);
  return JSON.stringify(value, replacer);
}

등가JSON.parse:

/**
 * Deserialize a POJO while preserving nested `undefined` values.
 */
function deserializePOJO(value, undefinedPlaceholder = "[undefined]") {
  const pojo = JSON.parse(value);
  if (pojo === undefinedPlaceholder) {
    return undefined;
  }

  // Function that walks through nested values
  function deepIterate(value, callback, parent, key) {
    if (typeof value === "object" && value !== null) {
      Object.entries(value).forEach(([entryKey, entryValue]) => deepIterate(entryValue, callback, value, entryKey));
    } else if (Array.isArray(value)) {
      value.forEach((itemValue, itemIndex) => deepIterate(itemValue, callback, value, itemIndex));
    } else if (parent !== undefined) {
      callback(value, parent, key);
    }
  }

  // Replaces `undefined` placeholders
  deepIterate(pojo, (value, parent, key) => {
    if (value === undefinedPlaceholder) {
      parent[key] = undefined;
    }
  });

  return pojo;
}

사용방법:

const source = {
    foo : undefined,
  bar : {
   baz : undefined
  }
};

const serialized = serializePOJO(source);
console.log("Serialized", serialized);
// '{"foo":"[undefined]","bar":{"baz":"[undefined]","qux":[1,"[undefined]",2]}}'

const deserialized = deserializePOJO(serialized);
console.log("Deserialized", deserialized);

개체 항목과 배열 항목 모두에서 작동합니다.

단점은 "실제" 소스 값을 통해 실수하지 않는 적절한 자리 표시자를 선택해야 한다는 것입니다.플레이스 홀더는 옵션에서 커스터마이즈 가능undefinedPlaceholder논쟁.

이것은 POJO를 브라우저 로컬 스토리지에 저장하는 데 특히 유용합니다.

다음 항목도 참조하십시오.

이렇게 하면 다음과 같이 인쇄됩니다.undefined그러나 이것은 INVALID json이지만 유효한 JavaScript입니다.

var string = JSON.stringify(obj, function(k,v){return v===undefined?"::undefined::":v}, 2).replace(new RegExp("\"::undefined::\"", 'g'), "undefined");

언급URL : https://stackoverflow.com/questions/26540706/preserving-undefined-that-json-stringify-otherwise-removes

반응형