Comment vérifier si l'objet JavaScript est JSON

87

J'ai un objet JSON imbriqué que je dois parcourir, et la valeur de chaque clé peut être une chaîne, un tableau JSON ou un autre objet JSON. Selon le type d'objet, je dois effectuer différentes opérations. Existe-t-il un moyen de vérifier le type de l'objet pour voir s'il s'agit d'une chaîne, d'un objet JSON ou d'un tableau JSON?

J'ai essayé d'utiliser typeofet instanceofmais les deux ne semblaient pas fonctionner, tout comme typeofle retour d'un objet pour l'objet JSON et le tableau, et instanceofdonnant une erreur lorsque je le fais obj instanceof JSON.

Pour être plus précis, après avoir analysé le JSON dans un objet JS, existe-t-il un moyen de vérifier s'il s'agit d'une chaîne normale, ou d'un objet avec des clés et des valeurs (à partir d'un objet JSON), ou d'un tableau (à partir d'un tableau JSON )?

Par exemple:

JSON

var data = "{'hi':
             {'hello':
               ['hi1','hi2']
             },
            'hey':'words'
           }";

Exemple de JavaScript

var jsonObj = JSON.parse(data);
var path = ["hi","hello"];

function check(jsonObj, path) {
    var parent = jsonObj;
    for (var i = 0; i < path.length-1; i++) {
        var key = path[i];
        if (parent != undefined) {
            parent = parent[key];
        }
    }
    if (parent != undefined) {
        var endLength = path.length - 1;
        var child = parent[path[endLength]];
        //if child is a string, add some text
        //if child is an object, edit the key/value
        //if child is an array, add a new element
        //if child does not exist, add a new key/value
    }
}

Comment effectuer la vérification des objets comme indiqué ci-dessus?

Wei Hao
la source
3
JSON est juste une notation stockée sous forme de chaîne . Êtes-vous sûr de ne pas confondre les termes?
zerkms
Non, j'ai mis à jour la question pour la rendre plus claire. Je suppose que ma question principale est de savoir ce qui se passe après avoir fait un .parse()sur une chaîne JSON, et comment l'identifier?
Wei Hao
1
le changement ne l'a pas rendu plus clair (au moins pour moi). Et si vous donniez un exemple de JSON avec lequel vous avez affaire
zerkms
Question mise à jour avec un exemple. (:
Wei Hao
La vraie question est: pourquoi vous souciez-vous?
Asherah

Réponses:

130

Je vérifierais l'attribut du constructeur.

par exemple

var stringConstructor = "test".constructor;
var arrayConstructor = [].constructor;
var objectConstructor = ({}).constructor;

function whatIsIt(object) {
    if (object === null) {
        return "null";
    }
    if (object === undefined) {
        return "undefined";
    }
    if (object.constructor === stringConstructor) {
        return "String";
    }
    if (object.constructor === arrayConstructor) {
        return "Array";
    }
    if (object.constructor === objectConstructor) {
        return "Object";
    }
    {
        return "don't know";
    }
}

var testSubjects = ["string", [1,2,3], {foo: "bar"}, 4];

for (var i=0, len = testSubjects.length; i < len; i++) {
    alert(whatIsIt(testSubjects[i]));
}

Edit: Ajout d'une vérification nulle et d'une vérification non définie.

Guy de programmation
la source
9
else ifn'est pas nécessaire
McSonk
N'est-ce pas la même chose que d'utiliser instanceof? developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Pereira
@Pereira: JavaScript a quelques rides déroutantes. Essayez l'instance "surely_this_is_a_string" de String.
Programmation Guy
{}.constructorme fait entrer ERROR TypeError: Cannot read property 'constructor' of undefineddans mon application angulaire.
kebab-case
@ Minyc510: On dirait que le comportement du navigateur a changé. L'emballage entre parenthèses semble résoudre le problème. J'ai modifié la réponse pour refléter cela.
Programmation Guy
25

Vous pouvez utiliser Array.isArray pour rechercher des tableaux. Puis typeof obj == 'string' , et typeof obj == 'object' .

var s = 'a string', a = [], o = {}, i = 5;
function getType(p) {
    if (Array.isArray(p)) return 'array';
    else if (typeof p == 'string') return 'string';
    else if (p != null && typeof p == 'object') return 'object';
    else return 'other';
}
console.log("'s' is " + getType(s));
console.log("'a' is " + getType(a));
console.log("'o' is " + getType(o));
console.log("'i' is " + getType(i));

's' est une chaîne
'a' est un tableau
'o' est l'objet
'i' est autre

McGarnagle
la source
5
N'oubliez pas de prendre en compte celatypeof null === 'object'
hugomg
[{ "name":[ {"key": "any key" } ] }] c'est également json valide mais son tableau de retour par votre code. check this - violon
Sudhir K Gupta
15

Un objet JSON est un objet. Pour vérifier si un type est un type d'objet, évaluez la propriété du constructeur.

function isObject(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Object;
}

La même chose s'applique à tous les autres types:

function isArray(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Array;
}

function isBoolean(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Boolean;
}

function isFunction(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Function;
}

function isNumber(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Number;
}

function isString(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == String;
}

function isInstanced(obj)
{
    if(obj === undefined || obj === null) { return false; }

    if(isArray(obj)) { return false; }
    if(isBoolean(obj)) { return false; }
    if(isFunction(obj)) { return false; }
    if(isNumber(obj)) { return false; }
    if(isObject(obj)) { return false; }
    if(isString(obj)) { return false; }

    return true;
}
Martin Wantke
la source
2
La ressource codée JSON n'est pas un objet. C'est une chaîne. Ce n'est qu'après l'avoir décodé ou en Javascript JSON.parse()que la ressource JSON devient un objet. Par conséquent, si vous testez une ressource provenant d'un serveur pour voir s'il s'agit de JSON, il est préférable de vérifier d'abord String, puis si n'est pas un <empty string>et ensuite après avoir analysé s'il s'agit d'un objet.
Hmerman6006
8

Si vous essayez de vérifier le type d'un objectaprès avoir analysé une JSONchaîne, je vous suggère de vérifier l'attribut du constructeur:

obj.constructor == Array || obj.constructor == String || obj.constructor == Object

Ce sera une vérification beaucoup plus rapide que typeof ou instanceof.

Si une bibliothèque JSON ne renvoie pas d'objets construits avec ces fonctions, je m'en méfierais beaucoup.

JoshRagem
la source
Une approche beaucoup plus directe. Merci! = D
Eduardo Lucio
Réponse préférée. D'où proviennent les informations sur les avantages des performances?
Daniel F
@DanielF c'était la sagesse courante en 2012, les choses sont toutes différentes maintenant, donc je ne sais pas si cela tient
JoshRagem
5

La réponse de @PeterWilkinson n'a pas fonctionné pour moi car un constructeur pour un objet "typé" est personnalisé au nom de cet objet. Je devais travailler avec typeof

function isJson(obj) {
    var t = typeof obj;
    return ['boolean', 'number', 'string', 'symbol', 'function'].indexOf(t) == -1;
}
Dmitry Efimenko
la source
4

Vous pouvez créer votre propre constructeur pour l'analyse JSON:

var JSONObj = function(obj) { $.extend(this, JSON.parse(obj)); }
var test = new JSONObj('{"a": "apple"}');
//{a: "apple"}

Vérifiez ensuite instanceof pour voir s'il avait besoin d'une analyse à l'origine

test instanceof JSONObj
matt3141
la source
4

J'ai écrit un module npm pour résoudre ce problème. Il est disponible ici :

object-types: un module pour trouver quels types littéraux sous-tendent les objets

Installer

  npm install --save object-types


Usage

const objectTypes = require('object-types');

objectTypes({});
//=> 'object'

objectTypes([]);
//=> 'array'

objectTypes(new Object(true));
//=> 'boolean'

Jetez un œil, cela devrait résoudre votre problème exact. Faites moi savoir si vous avez des questions! https://github.com/dawsonbotsford/object-types

Dawson B
la source
2

vous pouvez également essayer d'analyser les données, puis vérifier si vous avez un objet:

var testIfJson = JSON.parse(data);
if (typeOf testIfJson == "object")
{
//Json
}
else
{
//Not Json
}
Arielhad
la source
2

Je combine l'opérateur typeof avec une vérification de l'attribut constructeur (par Peter):

var typeOf = function(object) {
    var firstShot = typeof object;
    if (firstShot !== 'object') {
        return firstShot;
    } 
    else if (object.constructor === [].constructor) {
        return 'array';
    }
    else if (object.constructor === {}.constructor) {
        return 'object';
    }
    else if (object === null) {
        return 'null';
    }
    else {
        return 'don\'t know';
    } 
}

// Test
var testSubjects = [true, false, 1, 2.3, 'string', [4,5,6], {foo: 'bar'}, null, undefined];

console.log(['typeOf()', 'input parameter'].join('\t'))
console.log(new Array(28).join('-'));
testSubjects.map(function(testSubject){
    console.log([typeOf(testSubject), JSON.stringify(testSubject)].join('\t\t'));
});

Résultat:

typeOf()    input parameter
---------------------------
boolean     true
boolean     false
number      1
number      2.3
string      "string"
array       [4,5,6]
object      {"foo":"bar"}
null        null
undefined       
Martin Skorupski
la source
2

Je sais que c'est une question très ancienne avec de bonnes réponses. Cependant, il semble qu'il soit toujours possible d'y ajouter mes 2 ¢.

En supposant que vous essayez de tester non pas un objet JSON lui-même, mais une chaîne qui est formatée comme un JSON (ce qui semble être le cas dans votre var data), vous pouvez utiliser la fonction suivante qui renvoie un booléen (est ou n'est pas un ' JSON '):

function isJsonString( jsonString ) {

  // This function below ('printError') can be used to print details about the error, if any.
  // Please, refer to the original article (see the end of this post)
  // for more details. I suppressed details to keep the code clean.
  //
  let printError = function(error, explicit) {
  console.log(`[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}`);
  }


  try {
      JSON.parse( jsonString );
      return true; // It's a valid JSON format
  } catch (e) {
      return false; // It's not a valid JSON format
  }

}

Voici quelques exemples d'utilisation de la fonction ci-dessus:

console.log('\n1 -----------------');
let j = "abc";
console.log( j, isJsonString(j) );

console.log('\n2 -----------------');
j = `{"abc": "def"}`;
console.log( j, isJsonString(j) );

console.log('\n3 -----------------');
j = '{"abc": "def}';
console.log( j, isJsonString(j) );

console.log('\n4 -----------------');
j = '{}';
console.log( j, isJsonString(j) );

console.log('\n5 -----------------');
j = '[{}]';
console.log( j, isJsonString(j) );

console.log('\n6 -----------------');
j = '[{},]';
console.log( j, isJsonString(j) );

console.log('\n7 -----------------');
j = '[{"a":1, "b":   2}, {"c":3}]';
console.log( j, isJsonString(j) );

Lorsque vous exécutez le code ci-dessus, vous obtiendrez les résultats suivants:

1 -----------------
abc false

2 -----------------
{"abc": "def"} true

3 -----------------
{"abc": "def} false

4 -----------------
{} true

5 -----------------
[{}] true

6 -----------------
[{},] false

7 -----------------
[{"a":1, "b":   2}, {"c":3}] true

Veuillez essayer l'extrait ci-dessous et dites-nous si cela fonctionne pour vous. :)

IMPORTANT: la fonction présentée dans cet article a été adaptée de https://airbrake.io/blog/javascript-error-handling/syntaxerror-json-parse-bad-parsing où vous pouvez trouver plus de détails intéressants sur le JSON.parse ( ) fonction.

function isJsonString( jsonString ) {

  let printError = function(error, explicit) {
  console.log(`[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}`);
  }


  try {
      JSON.parse( jsonString );
      return true; // It's a valid JSON format
  } catch (e) {
      return false; // It's not a valid JSON format
  }

}


console.log('\n1 -----------------');
let j = "abc";
console.log( j, isJsonString(j) );

console.log('\n2 -----------------');
j = `{"abc": "def"}`;
console.log( j, isJsonString(j) );

console.log('\n3 -----------------');
j = '{"abc": "def}';
console.log( j, isJsonString(j) );

console.log('\n4 -----------------');
j = '{}';
console.log( j, isJsonString(j) );

console.log('\n5 -----------------');
j = '[{}]';
console.log( j, isJsonString(j) );

console.log('\n6 -----------------');
j = '[{},]';
console.log( j, isJsonString(j) );

console.log('\n7 -----------------');
j = '[{"a":1, "b":   2}, {"c":3}]';
console.log( j, isJsonString(j) );

Almir Campos
la source
1

Essaye ça

if ( typeof is_json != "function" )
function is_json( _obj )
{
    var _has_keys = 0 ;
    for( var _pr in _obj )
    {
        if ( _obj.hasOwnProperty( _pr ) && !( /^\d+$/.test( _pr ) ) )
        {
           _has_keys = 1 ;
           break ;
        }
    }

    return ( _has_keys && _obj.constructor == Object && _obj.constructor != Array ) ? 1 : 0 ;
}

Cela fonctionne pour l'exemple ci-dessous

var _a = { "name" : "me",
       "surname" : "I",
       "nickname" : {
                      "first" : "wow",
                      "second" : "super",
                      "morelevel" : {
                                      "3level1" : 1,
                                      "3level2" : 2,
                                      "3level3" : 3
                                    }
                    }
     } ;

var _b = [ "name", "surname", "nickname" ] ;
var _c = "abcdefg" ;

console.log( is_json( _a ) );
console.log( is_json( _b ) );
console.log( is_json( _c ) );
Sandro Rosa
la source
1

Pourquoi ne pas vérifier Number - un peu plus court et fonctionne dans IE / Chrome / FF / node.js

function whatIsIt(object) {
    if (object === null) {
        return "null";
    }
    else if (object === undefined) {
        return "undefined";
    }
    if (object.constructor.name) {
            return object.constructor.name;
    }
    else { // last chance 4 IE: "\nfunction Number() {\n    [native code]\n}\n" / node.js: "function String() { [native code] }"
        var name = object.constructor.toString().split(' ');
        if (name && name.length > 1) {
            name = name[1];
            return name.substr(0, name.indexOf('('));
        }
        else { // unreachable now(?)
            return "don't know";
        }
    }
}

var testSubjects = ["string", [1,2,3], {foo: "bar"}, 4];
// Test all options
console.log(whatIsIt(null));
console.log(whatIsIt());
for (var i=0, len = testSubjects.length; i < len; i++) {
    console.log(whatIsIt(testSubjects[i]));
}

À M
la source
0

Réponse de Peter avec un chèque supplémentaire! Bien sûr, pas garanti à 100%!

var isJson = false;
outPutValue = ""
var objectConstructor = {}.constructor;
if(jsonToCheck.constructor === objectConstructor){
    outPutValue = JSON.stringify(jsonToCheck);
    try{
            JSON.parse(outPutValue);
            isJson = true;
    }catch(err){
            isJson = false;
    }
}

if(isJson){
    alert("Is json |" + JSON.stringify(jsonToCheck) + "|");
}else{
    alert("Is other!");
}
Eduardo Lucio
la source
-5

essaie de cette manière sale

 ('' + obj).includes('{')
Stan Sokolov
la source