【问题标题】:How to check if JavaScript object is JSON如何检查 JavaScript 对象是否为 JSON
【发布时间】:2012-06-26 07:55:20
【问题描述】:

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

我尝试使用typeofinstanceof,但两者似乎都不起作用,因为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
    }
}

如上所示,如何进行对象检查?

【问题讨论】:

  • JSON 只是一个存储为 string 的符号。你确定你没有混淆术语吗?
  • 不,我更新了问题以使其更清晰。我想我的主要问题是在我们对 JSON 字符串执行 .parse() 之后会发生什么,以及如何识别它?
  • 变化并没有让它更清楚(至少对我来说)。如果你举一个你正在处理的 JSON 的例子呢
  • 用一个例子更新了问题。 (:
  • 真正的问题是:你为什么在乎?

标签: javascript json


【解决方案1】:

您可以使用 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' 是其他

【讨论】:

  • 别忘了考虑typeof null === 'object'
  • [{ "name":[ {"key": "any key" } ] }] 这也是有效的 json,但它的返回数组由您的代码返回。检查这个 - fiddle
【解决方案2】:

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

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

这将是比 typeof 或 instanceof 更快的检查。

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

【讨论】:

  • 更直接的方法。谢谢! =D
  • 首选答案。您从哪里获得性能收益信息?
  • @DanielF 这是 12 年的常识,现在一切都不同了,所以我不知道这是否成立
【解决方案3】:

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

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

然后检查instanceof,看它是否需要原来的解析

test instanceof JSONObj

【讨论】:

    【解决方案4】:

    我会检查构造函数属性。

    例如

    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 是不必要的
    • @Pereira:JavaScript 有一些令人困惑的皱纹。试试“surely_this_is_a_string”instanceof String。
    • {}.constructor 导致我在我的角度应用程序中得到ERROR TypeError: Cannot read property 'constructor' of undefined
    • 这么多if 声明...使用switch
    【解决方案5】:

    彼得的回答是额外的检查!当然,不是 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!");
    }
    

    【讨论】:

      【解决方案6】:

      @PeterWilkinson 的答案对我不起作用,因为“类型化”对象的构造函数是根据该对象的名称定制的。我不得不与typeof合作

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

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

          【解决方案8】:

          试试这个

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

          【讨论】:

            【解决方案9】:

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

            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

            【讨论】:

              【解决方案10】:

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

              【讨论】:

                【解决方案11】:

                试试这种肮脏的方式

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

                【讨论】:

                  【解决方案12】:

                  一个 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 编码资源不是对象。它是一个字符串。只有在您对其进行解码或在 Javascript JSON.parse() 中对其进行解码后,JSON 资源才会成为一个对象。因此,如果您测试来自服务器的资源是否为 JSON,最好先检查是否为 String,然后检查是否为 &lt;empty string&gt;,然后解析是否为对象。
                  【解决方案13】:

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

                  【讨论】:

                    【解决方案14】:

                    我知道这是一个非常古老的问题,但答案很好。不过,我的 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
                    

                    请尝试下面的 sn-p,让我们知道这是否适合您。 :)

                    重要提示:本文中介绍的函数改编自 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) );

                    【讨论】:

                      【解决方案15】:

                      基于@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"; }
                      
                      }
                      

                      注意:我发现这种方法非常具有指导意义,所以我提交了这个答案。

                      【讨论】:

                        【解决方案16】:

                        我对此有一个非常懒惰的答案,如果您尝试解析字符串/其他值,它不会引发错误。

                        const checkForJson = (value) => {
                            if (typeof value !== "string") return false;
                        
                            return value[0] === "{" && value[value.length - 1] === "}";
                        }
                        

                        你可以在做一些递归函数时使用它来检查你的键的值;抱歉,如果这不能完全回答问题

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

                        TLDR:它不是万无一失的,但它很简单,适用于绝大多数用例。

                        【讨论】:

                        • 如果里面有数组也是不行的。试试JSON.parse(JSON.stringify(['a','b','c',1,2,3])))
                        【解决方案17】:

                        lodash 也是检查这些东西的最佳选择。

                        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

                        【讨论】:

                          【解决方案18】:

                          试试吧,Catch 块会帮你解决这个问题

                          制作函数

                          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
                          

                          【讨论】:

                            猜你喜欢
                            • 2010-09-27
                            • 2011-05-16
                            • 2015-04-02
                            • 1970-01-01
                            • 2019-04-14
                            • 1970-01-01
                            • 2010-11-26
                            • 2023-03-15
                            相关资源
                            最近更新 更多