isJsonString('{ "Id": 1, "Name": "Coke" }')

应该是正确的

isJsonString('foo')
isJsonString('<div>foo</div>')

应该为假。

我正在寻找一种不使用try/catch的解决方案,因为我将调试器设置为“在所有错误上中断”,这导致它在无效的JSON字符串上中断。


当前回答

对于喜欢. net惯例中的“try”函数,它返回一个布尔值并处理一个包含结果的byref参数。如果不需要out参数,可以省略它,只使用返回值。

StringTests.js

  var obj1 = {};
  var bool1 = '{"h":"happy"}'.tryParse(obj1); // false
  var obj2 = {};
  var bool2 = '2114509 GOODLUCKBUDDY 315852'.tryParse(obj2);  // false

  var obj3 = {};
  if('{"house_number":"1","road":"Mauchly","city":"Irvine","county":"Orange County","state":"California","postcode":"92618","country":"United States of America","country_code":"us"}'.tryParse(obj3))
    console.log(obj3);

StringUtils.js

String.prototype.tryParse = function(jsonObject) {
  jsonObject = jsonObject || {};
  try {
    if(!/^[\[{]/.test(this) || !/[}\]]$/.test(this)) // begin / end with [] or {}
      return false; // avoid error handling for strings that obviously aren't json
    var json = JSON.parse(this);
    if(typeof json === 'object'){
      jsonObject.merge(json);
      return true;
    }
  } catch (e) {
    return false;
  }
}

ObjectUtils.js

Object.defineProperty(Object.prototype, 'merge', {
  value: function(mergeObj){
    for (var propertyName in mergeObj) {
      if (mergeObj.hasOwnProperty(propertyName)) {
        this[propertyName] = mergeObj[propertyName];
      }      
    }
    return this;
  },
  enumerable: false, // this is actually the default
});

其他回答

// vanillaJS
function isJSON(str) {
    try {
        return (JSON.parse(str) && !!str);
    } catch (e) {
        return false;
    }
}

用法:isJSON({})将为假,isJSON('{}')将为真。

检查某物是否是数组或对象(解析JSON):

// vanillaJS
function isAO(val) {
    return val instanceof Array || val instanceof Object ? true : false;
}

// ES2015
var isAO = (val) => val instanceof Array || val instanceof Object ? true : false;

用法:isAO({})为真,isAO('{}')为假。

我想我应该在一个实际的例子中加入我的方法。我在处理从Memjs输入和输出的值时使用了类似的检查,所以即使保存的值可能是字符串,数组或对象,Memjs期望的是字符串。该函数首先检查键/值对是否已经存在,如果存在,则进行预检查,以确定值是否需要在返回之前进行解析:

  function checkMem(memStr) {
    let first = memStr.slice(0, 1)
    if (first === '[' || first === '{') return JSON.parse(memStr)
    else return memStr
  }

否则,调用回调函数来创建值,然后检查结果,看看值是否需要在进入Memjs之前进行字符串化,然后返回回调的结果。

  async function getVal() {
    let result = await o.cb(o.params)
    setMem(result)
    return result

    function setMem(result) {
      if (typeof result !== 'string') {
        let value = JSON.stringify(result)
        setValue(key, value)
      }
      else setValue(key, result)
    }
  }

完整的代码如下。当然,这种方法假定数组/对象输入和输出的格式是正确的(例如,“{key: 'testkey']”之类的事情永远不会发生,因为在键/值对到达这个函数之前,所有正确的验证都已经完成了)。而且你只是在memjs中输入字符串,而不是整数或其他非对象/数组类型。

async function getMem(o) {
  let resp
  let key = JSON.stringify(o.key)
  let memStr = await getValue(key)
  if (!memStr) resp = await getVal()
  else resp = checkMem(memStr)
  return resp

  function checkMem(memStr) {
    let first = memStr.slice(0, 1)
    if (first === '[' || first === '{') return JSON.parse(memStr)
    else return memStr
  }

  async function getVal() {
    let result = await o.cb(o.params)
    setMem(result)
    return result

    function setMem(result) {
      if (typeof result !== 'string') {
        let value = JSON.stringify(result)
        setValue(key, value)
      }
      else setValue(key, result)
    }
  }
}

我从开头的注释推断,用例描述的是响应是HTML还是JSON。在这种情况下,当您确实收到JSON时,您可能应该解析它并在代码中的某个位置处理无效JSON。除此之外,我想如果您的浏览器收到了JSON但无效的JSON,您会希望得到通知(用户也会通过代理收到一些有意义的错误消息)!

因此,为JSON执行完整的正则表达式是不必要的(根据我的经验,对于大多数用例来说,这是不必要的)。你可能会更好地使用下面的方法:

function (someString) {
  // test string is opened with curly brace or machine bracket
  if (someString.trim().search(/^(\[|\{){1}/) > -1) {
    try { // it is, so now let's see if its valid JSON
      var myJson = JSON.parse(someString);
      // yep, we're working with valid JSON
    } catch (e) {
      // nope, we got what we thought was JSON, it isn't; let's handle it.
    }
  } else {
    // nope, we're working with non-json, no need to parse it fully
  }
}

这应该节省你不得不异常处理有效的非json代码,同时照顾duff json。

使用JSON.parse这样的JSON解析器:

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

这个答案降低了trycatch语句的代价。

我使用JQuery来解析JSON字符串,我使用trycatch语句来处理异常,但是对于不可解析的字符串抛出异常会降低我的代码,所以我使用简单的Regex来检查字符串,如果它是一个可能的JSON字符串,或者不是通过检查它的语法来羽毛,然后我使用常规的方式通过JQuery解析字符串:

if (typeof jsonData == 'string') {
    if (! /^[\[|\{](\s|.*|\w)*[\]|\}]$/.test(jsonData)) {
        return jsonData;
    }
}

try {
    jsonData = $.parseJSON(jsonData);
} catch (e) {

}

我将前面的代码包装在递归函数中,以解析嵌套的JSON响应。