programing

상속된 개체를 JSON으로 문자열화하는 방법

telebox 2023. 3. 18. 08:29
반응형

상속된 개체를 JSON으로 문자열화하는 방법

JSON.stringify()를 사용할 때 json2.js는 부모 객체의 멤버를 무시하는 것 같습니다.예:

require('./json2.js');

function WorldObject(type) {    
    this.position = 4;
}

function Actor(val) {
    this.someVal = 50;
}

Actor.prototype = new WorldObject();

var a = new Actor(2);

console.log(a.position);
console.log(JSON.stringify(a));

출력은 다음과 같습니다.

4
{"someVal":50}

다음과 같은 출력이 예상됩니다.

4
{"position":0, "someVal":50}

뭐, 원래 그렇긴 하지만JSON.stringify는 객체의 소유자가 아닌 속성을 보존하지 않습니다.다른 결점과 가능한 회피책에 대한 흥미로운 논의를 여기에서 볼 수 있습니다.

또한 저자는 문제를 문서화할 뿐만 아니라 Hydrate라는 라이브러리도 작성했습니다.JS가 도움이 될 겁니다.

그 문제는 첫눈에 보이는 것보다 조금 더 심각하다.라 할지라도a에 대해 정말로 엄격히 할 것이다.{"position":0, "someVal":50}그런 다음 나중에 해석하면 원하는 속성을 가지지만 Actor 인스턴스가 아니며 WorldObject로의 프로토타입 링크도 없는 개체가 생성됩니다(결국 해석 메서드에는 이 정보가 없기 때문에 이러한 방식으로 복원할 수 없습니다).

시제품 체인을 보존하려면 Hydrate에 사용된 것과 같은 교묘한 요령이 필요합니다.JS) 이것이 목적과 다르면 오브젝트를 문자열화하기 전에 "평활화"하면 될 수 있습니다.이를 위해 소유 여부에 관계없이 객체의 모든 속성을 반복하고 재할당할 수 있습니다(이를 통해 프로토타입에서 상속되는 것이 아니라 객체 자체에 정의됩니다).

function flatten(obj) {
    var result = Object.create(obj);
    for(var key in result) {
        result[key] = result[key];
    }
    return result;
}

함수가 쓰여져 있는 방식으로는 원래 객체가 변형되지 않습니다.그래서 사용하다

console.log(JSON.stringify(flatten(a)));

원하는 결과를 얻을 수 있고a그대로 있을 거예요.

또 다른 옵션은 다음과 같이 정의하는 것입니다.toJSONserialize할 객체 프로토타입의 메서드:

function Test(){}

Test.prototype = {

    someProperty: "some value", 

    toJSON: function() {
        var tmp = {};

        for(var key in this) {
            if(typeof this[key] !== 'function')
                tmp[key] = this[key];
        }

        return tmp;
    }
};

var t = new Test;

JSON.stringify(t); // returns "{"someProperty" : "some value"}"

이것은 JSON.stringify가 검색하기 때문에 동작합니다.toJSON네이티브 시리얼화를 시도하기 전에 수신하는 객체의 메서드를 지정합니다.

다음 바이올린을 확인해 주세요.http://jsfiddle.net/AEGYG/

다음 함수를 사용하여 개체를 플랫 문자열화할 수 있습니다.

function flatStringify(x) {
    for(var i in x) {
        if(!x.hasOwnProperty(i)) {
            // weird as it might seem, this actually does the trick! - adds parent property to self
            x[i] = x[i];
        }
    }
    return JSON.stringify(x);
}

오브젝트 트리의 여러 레벨에 상속이 있는 경우에 대비하여 그의 답변에 포함된 스니펫 @TomasVana의 재귀 버전을 다음에 나타냅니다.

var flatten = function(obj) {
    if (obj === null) {
        return null;
    }

    if (Array.isArray(obj)) {
        var newObj = [];
        for (var i = 0; i < obj.length; i++) {
            if (typeof obj[i] === 'object') {
                newObj.push(flatten(obj[i]));
            }
            else {
                newObj.push(obj[i]);
            }
        }
        return newObj;
    }

    var result = Object.create(obj);
    for(var key in result) {
        if (typeof result[key] === 'object') {
            result[key] = flatten(result[key]);
        }
        else {
            result[key] = result[key];
        }
    }
    return result;
}

어레이를 어레이로 유지합니다.같은 방법으로 불러주세요.

console.log(JSON.stringify(flatten(visualDataViews)));

한편,flatten일반적인 작업에서 지금까지 게시된 다른 답변의 스니펫은 프로토타입이 동결된 경우처럼 수정할 수 없는 속성에는 작동하지 않습니다.이 문제를 해결하려면 새 개체를 만들고 속성을 이 새 개체에 할당해야 합니다.오브젝트를 문자열화하기만 하면 되기 때문에 오브젝트 ID나 다른 JavaScript의 내부 정보는 상관없습니다.따라서 새로운 오브젝트를 반환해도 문제 없습니다.이 접근법은 오브젝트 속성을 재할당하기보다 읽기 쉬운데, 이는 no-op처럼 보이지 않기 때문입니다.

function flatten(obj) {
    var ret = {};
    for (var i in obj) {
        ret[i] = obj[i];
    }
    return ret;
}

JSON.stringify 가지 .

JSON.stringify(value[, replacer[, space]])

이렇게 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아,replacer각 함수에 으로 호출됩니다.key-value--. - - -

다음 문제: 실제로 모든 것을 얻으려면 프로토타입을 따라야 하며 모든 속성 이름을 가져오기 위해 사용해야 합니다(사용할 수 있는 것보다 더 많은 정보를 얻을 수 있습니다.keys ★★★★★★★★★★★★★★★★★」for…in

var getAllPropertyNames = () => {
  const seen = new WeakSet();
  return (obj) => {
    let props = [];
    do {
      if (seen.has(obj)) return [];
      seen.add(obj);
      Object.getOwnPropertyNames(obj).forEach((prop) => {
        if (props.indexOf(prop) === -1) props.push(prop);
      });
    } while ((obj = Object.getPrototypeOf(obj)));
    return props;
  };
};
var flatten = () => {
  const seen = new WeakSet();
  const getPropertyNames = getAllPropertyNames();
  return (key, value) => {
    if (value !== null && typeof value === "object") {
      if (seen.has(value)) return;
      seen.add(value);
      let result = {};
      getPropertyNames(value).forEach((k) => (result[k] = value[k]));
      return result;
    }
    return value;
  };
};

그런 다음 개체를 JSON으로 평탄화합니다.

JSON.stringify(myValue, flatten());

주의:

  • i i i i i 。nulltypeof value"object"
  • 순환 참조는 bee를 검출해야 하므로seen

언급URL : https://stackoverflow.com/questions/8779249/how-to-stringify-inherited-objects-to-json

반응형