programing

javascript 함수를 JSON에 저장하는 방법

muds 2023. 3. 7. 22:06
반응형

javascript 함수를 JSON에 저장하는 방법

나중에 사용할 수 있도록 로컬 스토리지에 저장하려는 JS 개체가 있는데 문자열로 구문 분석할 수 없습니다.

코드:

JSON.stringify({
    a: 5,
    b: function (param) {
        return param;
    }
})

결과:

"{"a":5}"

JSON을 사용하지 않을 경우 나중에 사용하기 위해 어떻게 저장합니까?

(또한 문자열 함수를 인터럽트하기 위한 자체 Lexer-Parser 작성은 옵션이라고 생각하지 않습니다.)

다음과 같은 접근방식을 권장합니다.

인수와 본문을 json에 저장합니다.

{"function":{"arguments":"a,b,c","body":"return a*b+c;"}}

이제 json을 해석하고 함수를 인스턴스화합니다.

var f = new Function(function.arguments, function.body);

세이브인 것 같아

일반적으로 다음과 같은 질문은 X/Y 문제를 나타냅니다.X를 할 필요가 있습니다.Y가 도와줄 것 같아서Y를 하려고 해도 안 되고Y를 어떻게 하는지 물어봐요X를 어떻게 하는지 물어보는 것이 더 도움이 될 것입니다.

그러나 질문에 대답하면서 다음과 같이 물었다.리페이서 및 리바이버 함수를 사용하여 함수를 문자열로 변환할 수 있습니다(중).stringify)ㄹ 때 (으)ㄹ 때 (으)ㄹ 때 (으)로로 되돌아가다.parse는 상관없지만, 할 수 (질문에 나타난 기능과는 상관없습니다만, 그것은 그다지 대표성이 없다고 생각합니다.)로컬 스토리지에서 실행 가능한 코드로 문자열을 변환하는 것은 로컬 스토리지 컨텐츠가 악의적인 방식으로 손상되지 않았다고 믿는다는 것을 의미합니다.페이지가 이미 XSS 공격에 취약하지 않는 한 가능성이 낮지만 유의해야 할 문제입니다.

들어 만, 다른 한 것이 좋습니다. 그이 다 사용되기 입니다.★★★★★★★★★★★★★★★★★★,eval처럼)new Function는, 악성 코드의 로서 사용할 수

// The object
var obj = {
    a: 5,
    b: function (param) {
        return param;
    }
};

// Convert to JSON using a replacer function to output
// the string version of a function with /Function(
// in front and )/ at the end.
var json = JSON.stringify(obj, function(key, value) {
  if (typeof value === "function") {
    return "/Function(" + value.toString() + ")/";
  }
  return value;
});

// Convert to an object using a reviver function that
// recognizes the /Function(...)/ value and converts it
// into a function via -shudder- `eval`.
var obj2 = JSON.parse(json, function(key, value) {
  if (typeof value === "string" &&
      value.startsWith("/Function(") &&
      value.endsWith(")/")) {
    value = value.substring(10, value.length - 2);
    return (0, eval)("(" + value + ")");
  }
  return value;
});
document.body.innerHTML = obj2.b(42);

★★(0, eval)("(" + value + ")"); 할 수 있습니다.eval는 리바이버 기능의 범위가 아닌 글로벌 범위에서 실행됩니다.통상은 「」입니다.eval에는 호출한 스코프를 사용하는 마법의 기능이 있습니다만, 이 기능은 직접 호출했을 때만 유효합니다.그림과 같이 간접(또는 그냥)var e = eval; e("(" + value + ")");의 능력을 있지 않습니다.에서 동작합니다이치노이치노

JSON에는 함수를 저장할 수 없습니다.

JSON 값은 문자열, 숫자, 개체, 배열만 포함할 수 있습니다.true,false ★★★★★★★★★★★★★★★★★」null:

여기에 이미지 설명 입력

JSON 사이트에서 확인하세요.

한 가지 간단한 방법은

var dstr = JSON.stringify( { a: 5
                           , b: x => x
                           }
                         , (k,v) => typeof v === "function" ? "" + v : v
                         );

함수 이름을 파라미터 값과 함께 배열에 저장하기 시작했는데 배열의 첫 번째 항목은 함수 이름 앞에 a가 붙습니다.$일반 어레이에서 분리합니다.

{
    "object": {
        "your-function": ["$functionName", "param-1", "param-2"],
        "color": ["$getColor", "brand", "brand-2"],
        "normal-array": ["normal", "array"]
        ...
    }
}

위의 예에서는 글로벌 맵/오브젝트에서 색상 값을 가져오는 Sass 및 JS 함수를 사용하고 있습니다.이 방법으로 함수를 해석하려면 당연히 커스텀 코드가 필요하지만, JSON에서의 「저장」함수의 관점에서는 이 방법이 마음에 듭니다.

내가 만든 것은JSON.parseIt()그리고.JSON.stringifyIt()사용하지 않고 첫 번째 답을 기반으로 하는 기능

JSON.stringifyIt = (obj)=>{
    return(
        JSON.stringify(obj, function(key, value) {
            if (typeof value === "function") {
                return "/Function(" + value.toString() + ")/";
            }
            if(typeof value === "string"){
                return "/String(" + value.toString() + ")/"
            }
            return value;
        })
    )
}
JSON.parseIt=(json)=>{
    return(
        JSON.parse(json, function(key, value) {
            if (typeof value === "string" &&
            value.startsWith("/Function(") &&
            value.endsWith(")/")) {
                value = value.substring(10, value.length - 2);
                var string = value.slice(value.indexOf("(") + 1, value.indexOf(")"));
                if(/\S+/g.test(string)){
                    return (new Function(string,value.slice(value.indexOf("{") + 1, value.lastIndexOf("}"))))

                }else{
                    return (new Function(value.slice(value.indexOf("{") + 1, value.lastIndexOf("}"))));
                }
                
            }
            if (typeof value === "string" &&
            value.startsWith("/String(") &&
            value.endsWith(")/")){
                value = value.substring(8, value.length - 2);
            }
            return value;
        })
    )
}

// DEMO

var obj = {
    string:"a string",
    number:10,
    func:()=>{
        console.log("this is a string from a parsed json function");
    },
    secFunc:(none,ntwo)=>{console.log(none + ntwo)} ,
    confuse:"/Function(hello)/"
}
const stringifiedObj = JSON.stringifyIt(obj);
console.log("the stringified object is: ",stringifiedObj);

const parsedObj = JSON.parseIt(stringifiedObj);

// console.log("the parsed object is:  ",parsedObj);
console.log(parsedObj.string);
console.log(parsedObj.number);
console.log(parsedObj.confuse);
parsedObj.func();
parsedObj.secFunc(5,6);

제가 고친 문제는

  • 평가판 삭제.
  • "/Function(hello)/"와 같은 문자열을 지정하면 구문 분석 시 함수가 되는 문자열화 및 구문 분석에서 문제가 발생했습니다.
  • 2가지 기능을 실현했습니다.
  • 파라미터 삽입 추가

어떤 이유로든 여전히 JSON에 함수 정의를 포함해야 하는 사용자에게 이 코드가 도움이 될 수 있습니다(오브젝트 크기에 따라 느릴 수 있습니다).

function Object2JsonWithFunctions(o, space = null) {
var functionList = {}
var fnSeq = 0;

var snrepl = function(k,v){
    if(typeof v === 'function'){
        fnSeq++;
        var funcName = `___fun${fnSeq}___`;
        var funcText = ''+v;
        
        functionList[funcName] = funcText
        
        return funcName;
    }
    
    return v;
}

var RawJson = JSON.stringify(o, snrepl, space);

for(func in functionList){
    var PropValue = `"${func}"`;
    RawJson = RawJson.replace(PropValue, functionList[func])
}

return RawJson;}

이 코드는 통상적으로 JSON으로 변환합니다.함수의 경우 원래 문자열화는 "prop":function()...(문자열로서의 함수)로 반환됩니다.위의 코드는 자리 표시자(예: "prop":fn1)를 만들고 함수 목록을 만듭니다.그런 다음 모든 자리 표시자를 원래 함수 본체로 바꿉니다.

언급URL : https://stackoverflow.com/questions/36517173/how-to-store-a-javascript-function-in-json

반응형