根本介绍
JSON的全称是JavaScript Object Notation,它并不是编程语言,而是一种能够在服务器和客户端之间传输的数据格式,原本是JavaScript的子集,但当初已独立存在于各种编程语言中。
它有以下应用场景
- 网络数据传递时,比方http申请中参数
- 我的项目里某些配置文件,比方package.json文件
- 非关系型数据库(NoSQL)将json作为存储格局
语法
它的文件以 .json 为后缀名,但json文件顶层的代码有严格限度,只能写以下三种,不然代码会间接标红~
1、简略值
数字(Number)、字符串(String,不反对单引号)、布尔类型(Boolean)、null类型
2、对象值
由key、value组成,key是字符串类型,必须增加双引号,值能够是简略值、对象值、数组值
3、数组值
简略值、对象值、数组值
序列化 stringify
在http申请中携带参数常常用到json格局,但咱们个别不会在代码中间接应用json,因为json数据中操作属性并不不便,大多数时候是应用对象,将对象转成json格局就能够通过 stringify 办法。
stringify办法有三个参数
- 参数一(必传),传入一个对象,示意对于哪个对象进行stringify操作
- 参数二(可选),传入数组或者函数,数组里包含对象的key值,示意对于对象中的指定key值的数据进行序列化,传入函数示意对指定的key/value值进行操作
- 参数三(可选),用于扭转序列化之后的json数据展示格局
咱们对以下对象进行操作
const user = { name: "alice", age: 20, friends: ["lisa", "macus", "windy"], info: { teacher: "kiki", },};
间接转换
当只传入一个参数时,进行根本的序列化操作
const str1 = JSON.stringify(user);console.log(str1);
操作指定的key值
const str2 = JSON.stringify(user, ["name", "friends"]);const str3 = JSON.stringify(user, (key, value) => { if (key === "age") { return value + 1; } return value;});console.log(str2);console.log(str3);
当传入第二个参数时,传入数组,示意只对 key值为“name”,“friends”的数据进行序列化;传入函数,示意操作 key 值为“age”的时候,value+1
扭转json展示格局
const str4 = JSON.stringify(user, null, 2);const str5 = JSON.stringify(user, null, "*");console.log(str4);console.log(str5);
传入第三个参数,2示意换行空2格, 示意换行及每行内容前加 号
toJson办法
如果原对象中有toJSON办法,那么stringify办法间接调用toJSON办法。咱们给下面的对象加上toJSON办法,所有的stringify办法的执行后果都会变动。
const user = { name: "alice", age: 20, friends: ["lisa", "macus", "windy"], info: { teacher: "kiki", }, toJSON(){ return 'hello world' }};const str1 = JSON.stringify(user);const str2 = JSON.stringify(user, ["name", "friends"]);const str3 = JSON.stringify(user, (key, value) => { if (key === "age") { return value + 1; } return value;});const str4 = JSON.stringify(user, null, 2);const str5 = JSON.stringify(user, null, "*");console.log(str1);console.log(str2);console.log(str3);console.log(str4);console.log(str5);
stringify办法的执行后果都变成了 toJSON 办法的返回值
解析 parse
接口申请返回的参数中个别是json数据,咱们要应用首先得通过parse办法将它转成对象。
parse办法能够接管两个参数
- 参数一(必传),json数据,示意将哪一个json数据转成对象
- 参数二(可选),传入函数,示意对指定的key/value值进行操作
const str = '{"name":"alice","age":21,"friends":["lisa","macus","windy"],"info":{"teacher":"kiki"}}'; const obj1 = JSON.parse(str)const obj2 = JSON.parse(str, (key, value)=>{ if(key === 'age'){ return value - 1 } return value})console.log(obj1)console.log(obj2)
传入函数,解决 key值为age时的数据,此时操作 value - 1
拷贝
拷贝有以下几种模式,拷贝进去的内存地址指向不一样
间接赋值
通过等于符号能够将一个对象赋值给另一个对象。
const user = { name: "alice", info: { hobbies: "tennis", },};const person = user;user.name = "lisa";console.log("user", user);console.log("person", person);
但它们其实指向的是同一个对象,如果操作其中一个对象的值,另外一个对象也会发生变化
在内存中体现如下
浅拷贝
浅拷贝只会遍历一层,如果对象中还有value值为对象或者数组的状况,那么更深一层不会被拷贝,开展运算符或者Object.assign能够进行浅拷贝。
const user = { name: "alice", info: { hobbies: "tennis", },};const consumer = { ...user };user.name = "lisa";user.info.hobbies = "swimming";console.log("user", user);console.log("consumer", consumer);
浅拷贝后,user和consumer曾经不是同一个对象了,但他们俩当中的info依然指向同一个对象,批改其中一个info中的属性,另一个也会变动
在内存中体现如下
深拷贝
深拷贝示意拷贝进去的对象与原对象齐全无关,操作任意属性都不会相互影响,通过 stringify 和 parse 办法能够实现深拷贝。
const user = { name: "alice", info: { hobbies: "tennis", },};const human = JSON.parse(JSON.stringify(user));user.name = "lisa";user.info.hobbies = "swimming";console.log("user", user);console.log("human", human);
此时user和human不是指向同一个对象,他们中的info对象也不是同一个对象
在内存中体现如下
stringify和parse实现深拷贝存在问题
尽管stringify和parse能够实现深拷贝,然而这种形式仍存在一些问题,如果对象中存在【办法、undefined、Symbol】,会间接被移除
const user = { name: "alice", height: undefined, [Symbol("age")]: 20, info: { hobbies: "tennis", }, study() { console.log("I love reading~"); },};const people = JSON.parse(JSON.stringify(user));console.log("user", user);console.log("person", people);
只剩下合乎json标准的数据
因为存在这种问题,所以个别不会用stringify和parse办法,能够本人编写解决深拷贝的办法,至于自定义深拷贝办法,留在前面的文章中具体介绍。
以上就是json相干内容,对于js高级,还有很多须要开发者把握的中央,能够看看我写的其余博文,继续更新中~