web-dev-qa-db-fra.com

Fonction JSON.stringify

J'ai un objet qui a des propriétés et des méthodes, comme ceci:

{name: "FirstName",
age: "19",
load: function () {},
uniq: 0.5233059714082628}

et je dois passer cet objet à une autre fonction. J'ai donc essayé d'utiliser JSON.stringify (obj) mais la fonction de chargement (qui n'est bien sûr pas vide, c'est uniquement pour les besoins de cet exemple) est "perdue".

Existe-t-il un moyen de stringify, d’objecter et de maintenir les méthodes dont il dispose?

Merci!

31
Sorin Buturugeanu

Pourquoi voulez-vous exactement stringifier l'objet? JSON ne comprend pas les fonctions (et ce n'est pas censé le faire). Si vous voulez faire circuler des objets, pourquoi ne pas utiliser l'une des méthodes suivantes?

var x = {name: "FirstName", age: "19", load: function () {alert('hai')}, uniq: 0.5233059714082628};

function y(obj) {
    obj.load();
}

// works
y({name: "FirstName", age: "19", load: function () {alert('hai')}, uniq: 0.5233059714082628});

// "safer"
y(({name: "FirstName", age: "19", load: function () {alert('hai')}, uniq: 0.5233059714082628}));

// how it's supposed to be done
y(x);
5
David Titarenco

Il existe un moyen de sérialiser une fonction dans JS, mais vous devrez l'évaluer de l'autre côté et cela perdra également l'accès à sa portée d'origine. Une façon de le faire serait:

JSON.stringify(objWithFunction, function(key, val) {
  if (typeof val === 'function') {
    return val + ''; // implicitly `toString` it
  }
  return val;
});

Il y a des utilisations légitimes pour ce que vous demandez, malgré ce que les gens écrivent ici. Cependant, tout dépend de l'utilisation que vous allez en faire. Il y a peut-être une meilleure façon de faire ce que vous essayez de faire.

57
chjj

En fait, il est très facile de réaliser/analyser javascript object avec des méthodes.

Regardez le plugin JSONfn

http://www.eslinstructor.net/jsonfn/

J'espère que cela t'aides.

-Vadim

9
vadimk

Ce n’est pas quelque chose que je ferais un jour, mais il convient de mentionner qu’il existe des moyens de structurer la fonction (c’est-à-dire que ce n’est pas impossible).

Prenez ce qui suit:

var func = function(){console.log('logged')};
var strFunc = func.toString();

//then
var parsedFunc = eval('('+strFunc+')');
parsedFunc();

//or simply
eval('('+strFunc+')()');
//or
eval('('+strFunc+')')();
//or
eval('var anotherFunc='+strFunc);
anotherFunc()

Ce qui précède avec une toJSON() surchargée peut réaliser une fonction stringifiée peu profonde;

DISCLAIMER: examinez ceci et d'autres articles et prenez votre propre décision avant d'utiliser eval()

3
RossBille

Voici du code que j'ai utilisé dans mes projets précédents, peut-être utile?

  // Similar to JSON.stringify(), with three major differences:
  // (1) It also wrap functions
  // (2) Upon execution, it expose an object, nl, into the scope
  // (3) Results are minified by 'uglify-js'
  var bundle = function(obj) {
    var type = typeof obj;
    if(type === 'string') return '\'' + obj + '\'';
    if(type === 'boolean' || type === 'number') return obj;
    if(type === 'function') return obj.toString();
    var ret = [];
    for(var prop in obj) {
      ret.Push(prop + ': ' + bundle(obj[prop]));
    }
    return '{' + ret.join(',') + '}';
  };
  var ret = 'var nl = ' + bundle(nl);
  ret = require('uglify-js').minify(ret, {fromString: true}).code;
  fs.writeFileSync('nl.js', ret);

Une mise en garde lors de l'utilisation de ceci est que si la fonction utilise quelque chose dans la fermeture externe, cela ne fonctionnera pas, c'est-à-dire: ... obj: {..., clé: (fonction () {... var a = 10 ;. .. return function () {... certains codes utilisent 'a' ...}) ()}

0
streaver91