У меня есть вложенный объект JSON, который мне нужно перебрать, и значение каждого ключа может быть строкой, массивом JSON или другим объектом JSON. В зависимости от типа объекта мне нужно выполнять разные операции. Есть ли способ проверить тип объекта, чтобы узнать, является ли он строкой, объектом JSON или массивом JSON?
Я пробовал использовать typeof
и, instanceof
но оба, похоже, не работали, так как typeof
вернет объект как для объекта JSON, так и для массива, и instanceof
выдает ошибку, когда я это сделаю obj instanceof JSON
.
Чтобы быть более конкретным, после синтаксического анализа JSON в объект JS, есть ли способ проверить, является ли это нормальной строкой, или объектом с ключами и значениями (из объекта JSON), или массивом (из массива JSON )?
Например:
JSON
var data = "{'hi':
{'hello':
['hi1','hi2']
},
'hey':'words'
}";
Образец 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
}
}
Как выполнить проверку объекта, как показано выше?
источник
.parse()
операцию со строкой JSON, и как ее идентифицировать?Ответы:
Я бы проверил атрибут конструктора.
например
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])); }
Изменить: добавлена нулевая проверка и неопределенная проверка.
источник
else if
не нужен{}.constructor
заставляет меня войтиERROR TypeError: Cannot read property 'constructor' of undefined
в мое угловое приложение.Вы можете использовать Array.isArray для проверки массивов. Затем typeof obj == 'string' и 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));
источник
typeof null === 'object'
[{ "name":[ {"key": "any key" } ] }]
это также действительный json, но его массив возврата по вашему коду. проверьте это - скрипкаОбъект JSON - это объект. Чтобы проверить, является ли тип типом объекта, оцените свойство конструктора.
function isObject(obj) { return obj !== undefined && obj !== null && obj.constructor == Object; }
То же касается и всех остальных типов:
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; }
источник
JSON.parse()
, ресурс JSON становится объектом. Поэтому, если вы тестируете ресурс, поступающий с сервера, чтобы узнать, является ли он JSON, лучше сначала проверить String, затем, если это не a,<empty string>
а затем после синтаксического анализа, является ли это объектом.Если вы пытаетесь проверить тип
object
после синтаксического анализаJSON
строки, я предлагаю проверить атрибут конструктора:obj.constructor == Array || obj.constructor == String || obj.constructor == Object
Это будет намного более быстрая проверка, чем проверка typeof или instanceof.
Если библиотека JSON не возвращает объекты, созданные с помощью этих функций, я бы отнесся к этому очень подозрительно.
источник
Ответ @PeterWilkinson не сработал для меня, потому что конструктор для «типизированного» объекта настроен на имя этого объекта. Мне пришлось работать с typeof
function isJson(obj) { var t = typeof obj; return ['boolean', 'number', 'string', 'symbol', 'function'].indexOf(t) == -1; }
источник
Вы можете создать свой собственный конструктор для разбора JSON:
var JSONObj = function(obj) { $.extend(this, JSON.parse(obj)); } var test = new JSONObj('{"a": "apple"}'); //{a: "apple"}
Затем проверьте instanceof, чтобы узнать, нужно ли изначально анализировать
test instanceof JSONObj
источник
Я написал модуль npm для решения этой проблемы. Это доступно здесь :
object-types
: модуль для определения типов литералов, лежащих в основе объектовУстановить
Применение
const objectTypes = require('object-types'); objectTypes({}); //=> 'object' objectTypes([]); //=> 'array' objectTypes(new Object(true)); //=> 'boolean'
Взгляните, это должно решить вашу точную проблему. Дайте знать, если у вас появятся вопросы! https://github.com/dawsonbotsford/object-types
источник
вы также можете попробовать проанализировать данные, а затем проверить, есть ли у вас объект:
var testIfJson = JSON.parse(data); if (typeOf testIfJson == "object") { //Json } else { //Not Json }
источник
Я комбинирую оператор typeof с проверкой атрибута конструктора (Питером):
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')); });
Результат:
typeOf() input parameter --------------------------- boolean true boolean false number 1 number 2.3 string "string" array [4,5,6] object {"foo":"bar"} null null undefined
источник
Я знаю, что это очень старый вопрос с хорошими ответами. Однако кажется, что еще можно добавить к нему мои 2 ¢.
Предполагая, что вы пытаетесь протестировать не сам объект JSON, а строку, отформатированную как JSON (что, похоже, имеет место в вашем случае
var data
), вы можете использовать следующую функцию, которая возвращает логическое значение (является или не является ' 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 } }
Вот несколько примеров использования указанной выше функции:
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) );
Когда вы запустите приведенный выше код, вы получите следующие результаты:
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
Пожалуйста, попробуйте приведенный ниже фрагмент и сообщите нам, работает ли это для вас. :)
ВАЖНО: функция, представленная в этом посте, была адаптирована из https://airbrake.io/blog/javascript-error-handling/syntaxerror-json-parse-bad-parsing, где вы можете найти больше интересных деталей о 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) );
источник
Попробуй это
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 ; }
Это работает для примера ниже
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 ) );
источник
Почему бы не проверить Number - немного короче и работает в 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])); }
источник
Ответ Петра с дополнительной проверкой! Конечно, не на 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!"); }
источник
попробуйте этот грязный способ
('' + obj).includes('{')
источник