Analyser Chaîne JSON dans un Prototype d'Objet en JavaScript
Je sais comment analyser une Chaîne JSON et le transformer en un Objet JavaScript.
Vous pouvez utiliser JSON.parse()
dans les navigateurs modernes (et IE9+).
C'est très bien, mais comment puis-je prendre cet Objet JavaScript et le transformer en un particulier Objet JavaScript (c'est à dire avec un certain prototype)?
Par exemple, supposons que vous avez:
function Foo()
{
this.a = 3;
this.b = 2;
this.test = function() {return this.a*this.b;};
}
var fooObj = new Foo();
alert(fooObj.test() ); //Prints 6
var fooJSON = JSON.parse({"a":4, "b": 3});
//Something to convert fooJSON into a Foo Object
//....... (this is what I am missing)
alert(fooJSON.test() ); //Prints 12
Encore une fois, je ne suis pas demandez comment convertir une chaîne JSON dans un générique d'Objet JavaScript. Je veux savoir comment faire pour convertir une chaîne JSON dans un "Foo" de l'Objet. C'est, à mon Objet devriez maintenant avoir une fonction "test" et les propriétés de 'a' et 'b'.
Mise à JOUR
Après avoir fait quelques recherches, j'ai pensé à cela...
Object.cast = function cast(rawObj, constructor)
{
var obj = new constructor();
for(var i in rawObj)
obj[i] = rawObj[i];
return obj;
}
var fooJSON = Object.cast({"a":4, "b": 3}, Foo);
Ça marche?
Mise à JOUR Mai 2017: Le "moderne" façon de faire cela, est via de l'Objet.attribuer
, mais cette fonction n'est pas disponible dans internet explorer 11 ou plus Android navigateurs.
Vous devez vous connecter pour publier un commentaire.
L'actuel réponses contiennent beaucoup de roulés à la main ou à la bibliothèque de code. Ce n'est pas nécessaire.
Utilisation
JSON.parse('{"a":1}')
pour créer un objet ordinaire.Utilisez l'une des fonctions standardisées pour définir le prototype:
Object.assign(new Foo, { a: 1 })
Object.setPrototypeOf({ a: 1 }, Foo.prototype)
Object.setPrototypeOf(...)
. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...setPrototypeOf
sont la propriété de descripteurs.Voir un exemple ci-dessous (cet exemple utilise le natif de l'objet JSON). Mes modifications sont commentées dans les CAPITALES:
for (var prop in obj) {if (obj.hasOwnProperty(prop)) {this[prop] = obj[prop];}}
for (var prop in obj) {if (this.hasOwnProperty(prop)) {this[prop] = obj[prop];}}
. Cela suppose que vous attendez le serveur afin de remplir toutes les propriétés, l'OMI devrait également jeter si obj.hasOwnProperty() échoue...Voulez-vous ajouter JSON de sérialisation/désérialisation de fonctionnalités, non? Alors regardez ceci:
Vous souhaitez réaliser ceci:
la méthode toJson() est une méthode normale.
fromJson() est une méthode statique.
Mise en œuvre:
Utilisation:
Remarque: Si vous le souhaitez, vous pouvez modifier toutes les définitions de propriété comme
this.title
,this.author
, etc parvar title
,var author
, etc. et d'ajouter que les accesseurs à la réalisation de l'UML définition.toJson()
méthode, qu'il a des propriétés individuelles codées en dur ou en utilise un pour chaque aurez besoin d'ajouter d'échappement barre oblique inverse les codes pour certains caractères qui pourraient être dans chaque chaîne de propriété. (Le titre du livre pourrait avoir des guillemets, par exemple.)JSON.stringify()
au lieu d'écrire la méthode toJSon() me. Pas besoin de réinventer la roue, maintenant que tous les navigateurs modernes supportent.serializable = ['title', 'author', ...]
.JSON.stringify(serializable.reduce((obj, prop) => {...obj, [prop]: this[prop]}, {}))
toJSON()
et retourner un objet anonyme vous que pour sérialiser commeJSON.stringify()
va utiliser les la méthode toJSON() automatiquement.Un blog que j'ai trouvé utile:
La Compréhension De JavaScript Prototypes
Vous pouvez gâcher, avec l' __proto__ propriété de l'Objet.
Cela permet fooJSON pour hériter de la Foo prototype.
Je ne pense pas que cela fonctionne sous IE, mais... au moins de ce que j'ai lu.
__proto__
a longtemps été deprecated. En outre, pour des raisons de performances, il est recommandé de ne pas modifier le [[Prototype]] intérieur de la propriété d'un objet déjà créé (par la mise en__proto__
ou par tout autre moyen).[[prototype]]
et il semble être hors de propos dans google Chrome. Dans firefox appel de nouveau est plus lent qu'à l'aide d'un prototype, et de l'Objet.créer est la plus rapide. Je suppose problème avec FF c'est que le premier test est plus lent que l'an dernier, juste l'ordre d'exécution des questions. Dans chrome tout fonctionne avec presque la même vitesse. Je veux dire l'accès à la propriété et nvocation de méthodes. Créatine est plus rapide avec le nouveau, mais ce n'est pas si important. voir: jsperf.com/prototype-change-test-8874874/1 et: jsperf.com/prototype-changed-method-callObject.setPrototypeOf(fooJSON, Foo.prototype)
au lieu defooJSON.__proto__
... droit?Suis-je raté quelque chose dans la question, ou sinon, pourquoi personne n'a mentionné
reviver
paramètre deJSON.parse
depuis 2011?Ici est simpliste code pour une solution qui fonctionne:
https://jsfiddle.net/Ldr2utrr/
PS: Votre question est déroutante: >>C'est très bien, mais comment puis-je prendre cet Objet JavaScript et le transformer en un particulier d'Objet JavaScript (c'est à dire avec un certain prototype)?
contredit le titre, où que vous vous posez sur JSON de l'analyse, mais la cité le paragraphe pose des questions sur JS exécution du prototype d'objet de remplacement.
Par souci d'exhaustivité, voici un simple one-liner j'ai fini avec (je n'avais pas besoin de vérifier pour les non-Foo-propriétés):
Une autre approche pourrait être à l'aide de
de l'Objet.créer
. En tant que premier argument, vous passez le prototype, et pour le second, vous passez d'une carte de la propriété des noms de descripteurs:JS:
J'ai créé un package appelé json-sec. Il prend en charge (circulaire) références et aussi des instances de classe.
Vous devez définir 2 nouvelles méthodes de votre classe (
toDry
sur le prototype etunDry
comme une méthode statique), le registre de la classe (Dry.registerClass
), et vous partez.J'ai comme l'ajout d'un argument facultatif pour le constructeur et l'appel
Object.assign(this, obj)
, puis la manipulation de toutes les propriétés qui sont des objets ou des tableaux d'objets eux-mêmes:J'ai combiné les solutions que j'ai pu trouver et compilé dans un générique qui peut automatiquement analyser un objet personnalisé et de tous les champs de manière récursive, donc vous pouvez utiliser le prototype des méthodes après la désérialisation.
Une hypothèse est que, vous avez défini un spécial déposé que l'indique le type de chaque objet que vous souhaitez appliquer, il est de type automatique (
this.__type
dans l'exemple).utilisation:
Affectation de Type fonction (il fonctionne de manière récursive pour affecter des types de tous les objets imbriqués; il a également parcourt les tableaux de trouver des objets):
Tout, ce n'est pas techniquement ce que vous voulez, si vous le savez avant de la main du type d'objet que vous souhaitez gérer vous pouvez utiliser l'appel/appliquer les méthodes du prototype de votre objet connu.
vous pouvez modifier ce
à ce
Olivers réponses, c'est très clair, mais si vous êtes à la recherche d'une solution en angular js, j'ai écrit une belle module appelé Angulaires-jsClass qui n'cette facilité, les objets définis dans litaral notation est toujours mauvais quand vous êtes en vue d'un gros projet mais en disant que les développeurs sont confrontés problème qui exactement BMiner dit, comment sérialiser un json d'un prototype ou d'un constructeur de la notation des objets
https://github.com/imalhasaranga/Angular-JSClass