您的位置:奥门新浦京网址 > Wed前段 > eval解析JSON字符串的一个小问题,实现数据压缩

eval解析JSON字符串的一个小问题,实现数据压缩

发布时间:2019-12-15 01:51编辑:Wed前段浏览(100)

    利用 canvas 实现数据压缩

    2016/03/15 · HTML5 · 1 评论 · Canvas

    原文出处: EtherDream   

    JavaScript 数组方法对比

    2017/02/15 · JavaScript · 数组

    本文由 伯乐在线 - 涂鸦码龙 翻译。未经许可,禁止转载!
    英文出处:Loren Stewart。欢迎加入翻译组。

    JavaScript 提供了多种新增,移除,替换数组元素的方法,但是有些会影响原来的数组;有些则不会,它是新建了一个数组。

    注意:区分以下两个方法的不同点:

    1. array.splice() 影响原来的数组
    2. array.slice() 不影响原来的数组

    eval解析JSON字符串的一个小问题

    2016/02/24 · JavaScript · JSON

    原文出处: 韩子迟   

    之前写过一篇 关于 JSON 的介绍文章,里面谈到了 JSON 的解析。我们都知道,高级浏览器可以用  JSON.parse() API 将一个 JSON 字符串解析成 JSON 数据,稍微欠妥点的做法,我们可以用 eval() 函数。

    JavaScript

    var str = '{"name": "hanzichi", "age": 10}'; var obj = eval('(' + str + ')'); console.log(obj); // Object {name: "hanzichi", age: 10}

    1
    2
    3
    var str = '{"name": "hanzichi", "age": 10}';
    var obj = eval('(' + str + ')');
    console.log(obj); // Object {name: "hanzichi", age: 10}

     

    是否注意到,向 eval() 传参时,str 变量外裹了一层小括号?为什么要这样做?

    我们先来看看 eval 函数的定义以及使用。

    eval() 的参数是一个字符串。如果字符串表示了一个表达式,eval() 会对表达式求值。如果参数表示了一个或多个 JavaScript 声明, 那么 eval() 会执行声明。不要调用 eval() 来为算数表达式求值; JavaScript 会自动为算数表达式求值。

    简单地说,eval 函数的参数是一个字符串,如果把字符串 “noString” 化处理,那么得到的将是正常的可以运行的 JavaScript 语句。

    怎么说?举个栗子,如下代码:

    JavaScript

    var str = "alert('hello world')"; eval(str);

    1
    2
    var str = "alert('hello world')";
    eval(str);

    执行后弹出 “hello world”。我们把 str 变量 “noString” 化,粗暴点的做法就是去掉外面的引号,内部调整(转义等),然后就变成了:

    JavaScript

    alert('hello world')

    1
    alert('hello world')

    very good!这是正常的可以运行的 JavaScript 语句!运行之!

    再回到开始的问题,为什么 JSON 字符串要裹上小括号。如果不加,是这个样子的:

    JavaScript

    var str = '{"name": "hanzichi", "age": 10}'; var obj = eval(str); // Uncaught SyntaxError: Unexpected token :

    1
    2
    var str = '{"name": "hanzichi", "age": 10}';
    var obj = eval(str);  // Uncaught SyntaxError: Unexpected token :

    恩,报错了。为什么会报错?试试把 str “noString” 化,执行一下:

    JavaScript

    {"name": "hanzichi", "age": 10}; // Uncaught SyntaxError: Unexpected token :

    1
    {"name": "hanzichi", "age": 10};  // Uncaught SyntaxError: Unexpected token :

    毫无疑问,一个 JSON 对象或者说是一个对象根本就不是能执行的 JavaScript 语句!等等,试试以下代码:

    JavaScript

    var str = '{name: "hanzichi"}'; var obj = eval(str); console.log(obj); // hanzichi

    1
    2
    3
    var str = '{name: "hanzichi"}';
    var obj = eval(str);
    console.log(obj); // hanzichi

    这又是什么鬼?但是给 name 加上 “” 又报错?

    JavaScript

    var str = '{"name": "hanzichi"}'; var obj = eval(str); // Uncaught SyntaxError: Unexpected token : console.log(obj);

    1
    2
    3
    var str = '{"name": "hanzichi"}';
    var obj = eval(str);  // Uncaught SyntaxError: Unexpected token :
    console.log(obj);

    好吧,快晕了,其实还是可以将 str “nostring” 化,看看是不是能正确执行的 JavaScript 语句。前者的结果是:

    JavaScript

    {name: "hanzichi"}

    1
    {name: "hanzichi"}

    这确实是一条合法的 JavaScript 语句。{} 我们不仅能在 if、for 语句等场景使用,甚至可以在任何时候,因为 ES6 之前 JavaScript 只有块级作用域,所以对于作用域什么的并不会有什么冲突。去掉 {} 后 name: "hanzichi"也是合法的语句,一个 label 语句,label 语句在跳出嵌套的循环中非常好用,具体可以参考 label,而作为 label 语句的标记,name 是不能带引号的,标记能放在 JavaScript 代码的任何位置,用不到也没关系。

    一旦一个对象有了两个 key,比如 {name: "hanzichi", age: 10} ,ok,两个 label 语句?将 “hanzhichi” 以及 10 分别看做是语句,但是 语句之间只能用封号连接!(表达式之间才能用逗号)。所以改成下面这样也是没有问题的:

    JavaScript

    var str = '{name: "hanzichi"; age: 10}'; var obj = eval(str); console.log(obj); // 10

    1
    2
    3
    var str = '{name: "hanzichi"; age: 10}';
    var obj = eval(str);  
    console.log(obj); // 10

    越扯越远,文章开头代码的错误的原因是找到了,为什么套个括号就能解决呢?简单来说,() 会把语句转换成表达式,称为语句表达式。括号里的代码都会被转换为表达式求值并且返回,对象字面量必须作为表达式而存在

    本文并不会大谈表达式,关于表达式,可以参考文末链接。值得记住的一点是,表达式永远有一个返回值。大部分表达式会包裹在() 内,小括号内不能为空,如果有多个表达式,用逗号隔开,也就是所谓的逗号表达式,会返回最后一个的值。

    说到表达式,不得不提函数表达式,以前翻译过一篇关于立即执行函数表达式的文章,可以参考下,文末。

    Read More:

    • [译]JavaScript中:表达式和语句的区别
    • (译)详解javascript立即执行函数表达式(IIFE)
    • 深入探究javascript的 {} 语句块

      1 赞 1 收藏 评论

    图片 1

    前言

    HTTP 支持 GZip 压缩,可节省不少传输资源。但遗憾的是,只有下载才有,上传并不支持。

    如果上传也能压缩,那就完美了。特别适合大量文本提交的场合,比如博客园,就是很好的例子。

    虽然标准不支持「上传压缩」,但仍可以自己来实现。

    I. 新增:影响原数组

    使用 array.push()array.ushift() 新增元素会影响原来的数组。

    JavaScript

    let mutatingAdd = ['a', 'b', 'c', 'd', 'e']; mutatingAdd.push('f'); // ['a', 'b', 'c', 'd', 'e', 'f'] mutatingAdd.unshift('z'); // ['z', 'b', 'c', 'd', 'e' 'f']

    1
    2
    3
    let mutatingAdd = ['a', 'b', 'c', 'd', 'e'];
    mutatingAdd.push('f'); // ['a', 'b', 'c', 'd', 'e', 'f']
    mutatingAdd.unshift('z'); // ['z', 'b', 'c', 'd', 'e' 'f']

    Flash

    首选方案当然是 Flash,毕竟它提供了压缩 API。除了 zip 格式,还支持 lzma 这种超级压缩。

    因为是原生接口,所以性能极高。而且对应的 swf 文件,也非常小。

    II. 新增:不影响原数组

    两种方式新增元素不会影响原数组,第一种是 array.concat()

    JavaScript

    const arr1 = ['a', 'b', 'c', 'd', 'e']; const arr2 = arr1.concat('f'); // ['a', 'b', 'c', 'd', 'e', 'f'] (注:原文有误,我做了修改 “.” ---> “,”) console.log(arr1); // ['a', 'b', 'c', 'd', 'e']

    1
    2
    3
    const arr1 = ['a', 'b', 'c', 'd', 'e'];
    const arr2 = arr1.concat('f'); // ['a', 'b', 'c', 'd', 'e', 'f']  (注:原文有误,我做了修改 “.” ---> “,”)
    console.log(arr1); // ['a', 'b', 'c', 'd', 'e']

    第二种方法是使用 JavaScript 的展开(spread)操作符,展开操作符是三个点(…)

    JavaScript

    const arr1 = ['a', 'b', 'c', 'd', 'e']; const arr2 = [...arr1, 'f']; // ['a', 'b', 'c', 'd', 'e', 'f'] const arr3 = ['z', ...arr1]; // ['z', 'a', 'b', 'c', 'd', 'e']

    1
    2
    3
    const arr1 = ['a', 'b', 'c', 'd', 'e'];
    const arr2 = [...arr1, 'f']; // ['a', 'b', 'c', 'd', 'e', 'f']  
    const arr3 = ['z', ...arr1]; // ['z', 'a', 'b', 'c', 'd', 'e']

    展开操作符会复制原来的数组,从原数组取出所有元素,然后存入新的环境。

    JavaScript

    Flash 逐渐淘汰,但取而代之的 HTML5,却没有提供压缩 API。只能自己用 JS 实现。

    这虽然可行,但运行速度就慢多了,而且相应的 JS 也很大。

    如果代码有 50kb,而数据压缩后只小 10kb,那就不值了。除非量大,才有意义。

    III. 移除:影响原数组

    使用 array.pop()array.shift() 移除数组元素时,会影响原来的数组。

    JavaScript

    let mutatingRemove = ['a', 'b', 'c', 'd', 'e']; mutatingRemove.pop(); // ['a', 'b', 'c', 'd'] mutatingRemove.shift(); // ['b', 'c', 'd']

    1
    2
    3
    let mutatingRemove = ['a', 'b', 'c', 'd', 'e'];  
    mutatingRemove.pop(); // ['a', 'b', 'c', 'd']  
    mutatingRemove.shift(); // ['b', 'c', 'd']

    array.pop()array.shift() 返回被移除的元素,你可以通过一个变量获取被移除的元素。

    JavaScript

    let mutatingRemove = ['a', 'b', 'c', 'd', 'e']; const returnedValue1 = mutatingRemove.pop(); console.log(mutatingRemove); // ['a', 'b', 'c', 'd'] console.log(returnedValue1); // 'e' const returnedValue2 = mutatingRemove.shift(); console.log(mutatingRemove); // ['b', 'c', 'd'] console.log(returnedValue2); // 'a'

    1
    2
    3
    4
    5
    6
    7
    let mutatingRemove = ['a', 'b', 'c', 'd', 'e'];
    const returnedValue1 = mutatingRemove.pop();  
    console.log(mutatingRemove); // ['a', 'b', 'c', 'd']  
    console.log(returnedValue1); // 'e'
    const returnedValue2 = mutatingRemove.shift();  
    console.log(mutatingRemove); // ['b', 'c', 'd']  
    console.log(returnedValue2); // 'a'

    array.splice() 也可以删除数组的元素。

    JavaScript

    let mutatingRemove = ['a', 'b', 'c', 'd', 'e']; mutatingRemove.splice(0, 2); // ['c', 'd', 'e']

    1
    2
    let mutatingRemove = ['a', 'b', 'c', 'd', 'e'];  
    mutatingRemove.splice(0, 2); // ['c', 'd', 'e']

    array.pop()array.shift() 一样,array.splice() 同样返回移除的元素。

    JavaScript

    let mutatingRemove = ['a', 'b', 'c', 'd', 'e']; let returnedItems = mutatingRemove.splice(0, 2); console.log(mutatingRemove); // ['c', 'd', 'e'] console.log(returnedItems) // ['a', 'b']

    1
    2
    3
    4
    let mutatingRemove = ['a', 'b', 'c', 'd', 'e'];  
    let returnedItems = mutatingRemove.splice(0, 2);  
    console.log(mutatingRemove); // ['c', 'd', 'e']  
    console.log(returnedItems) // ['a', 'b']

    本文由奥门新浦京网址发布于Wed前段,转载请注明出处:eval解析JSON字符串的一个小问题,实现数据压缩

    关键词:

上一篇:没有了

下一篇:没有了