So überprüfen Sie, ob das JavaScript-Objekt JSON ist

86

Ich habe ein verschachteltes JSON-Objekt, das ich durchlaufen muss, und der Wert jedes Schlüssels kann ein String, ein JSON-Array oder ein anderes JSON-Objekt sein. Je nach Objekttyp muss ich verschiedene Operationen ausführen. Kann ich den Typ des Objekts auf irgendeine Weise überprüfen, um festzustellen, ob es sich um einen String, ein JSON-Objekt oder ein JSON-Array handelt?

Ich habe versucht, typeofund instanceofbeide schienen nicht zu funktionieren, da typeofein Objekt sowohl für das JSON-Objekt als auch für das Array zurückgegeben wird und dabei instanceofein Fehler auftritt obj instanceof JSON.

Genauer gesagt, kann ich nach dem Parsen des JSON in ein JS-Objekt auf irgendeine Weise überprüfen, ob es sich um eine normale Zeichenfolge oder ein Objekt mit Schlüsseln und Werten (von einem JSON-Objekt) oder ein Array (von einem JSON-Array) handelt )?

Beispielsweise:

JSON

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

Beispiel 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
    }
}

Wie führe ich die Objektprüfung wie oben gezeigt durch?

Wei Hao
quelle
3
JSON ist nur eine als Zeichenfolge gespeicherte Notation . Sind Sie sicher, dass Sie Begriffe nicht verwirren?
Zerkms
Nein, ich habe die Frage aktualisiert, um sie klarer zu machen. Ich denke, meine Hauptfrage ist, was passiert, nachdem wir .parse()eine JSON-Zeichenfolge erstellt haben, und wie man sie identifiziert.
Wei Hao
1
Veränderung hat es nicht klarer gemacht (zumindest für mich). Was ist, wenn Sie ein Beispiel für JSON geben, mit dem Sie es zu tun haben
zerkms
Aktualisierte Frage mit einem Beispiel. (:
Wei Hao
Die eigentliche Frage ist: Warum interessiert es dich?
Asherah

Antworten:

129

Ich würde das Konstruktorattribut überprüfen.

z.B

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]));
}

Bearbeiten: Es wurde eine Nullprüfung und eine undefinierte Prüfung hinzugefügt.

Programmierer
quelle
9
else ifist unnötig
McSonk
Ist das nicht dasselbe wie die Verwendung von instanceof? developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Pereira
@ Pereira: JavaScript hat einige verwirrende Falten. Versuchen Sie die Instanz "sicherlich_this_is_a_string" von String.
Programmier Guy
{}.constructorbewirkt, dass ich ERROR TypeError: Cannot read property 'constructor' of undefinedin meine eckige Anwendung komme .
Minyc510
@ Minyc510: Es sieht so aus, als ob sich das Browserverhalten geändert hat. Das Einwickeln in Klammern scheint das Problem zu beheben. Ich habe die Antwort bearbeitet, um dies widerzuspiegeln.
Programmier Guy
24

Sie können Array.isArray verwenden , um nach Arrays zu suchen . Dann typeof obj == 'string' und 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' ist String
'a' ist Array
'o' ist Objekt
'i' ist anderes

McGarnagle
quelle
4
Vergessen Sie nicht, das zu berücksichtigentypeof null === 'object'
hugomg
[{ "name":[ {"key": "any key" } ] }] Dies ist auch gültig json, aber sein Rückgabearray durch Ihren Code. Überprüfen Sie diese - Geige
Sudhir K Gupta
14

Ein JSON-Objekt ist ein Objekt. Um zu überprüfen, ob ein Typ ein Objekttyp ist, bewerten Sie die Konstruktoreigenschaft.

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

Gleiches gilt für alle anderen Typen:

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
quelle
JSON-codierte Ressource ist kein Objekt. Es ist eine Zeichenfolge. Erst nachdem Sie es dekodiert haben oder in Javascript JSON.parse(), wird die JSON-Ressource zu einem Objekt. Wenn Sie eine von einem Server stammende Ressource testen, um festzustellen, ob es sich um JSON handelt, sollten Sie daher zuerst nach String suchen, dann nach a not a <empty string>und dann nach dem Parsen nach einem Objekt.
Hmerman6006
7

Wenn Sie versuchen, den Typ eines zu überprüfen, objectnachdem Sie einen JSONString analysiert haben , empfehle ich, das Konstruktorattribut zu überprüfen:

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

Dies ist eine viel schnellere Überprüfung als typeof oder instanceof.

Wenn eine JSON-Bibliothek keine mit diesen Funktionen erstellten Objekte zurückgibt, wäre ich sehr misstrauisch.

JoshRagem
quelle
Ein viel direkterer Ansatz. Vielen Dank! = D
Eduardo Lucio
Bevorzugte Antwort. Woher erhalten Sie die Informationen zum Leistungsvorteil?
Daniel F
@ DanielF, es war allgemein bekannt in '12, die Dinge sind jetzt alle anders, also weiß ich nicht, ob das gilt
JoshRagem
5

Die Antwort von @PeterWilkinson hat bei mir nicht funktioniert, da ein Konstruktor für ein "typisiertes" Objekt an den Namen dieses Objekts angepasst ist. Ich musste mit Typ arbeiten

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

Sie können Ihren eigenen Konstruktor für das JSON-Parsing erstellen:

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

Überprüfen Sie dann die Instanz von, um festzustellen, ob sie ursprünglich analysiert werden musste

test instanceof JSONObj
matt3141
quelle
4

Ich habe ein npm-Modul geschrieben, um dieses Problem zu lösen. Es ist hier verfügbar :

object-types: Ein Modul zum Finden, welche Literaltypen Objekten zugrunde liegen

Installieren

  npm install --save object-types


Verwendung

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

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

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

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

Werfen Sie einen Blick darauf, es sollte Ihr genaues Problem lösen. Lassen Sie mich wissen, wenn Sie Fragen haben! https://github.com/dawsonbotsford/object-types

Dawson B.
quelle
2

Sie können auch versuchen, die Daten zu analysieren und dann zu überprüfen, ob Sie ein Objekt erhalten haben:

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

Ich kombiniere den Operator typeof mit einer Überprüfung des Konstruktorattributs (von 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'));
});

Ergebnis:

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
quelle
2

Ich weiß, dass dies eine sehr alte Frage mit guten Antworten ist. Es scheint jedoch immer noch möglich zu sein, meine 2 ¢ hinzuzufügen.

Angenommen, Sie versuchen, nicht ein JSON-Objekt selbst zu testen, sondern einen String, der als JSON formatiert ist (was in Ihrem Fall der Fall zu sein scheint var data), könnten Sie die folgende Funktion verwenden, die einen Booleschen Wert zurückgibt (ist oder ist kein ' 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
  }

}

Hier einige Beispiele für die Verwendung der obigen Funktion:

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) );

Wenn Sie den obigen Code ausführen, erhalten Sie die folgenden Ergebnisse:

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

Bitte probieren Sie das folgende Snippet aus und lassen Sie uns wissen, ob dies für Sie funktioniert. :) :)

WICHTIG: Die in diesem Beitrag vorgestellte Funktion wurde von https://airbrake.io/blog/javascript-error-handling/syntaxerror-json-parse-bad-parsing angepasst. Dort finden Sie weitere und interessante Details zu JSON.parse ( ) Funktion.

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
quelle
1

Versuche dies

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 ;
}

Es funktioniert für das folgende Beispiel

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
quelle
0

Peters Antwort mit einem zusätzlichen Scheck! Natürlich nicht 100% garantiert!

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
quelle
0

Warum nicht Number überprüfen - etwas kürzer und funktioniert in 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]));
}

Tom
quelle
-4

versuche es auf diese schmutzige Weise

 ('' + obj).includes('{')
Stan Sokolov
quelle