如何检查JavaScript对象是否为JSON


87

我有一个需要循环浏览的嵌套JSON对象,每个键的值可以是String,JSON数组或另一个JSON对象。根据对象的类型,我需要执行不同的操作。有什么方法可以检查对象的类型以查看它是String,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
    }
}

如何执行上述对象检查?


3
JSON只是存储为字符串的一种表示法。您确定您不会混淆条款吗?
zerkms 2012年

不,我更新了问题以使其更清楚。我想我的主要问题是,在.parse()对JSON字符串执行操作之后会发生什么,以及如何识别它?
魏浩

1
变化还没有变得更清楚(对我而言)。如果您给出要处理的JSON示例,该怎么办
zerkms 2012年

用示例更新了问题。(:
Wei Hao

真正的问题是:你为什么在乎?
Asherah 2012年

Answers:


130

我会检查构造函数属性。

例如

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

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


9
else if是不必要的
McSonk '17


@Pereira:JavaScript有一些令人困惑的皱纹。尝试String的“ surely_this_is_a_string”实例。
编程人

{}.constructor使我进入ERROR TypeError: Cannot read property 'constructor' of undefined我的角度应用程序。
Minyc510

@ Minyc510:似乎浏览器行为已更改。用括号包裹似乎可以解决此问题。我已经编辑了答案以反映这一点。
编程专家

25

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

's'是字符串
'a'是数组
'o'是对象
'i'是其他


5
别忘了考虑到这一点typeof null === 'object'
hugomg

[{ "name":[ {"key": "any key" } ] }] 这也是有效的json,但由您的代码返回数组。检查此-小提琴
Sudhir K Gupta '18

15

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

2
JSON编码的资源不是对象。它是一个字符串。只有在您对其进行解码或使用Javascript进行解码之后JSON.parse(),JSON资源才成为对象。因此,如果您测试来自服务器的资源以查看它是否为JSON,则最好先检查String,然后检查is是否不是a <empty string>,然后在分析它是否为对象之后。
Hmerman6006

8

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

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

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

如果JSON库未返回使用这些函数构造的对象,我将对此非常怀疑。


更直接的方法。谢谢!= D
Eduardo Lucio '18

首选答案。您从哪里获得性能收益信息?
Daniel F

@DanielF这是12年前的常识,现在情况都不同了,所以我不知道这是否成立
JoshRagem

5

@PeterWilkinson的答案对我不起作用,因为针对“类型化”对象的构造函数已针对该对象的名称进行了自定义。我不得不使用typeof

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

4

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

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

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

test instanceof JSONObj

4

我写了一个npm模块来解决这个问题。在这里可用:

object-types:用于查找对象的文字类型的模块

安装

  npm install --save object-types


用法

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

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

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

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

看一看,它应该可以解决您的确切问题。如果您有任何疑问,请告诉我!https://github.com/dawsonbotsford/object-types


2

您还可以尝试解析数据,然后检查是否有对象:

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

2

我将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       

2

我知道这是一个非常老的问题,答案很好。但是,似乎仍然可以在其中加上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) );

当您运行上面的代码时,您将得到以下结果:

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


1

试试这个

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

1

为什么不检查数字-短一点并且可以在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]));
}


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.