Étant donné un bloc comme celui-ci:
var foo = {"regexp":/^http:\/\//,
"fun":function(){},
}
Quelle est la bonne façon de le stocker dans JSON?
Vous devez stocker RegExp en tant que chaîne dans l'objet JSON. Vous pouvez ensuite construire un objet RegExp à partir de la chaîne:
// 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';
}
En ce qui concerne les fonctions: elles ne doivent de toute façon pas être représentées en JSON ou XML. Une fonction peut être définie en tant qu'objet dans JS, mais son objectif principal est toujours d'encapsuler une séquence de commandes et de ne pas servir de wrapper pour les données de base.
Tu ne peux pas. JSON est pour les données seulement, pas de code. Il n'y a aucun moyen de transférer des fonctions, sauf si vous pouvez d'abord le transformer en chaîne.
Vous pourriez faire quelque chose comme ça ...
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
}
}
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
Presque une bonne solution, mais ne fonctionne pas avec regex (pour moi en tout cas)
// doing this: jsonPlus.stringify(myThing)
// just stores `regex` as an empty object
Pour ceux qui cherchent encore une réponse:
avec plagin JSONfn vous pouvez sérialiser un objet javascript avec
et recréez un objet à partir de cette chaîne.
Documentation: http://www.eslinstructor.net/jsonfn/
--Vadim
En JSON de base, il n'y en a pas; la spécification JSON autorise uniquement les valeurs primitives (chaîne/nombres/booléen/null), ainsi que les tableaux et les objets.
J'ai utilisé et je recommanderais serialize-javascript npm à partir de yahoo. Il peut sérialiser JSON avec des fonctions et regex spécifiquement et gère d'autres cas.
De leurs 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
});
produit
'{"str":"string","num":0,"obj":{"foo":"foo"},"arr":[1,2,3],"bool":true,"nil":null,"fn":function echo(arg) { return arg; },"re":/([^\\s]+)/g}'
qui peut être hydraté avec
const obj = JSON.parse(serialized)
Ceci peut être vérifié en regardant leurs tests unitaires .
Ce n'est pas JSON, mais c'est une forme de sérialisation: foo.toSource()
donne une représentation sous forme de chaîne: "({regexp:/^http:\\/\\//, fun:(function () {})})"
. Utiliser bar = eval(foo.toSource());
assigne un nouvel objet avec une expression rationnelle et une fonction à bar
.
Je ne sais pas si cela est bien pris en charge. Plusieurs sites Web mentionnent qu'il s'agit uniquement de gecko, bien qu'ils aient deux ans. Je n'ai actuellement accès qu'à Firefox, vous devez donc vérifier s'il fonctionne dans les navigateurs que vous souhaitez prendre en charge (probablement IE, Chrome, Safari et Opera).