如何检查 JavaScript 对象是否为 JSON

我需要循环访问一个嵌套的 JSON 对象,每个键的值可以是一个 String、 JSON 数组或另一个 JSON 对象。根据对象的类型,我需要执行不同的操作。有没有什么办法可以检查对象的类型,看看它是一个字符串,JSON 对象或 JSON 数组?

I tried using typeof and instanceof but both didn't seem to work, as typeof will return an object for both JSON object and array, and instanceof gives an error when I do 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
}
}

如何执行上面所示的对象检查?

247060 次浏览

可以使用 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));

‘ s’is string < br > ‘ a’is array < br > ‘ o’is object < br > ‘ i’is other

如果在解析 JSON字符串之后试图检查 object的类型,我建议检查构造函数属性:

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

这将是一个比 typeof 或 instanceof 快得多的检查。

If a JSON library does not return objects constructed with these functions, I would be very suspiciouse of it.

您可以为 JSON 解析创建自己的构造函数:

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

然后检查 instanceof,看看它最初是否需要解析

test instanceof JSONObj

我会检查构造函数属性。

例如:。

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

编辑: 添加了一个空检查和一个未定义的检查。

彼得的回答附加支票! 当然,不是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!");
}

由@PeterWilkinson 给出的答案对我不起作用,因为“类型化”对象的构造函数是根据该对象的名称定制的。我必须和 类型合作

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

您也可以尝试解析数据,然后检查是否得到对象:

try {
var testIfJson = JSON.parse(data);
if (typeof testIfJson == "object"){
//Json
} else {
//Not Json
}
}
catch {
return false;
}

试试这个

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

我编写了一个 npm 模块来解决这个问题:

object-types: 一个查找对象底层文字类型的模块

安装

  npm install --save object-types


Usage

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


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


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


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

看一看,它应该可以解决你的具体问题。如果你有任何问题请告诉我

我将 typeof 操作符与构造函数属性的检查结合起来(由 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'));
});

结果:

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

试试这种肮脏的方式

 ('' + obj).includes('{')

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

为什么不选择 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]));
}

我知道这是一个很老的问题,答案很好。然而,似乎仍然有可能把我的2加进去。

假设您试图测试的不是 JSON 对象本身,而是一个格式化为 JSON 的 String (在您的 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) );

When you run the code above, you will get the following results:

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

基于@Martin Wantke 的回答,但是通过一些推荐的改进/调整..。

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


}

注意: 我发现这个方法非常有说服力,所以我提交了这个答案。

对于这个问题,我有一个相当懒惰的答案,如果您尝试解析字符串/其他值,这个答案不会抛出错误。

const checkForJson = (value) => {
if (typeof value !== "string") return false;


return value[0] === "{" && value[value.length - 1] === "}";
}

您可以在创建一些递归函数时使用它来检查键的值; 如果这没有完全回答这个问题,那么很抱歉

Ofc 这不是最优雅的解决方案,当一个字符串实际上以“{”开头并以“}”结尾时,它就会失败,尽管这些用例很少见,如果你真的想要,你可以检查是否存在引号或其他废话... 无论如何,自己判断使用。

TLDR: 它不是防弹的,但是它很简单,适用于绝大多数用例。

Loash 也是检查这些事情的最佳选择。

function Foo() {
this.a = 1;
}
 

_.isPlainObject(new Foo);
// => false
 

_.isPlainObject([1, 2, 3]);
// => false
 

_.isPlainObject({ 'x': 0, 'y': 0 });
// => true
 

_.isPlainObject(Object.create(null));
// => true

Https://www.npmjs.com/package/lodash
Https://lodash.com/docs/#isplainobject

尝试,捕捉块将帮助您解决这个问题

发挥作用

function IsJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}

例如:

console.log(IsJson('abc')) // false
console.log(IsJson('[{"type":"email","detail":"john@example.com"}]')) // true

使用 罗达什-贡献快速检查 JSON 结构:

const _ = require('lodash-contrib');


_.isJSON('{"car": "ferarri"}'); //true for stringified
_.isJSON({car: "ferarri"}); //true

Usage guide: 这篇博文