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
대부분의 경우 잘 작동하지만 기능에는 "적합"합니다.
몇 가지 속임수를 써서 알아냈어
다음은 예를 제시하겠습니다.
// 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
.
함수 변환을 처리하는 솔루션을 생각해 냈습니다(아니오).eval
JSON
은 은 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
'programing' 카테고리의 다른 글
자동 추가 제거자동 추가 제거문자 그대로의 내용이 없는 페이지(숏 코드 사용)에서 (0) | 2023.03.12 |
---|---|
반응 후크의 oldValues와 newValues를 비교하는 방법 useEffect? (0) | 2023.03.12 |
개인 방법 Jasmine을 사용한 단위 테스트 (0) | 2023.03.12 |
ORACLE의 select 문에서 데이터 유형 필드 가져오기 (0) | 2023.03.12 |
매개 변수 속성이 있는 스프링 데이터 JPA 쿼리 (0) | 2023.03.12 |