• 安全基础 --- JSON + 函数声明


    JSON

    格式:JSON(JavaScript Object Notation缩写)是一种用于数据交换的文本格式,目的是取代繁琐笨重的 XML 格式。

    (1)规定

    1. 复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。

    2. 原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和null(不能使用NaN, Infinity, -Infinityundefined)。

    3. 字符串必须使用双引号表示,不能使用单引号。

    4. 对象的键名必须放在双引号里面。

    5. 数组或对象最后一个成员的后面,不能加逗号。

    (2)实例:

    • 合法JSON
    1. ["one", "two", "three"]
    2. { "one": 1, "two": 2, "three": 3 }
    3. {"names": ["张三", "李四"]
    4. [ { "name": "张三"}, {"name": "李四"} ]
    • 不合法JSON
    1. { name: "张三", 'age': 32 } // 属性名必须使用双引号
    2. [32, 64, 128, 0xFFF] // 不能使用十六进制值
    3. { "name": "张三", "age": undefined } // 不能使用 undefined
    4. { "name": "张三",
    5. "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
    6. "getName": function () {
    7. return this.name;
    8. }
    9. } // 属性值不能使用函数和日期对象

    (3)JSON对象

    JSON对象是 JavaScript 的原生对象,用来处理 JSON 格式数据。它有两个静态方法:JSON.stringify()JSON.parse()

    <1> JSON.stringify()
    [1] 基本用法

    JSON.stringfy()方法将一个值转为JSON字符串,该字符串符合JSON格式,且可被JSON.parse()还原

    例:

    1. JSON.stringify('abc') // ""abc""
    2. JSON.stringify(1) // "1"
    3. JSON.stringify(false) // false
    4. JSON.stringify([]) // "[]"
    5. JSON.stringify({}) // "{}"
    6. JSON.stringify([1,"false",false])
    7. // '[1,"false",false]'
    8. JSON.stringfy({name:"张三"})
    9. // '{name:张三}'
    10. 上方将各种类型的值,转为JSON字符串,对于原始类型,转换结果会带双引号
    11. JSON.stringify('foo') === "foo" // false
    12. JSON.stringify('foo') === "\"foo\"" // true
    13. // 上面代码中,如果不是内层的双引号,将来还原的时候,引擎就无法知道原始值是布尔值还是字符串。

    JSON.stringify()方法会忽略对象的不可遍历的属性

    1. var obj = {};
    2. Object.defineProperties(obj,{
    3. 'foo':{
    4. value:1,
    5. enumerable:true
    6. },
    7. 'bar':{
    8. value:2,
    9. enumerable:false
    10. }
    11. });
    12. JSON.stringify(obj); // "{"foo":1}"
    13. // bar是obj对象的不可遍历属性,JSON.stringify方法将会忽略这个属性
    [2] 第二个参数

    JSON.stringify()方法还可以接受一个数组,作为第二个参数,指定参数对象的哪些属性需要转为字符串

    1. var obj = {
    2. 'prop1':'value1',
    3. 'prop2':'value2',
    4. 'prop3':'value3'
    5. };
    6. var selectedProperties = ['prop1','prop2'];
    7. JSON.stringify(obj,selectedProperties)
    8. // "{"prop1":"value1","prop2":"value2"}"
    9. // JSON.stringify()方法的第二个参数指定,只转prop1和prop2的两个属性

    类似白名单的数组,只对对象的属性有效,对数组无效。

    1. JSON.stringfy(['a','b'],[0]);
    2. // "["a","b"]"
    3. JSON.stringify({0:'a',1:'b'},['0']);
    4. // "{"0":"a"}"

    第二个参数还可以是函数,用来更改JSON.stringify()的返回值

    1. function f(key,value) {
    2. if(typeof value === "number") {
    3. value = 2 * value;
    4. }
    5. return value;
    6. }
    7. JSON.stringify({a:1,b:2},f);
    8. // '{"a":2,"b":4}'
    9. // f函数,接受两个参数,分别是被转换的对象的键名和键值。键值为数值的话,将乘2,否则原样返回,

    注意:这个处理函数是递归处理所有的键

    1. var obj = {a:{b:1}}
    2. function f(key.value) {
    3. console.log("[" + key + "]:" + value);
    4. return value;
    5. }
    6. JSON.stringify(obj.f);
    7. //[]:[object object]
    8. //[a]:[object object]
    9. //[b]:1
    10. //'{"a":{"b":1}}'
    11. // 对象 obj 一共会被函数 f 处理三次,输出的最后那行是JSON.stringify()的默认输出,第一次键名为空,键值是整个对象的obj;第二次键名为a,键值是{b:1};第三次键名为b,键值为1

    递归处理中,每一次处理的对象,都是前一次返回的值

    1. var obj = {a:1};
    2. function f(key,value) {
    3. if (typeof value === 'object') {
    4. return {b:2};
    5. }
    6. return value * 2;
    7. }
    8. JSON.stringify(obj,f);
    9. // "{"b":4}"
    10. // 上面代码中,f函数修改了对象obj,接着JSON.stringify()方法就递归处理修改后的对象obj

    如果处理函数返回undefined或没有返回值,则该属性会被忽略

    1. function f(key,value) {
    2. if (typeof(value) === "string") {
    3. return undefined;
    4. }
    5. return value;
    6. }
    7. JSON.stringify({a:"abc",b:123},f)
    8. // '{"b":123}'
    9. // a属性被处理后,返回undefined,于是该属性被忽略
    [3] 第三个参数

    JSON.stringify()还可以接受第三个参数,用于增加返回的JSON字符串的可读性

    默认返回单行字符串,对于大型JSON对象,可读性差。第三个参数使得每个属性单独占据一行,并将每个属性前面添加指定的前缀(前缀不超过10个字符)

    1. // 默认输出
    2. JSON.stringify({p1:1,p2:2})
    3. // JSON.stringify({p1:1,p2:2})
    4. // 分行输出
    5. JSON.stringify({p1:1,p2:2},null,'\t')
    6. /*
    7. {
    8. "p1":1,
    9. "p2":2
    10. )
    11. */
    12. // 第三个属性\t在每个属性前面添加一个制表符(从当前位置移动到下一个tab位置),然后分行显示

    第三个属性如果是数字,则表示在每个属性前面添加的空格(不超过10个)

    1. JSON.stringify({ p1: 1, p2: 2 }, null, 2);
    2. /*
    3. "{
    4. "p1": 1,
    5. "p2": 2
    6. }"
    7. */
    <2> JSON.parse()

    JSON.parse()方法用于将 JSON 字符串转换成对应的值。

    例1:

    1. JSON.parse('{}'); // {}
    2. JSON.parse('true'); // true
    3. JSON.parse('"foo"'); // "foo"
    4. JSON.parse('[1,5,"false"]'); // [1,5,"false"]
    5. JSON.parse('null'); // null
    6. var o = JSON.parse('{"name":"张三"}');
    7. o.name // 张三

    例2:传入字符串不是有效的JSON格式,将报错

    1. JSON.parse("'String'");
    2. // 报错
    3. // 双引号字符串中是一个单引号字符串,因为单引号字符串不符合JSON格式,所以报错

    try...catch代码块,解析错误

    1. try {
    2. JSON.parse("'String'");
    3. }catch(e) {
    4. console.log('parsing error');
    5. }

    JSON.parse()方法接受一个处理函数,作为第二个参数,用法与JSON.stringify()方法类似

    1. function f(key,value) {
    2. if (key === 'a') {
    3. return value + 10;
    4. }
    5. return value;
    6. }
    7. JSON.parse('{"a":1,"b":2}',f);
    8. // {a:11,b:2}
    9. // JSON.parse()的第二个参数是一个函数,如果键名是a,该函数会将键值加上10

    函数声明

    js中有三种声明函数的方法

    (1)function命令

    function命令声明的代码区块,就是一个函数。function命令后面是函数名,函数名后面是一对圆括号,里面是传入函数的参数。函数体放在大括号里面

    1. function print(s) {
    2. console.log(s);
    3. }
    4. // 代码中命名了一个print函数,使用print()这种形式,就可以调用相应的代码,这叫做函数的声明

    (2)函数表达式

    funciton命令声明函数,还可采用变量赋值的写法

    1. var print = function(s) {
    2. console.log(s);
    3. }
    4. // 将一个匿名函数赋值给变量,匿名函数又被称为函数表达式,赋值语句右侧只能放表达式

    采用函数表达式声明函数时,function命令后面不带有函数名。加上函数名,则函数名只在函数体内部有效,在函数体外部无效

    1. var print = funciton x() {
    2. coonsole.log(typeof x);
    3. };
    4. print();
    5. // funciton
    6. // 上面代码在函数表达式中,加入了函数x。x只在函数体内部可用,指代函数表达式本身,其他地方都不可用
    7. // 两种用法:
    8. //(1)函数体内部调用自身
    9. //(2)方便除错(除错工具显示函数调用栈时,显示函数名,而不再显示这里是一个匿名函数)

    var funciton  f()  {};

    函数表达式末尾加分号,表示语句结束;而函数声明在结尾的大括号后面不用加分号。

    (3)Function构造函数

    1. var add = new Function(
    2. 'x',
    3. 'y',
    4. 'return x + y'
    5. );
    6. // 等同于
    7. function add(x,y) {
    8. return x + y;
    9. }
    10. // Function构造函数接受三个参数,除了最后一个参数是add函数的“函数体”,其他参数都是add函数的参数

    可传递任意数量参数给Function构造函数,仅最后一个参数会被当做函数体;若仅一个参数,该参数就是函数体

    1. var foo = new Function(
    2. 'return "hello world";'
    3. );
    4. // 等同于
    5. function foo() {
    6. return "hello world";
    7. }
    8. // function构造函数可不使用new命令,返回结果相同。(声明函数的方式不直观,无人使用)
  • 相关阅读:
    纳米二氧化硅/分解酶/聚己内酯复合微球/银纳米颗粒修饰二氧化硅微球SERS基底的应用
    输出有价值的性能报告
    【web-代码审计】(14.5)PHP
    组合计数训练题解
    操作系统简介(下)
    电力电子技术——单相可控整流电路——单相半波可控整流电路
    java分布式锁
    第五章:Python中的集合(上)
    电影主题HTM5网页设计作业成品——爱影评在线电影(10页面)使用dreamweaver制作采用DIV+CSS进行布局
    如何在 PHP 中使用常量
  • 原文地址:https://blog.csdn.net/weixin_62443409/article/details/132717858