Javascript 我可以在 JSON 中存储 RegExp 和 Function 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8328119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I store RegExp and Function in JSON?
提问by Huang
Given a block like this:
给定一个这样的块:
var foo = {"regexp":/^http:\/\//,
"fun":function(){},
}
What is a proper way to store it in JSON?
将它存储在 JSON 中的正确方法是什么?
回答by Ankit Aggarwal
You have to store the RegExp as a string in the JSON object. You can then construct a RegExp object from the string:
您必须将 RegExp 作为字符串存储在 JSON 对象中。然后,您可以从字符串构造一个 RegExp 对象:
// JSON Object (can be an imported file, of course)
// Store RegExp pattern as a string
// Double backslashes are required to put literal \ characters in the string
var jsonObject = { "regex": "^http:\/\/" };
function fun(url) {
var regexp = new RegExp(jsonObject.regex, 'i');
var match;
// You can do either:
match = url.match(regexp);
// Or (useful for capturing groups when doing global search):
match = regexp.exec(url);
// Logic to process match results
// ...
return 'ooga booga boo';
}
As for functions: they should not be represented in JSON or XML anyway. A function may be defined as an object in JS, but its primary purpose is still to encapsulate a sequence of commands, not serve as a wrapper for basic data.
至于函数:无论如何,它们都不应该用 JSON 或 XML 表示。一个函数在 JS 中可以定义为一个对象,但它的主要目的仍然是封装一系列命令,而不是作为基本数据的包装器。
回答by Evert
You can't. JSON is for data only, not code. There's no way to transfer functions, unless you can transform it to a string first.
你不能。JSON 仅用于数据,而非代码。无法传递函数,除非您可以先将其转换为字符串。
回答by Billy Moon
You could do something like this...
你可以做这样的事情......
Method
方法
JSONEX = {
stringify: function(obj){
var jsonified = {}
// loop through object and write string and type to newly stored data structure
for(i in obj)
jsonified[i] = {
// some voodoo to determine the variable type
type: Object.prototype.toString.call(obj[i]).split(/\W/)[2],
value: obj[i].toString()
}
return JSON.stringify(jsonified)
},
parse: function(json){
objectified = {}
obj = JSON.parse(json)
// loop through object, and handle parsing of string according to type
for(i in obj)
if(obj[i].type == "RegExp"){
var m = obj[i].value.match(/\/(.*)\/([a-z]+)?/)
objectified[i] = new RegExp(m[1],m[2]);
} else if(obj[i].type == "String"){
objectified[i] = obj[i].value
} else if(obj[i].type == "Function"){
// WARNING: this is more or less like using eval
// All the usual caveats apply - including jailtime
objectified[i] = new Function("return ("+obj[i].value+")")();
}
// ADD MORE TYPE HANDLERS HERE ...
return objectified
}
}
Usage
用法
myThing = {
regex: new RegExp("123","g"),
text: "good",
func: function(x){
return x * x
}
}
json = JSONEX.stringify(myThing)
// "{"regex":{"type":"RegExp","value":"/123/g"},"text":{"type":"String","value":"good"},"func":{"type":"Function","value":"function (x) {\n return x * x;\n}"}}"
obj = JSONEX.parse(json)
// native object representing original object
N.B.
NB
Almost a good solution, but does not work with regex (for me anyway)
几乎是一个很好的解决方案,但不适用于正则表达式(无论如何对我来说)
// doing this: jsonPlus.stringify(myThing)
// just stores `regex` as an empty object
回答by vadimk
For those who's still looking for an answer:
对于那些仍在寻找答案的人:
with plagin JSONfnyou can serialize javascript object with
使用 plagin JSONfn你可以序列化 javascript 对象
- Functions
- Regexp
- Date
- 职能
- 正则表达式
- 日期
and re-create object from this string.
并从此字符串重新创建对象。
Documentation: http://www.eslinstructor.net/jsonfn/
文档:http: //www.eslinstructor.net/jsonfn/
--Vadim
--瓦迪姆
回答by Jason S
In core JSON, there isn't; the JSON speconly allows for primitive values (string/numbers/boolean/null), and arrays and objects.
在核心 JSON 中,没有;JSON 规范只允许原始值(字符串/数字/布尔值/null)以及数组和对象。
回答by Dmitry Parzhitsky
TL;DR:
特尔;博士:
Storing both as objects seems the best to me:
将两者都存储为对象对我来说似乎是最好的:
{
"regexp": {
"body": "^http:\/\/",
"flags": ""
},
"fun": {
"args": [],
"body": ""
}
}
RegExps:
正则表达式:
There are already a lot of great answers for storing regexps: store them as raw strings, so that one can use RegExp
constructor to create an actual regexp from strings.
对于存储正则RegExp
表达式已经有很多很好的答案:将它们存储为原始字符串,以便可以使用构造函数从字符串创建实际的正则表达式。
My addition would be to keep in mind flags. The OP might not need it, but it is definitely has to be addressed. RegExp
constructor takes flags in the form of a string as its second parameter. So the contract for JSON-stored regexp would be:
我的补充是记住标志。OP 可能不需要它,但绝对必须解决它。RegExp
构造函数采用字符串形式的标志作为其第二个参数。所以 JSON 存储的正则表达式的契约是:
interface JSONStoredRegExp {
body: string; // "" (empty string) for empty regexp
flags: string; // "" (empty string) for zero flags
}
... and, for example, this JSON:
...,例如,这个 JSON:
{
"regexp": {
"body": "abc",
"flags": "gi"
}
}
... would produce this regexp:
...会产生这个正则表达式:
RegExp(json.regexp.body, json.regexp.flags);
/abc/gi
Functions:
职能:
Unless a given function is pure, it seems weird to me to transfer it via JSON. Also, the code of such an algorithm is likely incompatible with any language, other than JavaScript.
除非给定的函数是纯函数,否则通过 JSON 传输它对我来说似乎很奇怪。此外,这种算法的代码可能与 JavaScript 之外的任何语言都不兼容。
Anyway, if that is still necessary to do, I would recommend the same approach: transfer functions as an object, rather than a string. One can also use Function
constructor to create functions from serialized list of arguments and body.
无论如何,如果仍然需要这样做,我会推荐相同的方法:将函数作为对象而不是字符串传递。还可以使用Function
构造函数从参数和主体的序列化列表中创建函数。
interface JSONStoredFunction {
args: string[]; // [] (empty array) for zero arguments
body: string; // "" (empty string) for no-op function
}
Function
constructor takes body as its last argument, and each of the parameters has to be passed separately; so this JSON:
Function
构造函数将 body 作为最后一个参数,并且每个参数都必须单独传递;所以这个 JSON:
{
"fun": {
"args": [ "x", "y" ],
"body": "return x + y;"
}
}
... will produce this function:
...将产生这个功能:
Function(...json.fun.args, json.fun.body);
function anonymous(x, y) { return x + y; }
It might be inconvenient to use ...
the spread operator. In that case, using .apply
might help:
使用...
扩展运算符可能不方便。在这种情况下,使用.apply
可能会有所帮助:
Function.apply(null, json.fun.args.concat(json.fun.body));
回答by pery mimon
There is good movement to use https://json5.org/some new super-set of JSON that contain a lot of things that Illegal in JSON
使用https://json5.org/一些新的 JSON 超集有很好的运动,其中包含很多在 JSON 中非法的东西
{
// comments
unquoted: 'and you can quote me on that',
singleQuotes: 'I can use "double quotes" here',
lineBreaks: "Look, Mom! \
No \n's!",
hexadecimal: 0xdecaf,
leadingDecimalPoint: .8675309, andTrailing: 8675309.,
positiveSign: +1,
trailingComma: 'in objects', andIn: ['arrays',],
"backwardsCompatible": "with JSON",
}
github: https://github.com/json5/json5
github:https: //github.com/json5/json5
回答by Daan Wilmer
It is not JSON, but it is a form of serialization: foo.toSource()
gives a string representation: "({regexp:/^http:\\/\\//, fun:(function () {})})"
. Using bar = eval(foo.toSource());
assigns a new object with a regex and a function to bar
.
它不是 JSON,而是一种序列化形式:foo.toSource()
给出一个字符串表示:"({regexp:/^http:\\/\\//, fun:(function () {})})"
. Usingbar = eval(foo.toSource());
将一个带有正则表达式和函数的新对象分配给bar
.
I don't know how well it is supported. Several website mention that it is gecko-only, although they are two years old. I currently only have access to Firefox, so you test whether it works in the browsers you want to support (probably IE, Chrome, Safari and Opera).
我不知道它的支持程度如何。有几个网站提到它只有壁虎,尽管它们已经两岁了。我目前只能访问 Firefox,因此您测试它是否可以在您想要支持的浏览器(可能是 IE、Chrome、Safari 和 Opera)中运行。
回答by cchamberlain
I've used and would recommend serialize-javascriptnpm package from yahoo. It can serialize JSON with functions and regex specifically and handles other cases.
我已经使用并会推荐来自雅虎的serialize-javascriptnpm 包。它可以专门使用函数和正则表达式序列化 JSON 并处理其他情况。
From their docs:
从他们的文档:
var serialize = require('serialize-javascript');
const serialized = serialize({
str : 'string',
num : 0,
obj : {foo: 'foo'},
arr : [1, 2, 3],
bool : true,
nil : null,
undef: undefined,
fn: function echo(arg) { return arg; },
re: /([^\s]+)/g
});
produces
产生
'{"str":"string","num":0,"obj":{"foo":"foo"},"arr":[1,2,3],"bool":true,"nil":null,"fn":function echo(arg) { return arg; },"re":/([^\s]+)/g}'
which can be hydrated with
可以与
const obj = JSON.parse(serialized)
This can be verified by looking at their unit tests.
这可以通过查看他们的单元测试来验证。
回答by balkon_smoke
All answers above is right, instead of you can save this part of code as a string and then do eval()
上面的所有答案都是正确的,而不是您可以将这部分代码保存为字符串然后执行 eval()
var sCode = 'var oFoo = {"regexp": new RegExp("/^http:\/\//"), "fun": function() {}}';
eval(sCode);
console.log(oFoo);