programing

JSON.stringify에서 기능을 유지할 수 있습니까?

closeapi 2023. 3. 12. 10:49
반응형

JSON.stringify에서 기능을 유지할 수 있습니까?

다음 개체를 사용합니다.

x = {
 "key1": "xxx",
 "key2": function(){return this.key1}
}

이렇게 하면:

y = JSON.parse( JSON.stringify(x) );

그럼 y는 돌아올거야{ "key1": "xxx" }stringify를 통해 함수를 전송할 수 있는 방법이 있습니까?"ye goode olde eval()"을 사용하여 부가 기능을 가진 오브젝트를 만들 수 있는데, 패킹은 무엇입니까?

json-stringify-function은 이 게시물과 유사합니다.

그 게시물을 통해 발견된 단편은 이 답변을 우연히 접하는 사람에게 유용할 수 있습니다.JSON.stringify의 replacer 파라미터와 JSON.parse의 reviver 파라미터를 사용함으로써 동작합니다.

좀 더 구체적으로, 어떤 값이 함수 유형일 때,.toString()를 통해 호출됩니다.replacer파싱할 시간이 되면eval()를 경유하여 실행됩니다.reviver문자열 형식으로 함수가 존재하는 경우.

var JSONfn;
if (!JSONfn) {
    JSONfn = {};
}

(function () {
  JSONfn.stringify = function(obj) {
    return JSON.stringify(obj,function(key, value){
            return (typeof value === 'function' ) ? value.toString() : value;
        });
  }

  JSONfn.parse = function(str) {
    return JSON.parse(str,function(key, value){
        if(typeof value != 'string') return value;
        return ( value.substring(0,8) == 'function') ? eval('('+value+')') : value;
    });
  }
}());

Vadim Kiryukin의 JSONfn.js에서 가져온 코드 조각 또는 홈페이지에서 문서를 참조하십시오.

나도 최근에 비슷한 요구 사항이 있었어.확실히 말하면, 출력은 JSON과 비슷하지만, 실제로는 javascript에 지나지 않습니다.

JSON.stringify대부분의 경우 잘 작동하지만 기능에는 "적합"합니다.

몇 가지 속임수를 써서 알아냈어

  1. (의 두 번째 파라미터)를 사용합니다.
  2. 사용하다func.toString()함수의 JS 코드를 가져오려면
  3. 어떤 함수가 문자열화되어 있는지 기억하고 결과에 따라 직접 대체한다.

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

// our source data
const source = {
    "aaa": 123,
    "bbb": function (c) {
        // do something
        return c + 1;
    }
};

// keep a list of serialized functions
const functions = [];

// json replacer - returns a placeholder for functions
const jsonReplacer = function (key, val) {
    if (typeof val === 'function') {
  	    functions.push(val.toString());
        
        return "{func_" + (functions.length - 1) + "}";
    }
        
    return val;
};

// regex replacer - replaces placeholders with functions
const funcReplacer = function (match, id) {
   return functions[id];
};

const result = JSON
    .stringify(source, jsonReplacer)               // generate json with placeholders
    .replace(/"\{func_(\d+)\}"/g, funcReplacer);   // replace placeholders with functions

// show the result
document.body.innerText = result;
body { white-space: pre-wrap; font-family: monospace; }

중요:자리 표시자 형식에 주의하십시오. 너무 일반적이지 않은지 확인하십시오.변경할 경우 필요에 따라 정규식도 변경하십시오.

엄밀히 말하면, 이것은 JSON이 아닙니다.또, 왜 이것을 하고 싶은지도 잘 모르겠습니다만, 다음의 해킹을 시험해 보세요.

x.key2 = x.key2.toString();
JSON.stringify(x)  //"{"key1":"xxx","key2":"function (){return this.key1}"}"

물론 첫 번째 줄은 오브젝트에 반복적으로 반복함으로써 자동화할 수 있습니다.역연산은 더 어렵다. 함수는 문자열일 뿐이다.eval는 동작하지만, 특정 키에 문자열화된 함수 코드가 포함되어 있는지 여부를 추측할 필요가 있습니다.

함수가 닫히는 데이터는 시리얼라이저에 표시되지 않으므로 함수를 패키징할 수 없습니다.심지어 Mozilla의uneval닫힘을 제대로 포장할 수 없습니다.

리바이버와 리페이서를 사용하는 것이 최선의 방법입니다.

https://yuilibrary.com/yui/docs/json/json-freeze-thaw.html

JSON.parse에 전달된 리바이버 함수는 가장 깊은 키에서 가장 높은 수준까지의 원시 구문 분석 개체 내의 모든 키:값 쌍에 적용됩니다.이 경우 이는 이름 및 검색된 속성이 리바이버를 통과하고 해당 키를 포함하는 개체가 통과됨을 의미합니다.

이것이 https://gist.github.com/Lepozepo/3275d686bc56e4fb5d11d27ef330a8ed에서 한 일입니다.

function stringifyWithFunctions(object) {
  return JSON.stringify(object, (key, val) => {
    if (typeof val === 'function') {
      return `(${val})`; // make it a string, surround it by parenthesis to ensure we can revive it as an anonymous function
    }
    return val;
  });
};

function parseWithFunctions(obj) {
  return JSON.parse(obj, (k, v) => {
    if (typeof v === 'string' && v.indexOf('function') >= 0) {
      return eval(v);
    }
    return v;
  });
};

장난스럽지만 효과적인 방법은 다음과 같습니다.

Function.prototype.toJSON = function() { return this.toString(); }

(의하는 것을 하고) Function)는, 다음의 명령어를 사용하지 않는 경우, 역직렬화 됩니다.eval.

함수 변환을 처리하는 솔루션을 생각해 냈습니다(아니오).evalJSON 1개의 매개 사용합니다.value 중인 JSON을 replacer ★★★★★★★★★★★★★★★★★」space그들은 무시될 것이다.

void function () {
    window.JSON = Object.create(JSON)

    JSON.stringify = function (obj) {
        return JSON.__proto__.stringify(obj, function (key, value) {
            if (typeof value === 'function') {
                return value.toString()
            }
            return value
        })
    }

    JSON.parse = function (obj) {
        return JSON.__proto__.parse(obj, function (key, value) {
            if (typeof value === 'string' && value.slice(0, 8) == 'function') {
                return Function('return ' + value)()
            }
            return value
        })
    }
}()


// YOUR CODE GOES BELOW HERE

x = {
 "key1": "xxx",
 "key2": function(){return this.key1}
}

const y = JSON.parse(JSON.stringify(x))
console.log(y.key2())

문자열에서 함수를 생성할 수 있습니다.

var obj = {a:function(a,b){
    return a+b;
}};

var serialized = JSON.stringify(obj, function(k,v){
    //special treatment for function types
    if(typeof v === "function")
        return v.toString();//we save the function as string
    return v;
});
/*output:
"{"a":"function (a,b){\n        return a+b;\n    }"}"
*/

이 기능으로 현을 기능화하는 마법이 있습니다.

var compileFunction = function(str){
    //find parameters
    var pstart = str.indexOf('('), pend = str.indexOf(')');
    var params = str.substring(pstart+1, pend);
    params = params.trim();

    //find function body
    var bstart = str.indexOf('{'), bend = str.lastIndexOf('}');
    var str = str.substring(bstart+1, bend);

    return Function(params, str);
}

리바이버와 함께 JSON.parse를 사용합니다.

var revivedObj = JSON.parse(serialized, function(k,v){
    // there is probably a better way to determ if a value is a function string
    if(typeof v === "string" && v.indexOf("function") !== -1)
        return compileFunction(v);
    return v;
});

//output:

 revivedObj.a

 function anonymous(a,b
 /**/) {

    return a+b;

 }

 revivedObj.a(1,2)
3

제가 알기로는 어떤 언어에서도 기능을 지속하는 시리얼라이제이션 라이브러리는 없습니다.시리얼화는 데이터를 보존하기 위해 해야 할 일입니다.컴파일은 기능을 유지하기 위해 해야 할 일이다.

이곳에 도착한 사람들은 기능을 포함하고 있지 않다면 유효한 JSON을 취급하고 있는 것 같습니다.그럼 이 구조들을 어떻게 묶어야 할까요?

Require를 수정하는 하였습니다.JS이렇게 했어요.사용되었음을 ">>>F<<<"는 [Require]에 . 낮지만 후회보다는 이 낫다.일어날 것 같진 않지만 후회보다는 안전이 낫다.개체에는 원자값, JavaScript 개체, JavaScript 개체 등이 될 수 .Object 할 수 .함수가 존재하지 않으면 JSON으로 스트링할 수 있습니다.은 " " 입니다.config다음과 같이 합니다.

// Holds functions we encounter.
var functions = [];
var placeholder = ">>>F<<<";

// This handler just records a function object in `functions` and returns the 
// placeholder as the value to insert into the JSON structure.
function handler(key, value) {
    if (value instanceof Function) {
        functions.push(value);
        return placeholder;
    }

    return value;
}

// We stringify, using our custom handler.    
var pre = JSON.stringify(config, handler, 4);

// Then we replace the placeholders in order they were encountered, with
// the functions we've recorded.
var post = pre.replace(new RegExp('"' + placeholder + '"', 'g'),
                       functions.shift.bind(functions));

post됩니다.handler.ECMAScript 5th Edition을 확인했는데, 문자열화 알고리즘을 정의하여 주문에 문제가 있는 경우를 찾을 수 없습니다.향후 에디션에서 이 알고리즘이 변경될 경우 수정사항은 고유한 플레이스홀더를 함수에 매핑하는 관련 배열에 저장되는 함수를 참조하기 위해 고유한 플래콜더를 사용하는 것입니다.

언급URL : https://stackoverflow.com/questions/7759200/is-there-any-possibility-to-have-json-stringify-preserve-functions

반응형