JSON(回顾)

JSON是什么

JSON,全称是 JavaScript Object Notation,即 JavaScript对象标记法。
JSON 是一种语法,用来序列化对象、数组、数值、字符串、布尔值和 null,基于JS,但是JSON并不是JS的子集
JSON字符串:一种传输数据的格式,本质是字符串
注意:JSON字符串属性名称必须是双引号括起来的字符串;最后一个属性后不能有逗号

JSON的方法

  • JSON.stringify()
  • JSON.parse()

JSON.stringify(value,replacer,space)

定义:将一个JS对象或值转换为JSON字符串,返回JSON字符串
参数1:要被转换的对象或值
参数2:数组或函数,对序列化的每个属性进行处理,可选
参数3:指定缩进用的字符串,用于美化输出,数字代表多少个空格(1-10),字符串代表该字符串作为缩进,可选,默认没有空格

JSON.stringify([undefined,function test() {},Symbol(""),{ a: 1 },]);
//'[null,null,null,{"a":1}]'
replacer参数

定义:数组或函数格式,对序列化的每个属性进行处理,可选
数组格式 包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中

JSON.stringify({ a: 1, b: 2 }, ["a"]);//'{"a":1}'
函数格式

每个属性都会经过该函数的转换和处理,会按照最顶层属性开始往里,最终达到里层
注意:当遍历到顶层时,传入的形参1会是空字符串 ‘’,形参2是被修改完成的对象,所以得返回该对象

var res = JSON.stringify({ a: 1, b: 2 }, function (prop, v) {
  if (prop === "") {
    return v;
  }
  console.log(prop, v);
  return v + 1;
});
console.log(res); //'{"a":2,"b":3}'
space参数

定义:用来控制结果字符串里面的间距,数字代表多少个空格(1-10),字符串代表该字符串作为缩进,可选,默认没有空格
常用 \t 换行符

// 使用'\t'制表符
JSON.stringify({ a: 1, b: 2 }, null, "\t");
{
	"a": 1,
	"b": 2
}

存在的几个特征

  1. Boolean | Number | String 类型自动会转换为对应原始值
// Boolean对象
let temp =JSON.stringify(new Boolean(1))
console.log(typeof temp) // string
console.log(typeof JSON.parse(temp)) // boolean
// Number对象
let temp =JSON.stringify(new Number(1))
console.log(typeof temp)// string
console.log(typeof JSON.parse(temp))// number
// String对象
let temp =JSON.stringify(new String(1))
console.log(typeof temp)// string
console.log(typeof JSON.parse(temp))// string
  1. undefined、任意函数、symbol,这三种类型在非数组对象中会被忽略, 在数组中转换成null,在单个值时转换为 undefined

数组对象中 :>> undefined、任意函数、symbol,这三种类型转换为 “null”

// 数组中
let test = () => {};
let arr = [new String(1),test,Symbol("1"),undefined,null];
let temp = JSON.stringify(arr)
console.log(temp);// '["1",null,null,null,null]'
console.log(JSON.parse(temp));// [1,null,null,null,null]

非数组对象中 :>> undefined、任意函数、symbol,这三种类型会被忽略

// 非数组对象中 
let obj = {
  a: new Number(1),
  b: ()=>{},
  c: Symbol(1),
  d:undefined,
  e:null
}
let temp =JSON.stringify(obj)
console.log(temp);// '{"a":1,"e":null}'
console.log(JSON.parse(temp));// { a: 1, e: null }

单个值时:>> undefined、任意函数、symbol,这三种类型转换为 undefined

// 单个值时,当前因为parse需要json格式对象,这样是没意义的
let temp =JSON.stringify(Symbol(1))
console.log(temp)// 'undefined'
let temp1 =JSON.stringify(()=>1)
console.log(temp1) // 'undefined'
  1. 不可枚举属性会被忽略,数组中不会被忽略
let obj = {
  a: new Number(1),
}
Object.defineProperty(obj, "b", {
  value: '1',
  configurable: false, // 可配置性,默认为false
  enumerable: false, // 可枚举性,默认为false
  writable: false, // 可重写性,默认为false
});
let temp =JSON.stringify(obj)
console.log(temp)// '{ a: 1 }'
console.log(JSON.parse(temp))// { a: 1 }
  1. 如果对象属性通过 get 方式返回对象本身,即循环引用,该属性会被忽略
let obj = {
  a: new Number(1),
  b:'1'
}
Object.defineProperty(obj, "b", {
  get(v){
    return v
  }
});
let temp =JSON.stringify(obj)
console.log(temp)// '{ a: 1 }'
console.log(JSON.parse(temp))// { a: 1 }

封装stringify

class L {
	stringify(tar) {// JSON.stringify
    // 1.Boolean | Number | String 类型自动会转换为对应原始值
    // 2.undefined、任意函数、symbol,这三种类型在非数组对象中会被忽略,在数组中转换成null,在单个值时转换为 undefined
    // 3.不可枚举属性会被忽略,数组中不会被忽略
    // 4.如果对象属性通过 get 方式返回对象本身,即循环引用,该属性会被忽略
    var type = typeof tar;
    if (type !== "object") {
      if (/undefined|function|symbol/.test(type)) {
        return String(undefined);
      }
      return String(tar);
    } else if (tar === null) {
      return "null";
    } else if (tar.constructor === Array) {// 数组
      let json = [];
      for (var i = 0; i < tar.length; i++) {
        var v = tar[i];
        var type1 = typeof v;
        if (/undefined|function|symbol/.test(type1) || v === null) {
          v = "null";
        } else if (/string/.test(type1) || v instanceof String) {
          v = '"' + v + '"';
          console.log(v);
        } else {
          v = this.stringify(v);
        }
        json.push(String(v));
      }
      return "[" + json.join() + "]";
    } else {// 非数组对象
      var json = [];
      if (tar instanceof Number || tar instanceof Boolean || tar instanceof String) {
        return String(tar);
      }
      for (var k in tar) {
        var v = tar[k];
        var type2 = typeof v;
        if (/undefined|function|symbol/.test(type2)) {
          continue;
        } else if (v === null) {
          v = "null";
        } else if (/string/.test(type2) || tar instanceof String) {
          v = '"' + v + '"';
        } else {
          v = this.stringify(v);
        }
        json.push('"' + k + '":' + String(v));
      }
      return "{" + json.join() + "}";
    }
  }
}

JSON.parse(text, reviver)

定义:用来解析JSON字符串,返回油字符串描述的对象或值
参数1:被解析的JSON字符串
参数2:转换器,用来修改生成的对象,可选

var res = JSON.parse('{"a":1,"b":2}', function (prop, v) {
  if (prop === "") {
    console.log(v,'顶层')
    return v;
  }
  console.log(prop);
  console.log(this);
  return v +1;
});
/*
a
{ a: 1, b: 2 }
b
{ a: 2, b: 2 }
{ a: 2, b: 3 } 顶层
*/
console.log(res);// {a: 2, b: 3}
reviver参数

定义:用来修改生成的对象,会按照最里层属性开始往外,最终达到顶层
形参1:当前对象属性名
形参2:当前对象属性值
注意:当遍历到顶层时,传入的形参1会是空字符串 ‘’,形参2是被修改完成的对象,所以得返回该对象

JSON.parse('{"p": 5}', function (k, v) {
  if(k === '') return v;     // 如果到了最顶层,则直接返回属性值,这个是最后指向的
  return v * 2;              // 否则将属性值变为原来的 2 倍
});                          // { p: 10 }
JSON的异常

开发过程中,常常遇到这个错误,这是JSON数据格式不对,得找JSON.parse的参数,找寻具体错误
在这里插入图片描述

封装 parse

参考 梁少峰:JSON实现的三种方式

方式1:使用 eval,存在xss危险(跨站脚本攻击)

class L {
  parse(tar) {//存在xss漏洞(跨站脚本攻击)
    return eval("(" + tar + ")");
  }
}

方式2:使用Function

class L {
  parse2(tar){//使用Function
    return (new Function('return' + tar))()
  }
}

方式3:递归,请参考上文

这里推荐下 查看正则的工具

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳晓黑胡椒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值