Javascript 我可以用JSON存储RegExp和函数吗?
给定这样一个块:Javascript 我可以用JSON存储RegExp和函数吗?,javascript,regex,json,serialization,anonymous-function,Javascript,Regex,Json,Serialization,Anonymous Function,给定这样一个块: var foo = {"regexp":/^http:\/\//, "fun":function(){}, } 用JSON存储它的正确方法是什么?你不能。JSON仅用于数据,不用于代码。除非可以先将函数转换为字符串,否则无法传输函数。在核心JSON中,没有;只允许原语值(字符串/数字/布尔值/空)、数组和对象。以上所有答案都是正确的,您可以将这部分代码保存为字符串,然后执行eval() 它不是JSON,但它是序列化的一种形式:foo.toSource()
var foo = {"regexp":/^http:\/\//,
"fun":function(){},
}
用JSON存储它的正确方法是什么?你不能。JSON仅用于数据,不用于代码。除非可以先将函数转换为字符串,否则无法传输函数。在核心JSON中,没有;只允许原语值(字符串/数字/布尔值/空)、数组和对象。以上所有答案都是正确的,您可以将这部分代码保存为字符串,然后执行
eval()
它不是JSON,但它是序列化的一种形式:
foo.toSource()
给出了一个字符串表示:“({regexp://^http:\\/\\//,fun:(function(){})})”
。使用bar=eval(foo.toSource())代码>为一个新对象分配一个正则表达式和一个函数到bar
我不知道它得到了多大的支持。有几个网站提到它只是壁虎,尽管它们已经两岁了。我目前只能访问Firefox,因此您可以测试它是否在您想要支持的浏览器(可能是IE、Chrome、Safari和Opera)中工作。您必须将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';
}
至于函数:无论如何,它们不应该用JSON或XML表示。在JS中,函数可以定义为对象,但它的主要用途仍然是封装一系列命令,而不是用作基本数据的包装器。您可以这样做
方法
用法
请注意
几乎是一个很好的解决方案,但不适用于正则表达式(对我来说)
我已经使用并推荐雅虎的npm软件包。它可以专门用函数和正则表达式序列化JSON,并处理其他情况
从他们的文档中:
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
});
产生
'{"str":"string","num":0,"obj":{"foo":"foo"},"arr":[1,2,3],"bool":true,"nil":null,"fn":function echo(arg) { return arg; },"re":/([^\\s]+)/g}'
它可以用水来补充水分
const obj = JSON.parse(serialized)
这可以通过查看它们的TL来验证。TL;博士:
对我来说,将两者都存储为对象似乎是最好的:
{
"regexp": {
"body": "^http:\\/\\/",
"flags": ""
},
"fun": {
"args": [],
"body": ""
}
}
正则表达式:
存储regexp已经有很多很好的答案:将它们存储为原始字符串,这样就可以使用构造函数从字符串创建实际的regexp
我的补充是要记住国旗。OP可能不需要它,但它肯定需要解决。构造函数将字符串形式的标志作为其第二个参数。因此,JSON存储的regexp的契约是:
interface JSONStoredRegExp {
body: string; // "" (empty string) for empty regexp
flags: string; // "" (empty string) for zero flags
}
。。。例如,这个JSON:
{
"regexp": {
"body": "abc",
"flags": "gi"
}
}
{
"fun": {
"args": [ "x", "y" ],
"body": "return x + y;"
}
}
。。。将生成此regexp:
RegExp(json.RegExp.body,json.RegExp.flags);
/abc/gi
功能:
除非给定的函数是纯函数,否则通过JSON传输它对我来说似乎很奇怪。此外,这种算法的代码可能与JavaScript以外的任何语言都不兼容
无论如何,如果仍然需要这样做,我建议使用相同的方法:将函数作为对象而不是字符串进行传递。还可以使用构造函数从参数和主体的序列化列表创建函数
interface JSONStoredFunction {
args: string[]; // [] (empty array) for zero arguments
body: string; // "" (empty string) for no-op function
}
构造函数将body作为其最后一个参数,每个参数都必须单独传递;所以这个JSON:
{
"regexp": {
"body": "abc",
"flags": "gi"
}
}
{
"fun": {
"args": [ "x", "y" ],
"body": "return x + y;"
}
}
。。。将产生此功能:
函数(…json.fun.args,json.fun.body);
匿名函数(x,y){返回x+y;}
使用…
可能不方便。在这种情况下,使用.apply
可能有助于:
Function.apply(null,json.fun.args.concat(json.fun.body));
有很好的移动方式可供使用
一些新的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:除非您已经明确地将字符串与“安全”模式(无论是通过regexp或解析器还是其他方式)匹配,否则不要使用eval,这是非常重要的——这就是JSON如此简单的原因之一;它可以被安全地解析。regexp可能是可消毒的(但不容易);函数几乎肯定不是,并且通过Godel定理或类似技术可以证明。一般不要使用eval(请参阅我在Daan回答中的评论)@JasonS我知道这一点,这只是一种方法,Huang Wants这一回答没有对这样做的安全影响提出任何警告。如果您在答案本身而不是在注释中添加警告,那么这将是一个正确但危险的回答。嘿,这真的很酷,但是如果值是对象,JSONEX.stringify会给出{“type”:“Object”,“value”:“[Object Object]”}
。例如:var a={b:{c:'hello world'}
有一条注释//在这里添加更多类型处理程序…
这就是对象处理程序应该去的地方。这是一个关于如何制作解决方案的解释,而不是一个库,尽管如果是这样的话那就太好了<代码>[对象对象]
-Internet Explorer再次罢工?包括“监禁时间”。。那很好。英雄联盟所以必须将RegExp标志(例如:g、m和i)存储在JSON中的单独字符串中?
{
"fun": {
"args": [ "x", "y" ],
"body": "return x + y;"
}
}
{
// 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",
}