Mam zagnieżdżony obiekt JSON, przez który muszę przechodzić w pętli, a wartością każdego klucza może być String, tablica JSON lub inny obiekt JSON. W zależności od rodzaju przedmiotu muszę wykonywać różne operacje. Czy istnieje sposób, aby sprawdzić typ obiektu, aby zobaczyć, czy jest to String, obiekt JSON czy tablica JSON?
Próbowałem użyć typeof
i, instanceof
ale oba nie działały, ponieważ typeof
zwróci obiekt zarówno dla obiektu JSON, jak i tablicy, i instanceof
wyświetli błąd, gdy to zrobię obj instanceof JSON
.
Mówiąc dokładniej, po przeanalizowaniu JSON w obiekt JS, czy istnieje sposób, w jaki mogę sprawdzić, czy jest to zwykły ciąg, czy obiekt z kluczami i wartościami (z obiektu JSON) lub tablica (z tablicy JSON )?
Na przykład:
JSON
var data = "{'hi':
{'hello':
['hi1','hi2']
},
'hey':'words'
}";
Przykładowy 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
}
}
Jak mogę sprawdzić obiekt, jak pokazano powyżej?
źródło
.parse()
ciągu JSON i jak go zidentyfikować?Odpowiedzi:
Sprawdziłbym atrybut konstruktora.
na przykład
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])); }
Edycja: Dodano sprawdzenie zerowe i niezdefiniowane sprawdzenie.
źródło
else if
jest niepotrzebne{}.constructor
powoduje, że dostaję sięERROR TypeError: Cannot read property 'constructor' of undefined
do mojej aplikacji kątowej.if
instrukcji ... Użyjswitch
!Możesz użyć Array.isArray, aby sprawdzić tablice. Następnie typeof obj == 'string' i 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));
źródło
typeof null === 'object'
[{ "name":[ {"key": "any key" } ] }]
jest to również poprawny plik json, ale jego tablica zwracana przez Twój kod. sprawdź to - skrzypceObiekt JSON jest obiektem. Aby sprawdzić, czy typ jest typem obiektu, oceń właściwość konstruktora.
function isObject(obj) { return obj !== undefined && obj !== null && obj.constructor == Object; }
To samo dotyczy wszystkich innych typów:
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; }
źródło
JSON.parse()
zasób JSON staje się obiektem. Dlatego jeśli testujesz zasób pochodzący z serwera, aby zobaczyć, czy jest to JSON, najlepiej najpierw sprawdzić, czy nie ma String, a następnie, jeśli nie jest a,<empty string>
a następnie po przeanalizowaniu, czy jest to obiekt.Jeśli próbujesz sprawdzić typ ciągu
object
po przeanalizowaniuJSON
ciągu, sugeruję sprawdzenie atrybutu konstruktora:obj.constructor == Array || obj.constructor == String || obj.constructor == Object
Będzie to znacznie szybsze sprawdzenie niż typeof czy instanceof.
Jeśli biblioteka JSON nie zwraca obiektów skonstruowanych za pomocą tych funkcji, byłbym bardzo podejrzliwy.
źródło
Możesz stworzyć własny konstruktor do analizowania JSON:
var JSONObj = function(obj) { $.extend(this, JSON.parse(obj)); } var test = new JSONObj('{"a": "apple"}'); //{a: "apple"}
Następnie sprawdź instanceof, aby zobaczyć, czy pierwotnie wymagał parsowania
test instanceof JSONObj
źródło
Odpowiedź @PeterWilkinson nie zadziałała dla mnie, ponieważ konstruktor obiektu „wpisanego” jest dostosowany do nazwy tego obiektu. Musiałem pracować z typeof
function isJson(obj) { var t = typeof obj; return ['boolean', 'number', 'string', 'symbol', 'function'].indexOf(t) == -1; }
źródło
Napisałem moduł npm, aby rozwiązać ten problem. Jest dostępny tutaj :
object-types
: moduł do znajdowania typów literałów znajdujących się pod obiektamizainstalować
Stosowanie
const objectTypes = require('object-types'); objectTypes({}); //=> 'object' objectTypes([]); //=> 'array' objectTypes(new Object(true)); //=> 'boolean'
Spójrz, to powinno rozwiązać twój dokładny problem. Daj mi znać, jeśli masz jakieś pytania! https://github.com/dawsonbotsford/object-types
źródło
możesz również spróbować przeanalizować dane, a następnie sprawdzić, czy masz obiekt:
var testIfJson = JSON.parse(data); if (typeOf testIfJson == "object") { //Json } else { //Not Json }
źródło
Łączę operator typeof ze sprawdzeniem atrybutu konstruktora (autorstwa Petera):
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')); });
Wynik:
typeOf() input parameter --------------------------- boolean true boolean false number 1 number 2.3 string "string" array [4,5,6] object {"foo":"bar"} null null undefined
źródło
Dlaczego nie sprawdzić Numer - trochę krótszy i działa w 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])); }
źródło
Wiem, że to bardzo stare pytanie z dobrymi odpowiedziami. Wydaje się jednak, że nadal można dodać do tego moje 2 ¢.
Zakładając, że próbujesz przetestować nie sam obiekt JSON, ale String sformatowany jako JSON (co wydaje się mieć miejsce w twoim
var data
), możesz użyć następującej funkcji, która zwraca wartość logiczną (jest lub nie jest ' 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 } }
Oto kilka przykładów użycia powyższej funkcji:
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) );
Po uruchomieniu powyższego kodu otrzymasz następujące wyniki:
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
Wypróbuj poniższy fragment i daj nam znać, czy to działa w Twoim przypadku. :)
WAŻNE: funkcja przedstawiona w tym poście została zaadaptowana z https://airbrake.io/blog/javascript-error-handling/syntaxerror-json-parse-bad-parsing, gdzie można znaleźć więcej i interesujących szczegółów na temat JSON.parse ( ).
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) );
źródło
Spróbuj tego
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 ; }
Działa na poniższym przykładzie
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 ) );
źródło
Odpowiedź Piotra z dodatkowym czekiem! Oczywiście nie gwarantuje to 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!"); }
źródło
Na podstawie odpowiedzi @Martin Wantke, ale z kilkoma zalecanymi ulepszeniami / dostosowaniami ...
// NOTE: Check JavaScript type. By Questor function getJSType(valToChk) { function isUndefined(valToChk) { return valToChk === undefined; } function isNull(valToChk) { return valToChk === null; } function isArray(valToChk) { return valToChk.constructor == Array; } function isBoolean(valToChk) { return valToChk.constructor == Boolean; } function isFunction(valToChk) { return valToChk.constructor == Function; } function isNumber(valToChk) { return valToChk.constructor == Number; } function isString(valToChk) { return valToChk.constructor == String; } function isObject(valToChk) { return valToChk.constructor == Object; } if(isUndefined(valToChk)) { return "undefined"; } if(isNull(valToChk)) { return "null"; } if(isArray(valToChk)) { return "array"; } if(isBoolean(valToChk)) { return "boolean"; } if(isFunction(valToChk)) { return "function"; } if(isNumber(valToChk)) { return "number"; } if(isString(valToChk)) { return "string"; } if(isObject(valToChk)) { return "object"; } }
UWAGA: Uznałem to podejście za bardzo dydaktyczne, więc przedstawiłem tę odpowiedź.
źródło
spróbuj w ten brudny sposób
('' + obj).includes('{')
źródło