• JSON.parse与eval的区别


     

     

    JSON.parse与eval和能将一个字符串解析成一个JSON对象,但还是有挺大区别。

    测试代码

    复制代码
    var A = "{  a: 1 , b : 'hello' }";
    var B = "{  'a': 1 , 'b' : 'hello' }";
    var C = "{'a':1,'b':'hello'}";
    var D = '{"a":1,"b":"hello"}';
    var E = '{ "a" : 1 , "b" : "hello" }';
    var F = '{ "a" : 1 ,
      "b" : "hello" }';
    var G = '{ "a" : 1 , "b" : window.location.href="https://www.baidu.com" }';
    复制代码

    JSON.parse执行:

    例:JSON.parse(A);

    A、B、C、G都不可转,D、E、F都可以。

    eval执行:

    例:eval("("+A+")");

    A到G都可以转,特别到G时,页面还跳转到百度了。

    JSON.parse

    上面的演示例子可以看出,这方法只能解析属性名是双引号包裹的字符串对象,并会忽略换行和空格(值外面)。

    但是,从MDN对JSON的描述,能解析的JSON字符串的条件完整如下:

    JavaScript类型  JSON与之区别
    对象和数组
    属性名称必须用双引号包裹;
    最后一个属性后面不能有逗号。
    数值
    前导0不能使用(在 JSON.stringify 中将会被忽略,在 JSON.parse 会抛出错误);
    小数点后面至少有一个数字。
    字符串
    只有有限的字符能够被转义;
    不允许某些控制字符;但允许使用Unicode 行分隔符 (U+2028) 和段落分隔符 (U+2029) ;
    字符串必须用双引号括起来。

    这方法还可以捕捉JSON中的语法错误,并允许你传入一个函数,用来过滤或转换解析结果。

    浏览器兼容:IE8+

    eval

    eval函数可将一个JavaScript代码字符串求值成特定的对象,所以解析成JSON对象只不过是作用之一。

    为什么eval()解析JSON字符串要加上括号?

    原因是两点:

    1. json对象是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理。

    2. 加上圆括号为了处理字符串为表达式,而不是语句(statement)来执行。

    例子:

    对象字面量 {},不加外层的括号,那么eval会识别为JS代码块的开始和结束标记,那么 {} 将会被认为是执行了一句空语句。

    alert(eval("{}")); // return undefined
    alert(eval("({})"));// return object[Object]

    不建议使用

    虽然从演示例子看,eval的能力是强过于JSON.parse的,它可解析不规范的JSON字符串,但是G的例子也可以看出,eval是不安全的,特别是数据是第三方给予时候,你根本不知道eval之后它会干什么。

    所以结论就是,乖乖用JSON.parse解析JSON对象。

    $.parseJSON

    jQuery也有提供解析JSON字符串的方法,$.parseJSON ,就目前jQuery版本来讲,分为两类。

    2.x和3.x版本: $.parseJSON 都是直接使用 JSON.parse 的。

    1.x版本:浏览器支持 JSON.parse 就用这个,不支持就进行校验,确认是JSON字符串,则用

      ( Function( "return " + str ) )()

    返回对象,否则返回无效JSON对象error。

    PS:之所以能用Function处理,前提是校验确认为JSON字符串,不然还是不安全的转换方法。

    总结

    eval是强烈不建议用来解析JSON字符串,但是凡事无绝对,如果数据来源于你信任的并且格式也不大规范,那用它也不是不可以。

  • 相关阅读:
    ThinkPHP中PHPExcel的使用(包含日期格式)
    python学习一
    autocomplete 在火狐中文输入的问题
    NPM WARN 错误分析汇总
    react+reatrouter+redux学习笔记
    a++与++a的区别
    ES6箭头函数(Arrow Functions)
    document.referrer
    modem无法编译
    linux时钟浅析 转载
  • 原文地址:https://www.cnblogs.com/aer2005/p/11603216.html
Copyright © 2020-2023  润新知