当前位置: 首页 > Web前端 > JavaScript

json虽然简单,但这些细节你可能不知道

时间:2023-03-27 15:06:32 JavaScript

基本介绍JSON的全称是JavaScriptObjectNotation。它不是一种编程语言,而是一种可以在服务器和客户端之间传输的数据格式。它最初是JavaScript的子集,但现在独立存在于各种编程语言中。它在传输网络数据时有如下使用场景,比如http请求中参数项目中的一些配置文件,比如package.json文件。非关系数据库(NoSQL)使用json作为存储格式语法。它的文件有一个.json后缀。但是json文件顶层的代码是有严格限制的,只能写下面三种类型,否则代码会被标红~1,简单值数字(Number),字符串(String,单引号是不支持),布尔类型(Boolean),null类型2,对象值由key和value组成,key为字符串类型,必须加双引号,值可以是简单值,对象值,数组值3,arrayvaluesimplevalue,objectvalue,arrayvalueserializationstringifyinhttp请求中经常使用json格式来携带参数,但是我们一般不会在代码中直接使用json,因为不方便操作json数据中的属性。大多数时候,使用对象。把对象转成json格式可以通过stringify方法。stringify方法具有三个参数。参数1(必填),传入一个对象,表示对哪个对象进行stringify操作。参数2(可选),传入一个数组或函数,数组包含对象的键值,表示对象序列化中指定键值的数据,传入函数表示对指定键/值进行操作value参数三(可选),用于改变序列化后的json数据显示格式我们对以下对象进行操作constuser={name:"alice",age:20,friends:["lisa","macus","windy"],信息:{老师:"kiki",},};当只传入一个参数时直接转换当执行基本的序列化操作时conststr1=JSON.stringify(user);控制台日志(str1);操作指定键值conststr2=JSON.stringify(user,["name","friends"]);conststr3=JSON.stringify(user,(key,value)=>{if(key==="age"){returnvalue+1;}returnvalue;});console.log(str2);console.log(str3);传入第二个参数时,传入数组,表示只序列化key值为“name”和“friends”的数据;传入函数,表示操作key值为"age",value+1改变json显示格式conststr4=JSON.stringify(user,null,2);conststr5=JSON.stringify(user,null,"*");console.log(str4);console.log(str5);传入第三个参数,2表示一个换行符和2个空格,表示每行内容前一个换行符和一个加号。toJson方法如果原始对象有toJSON方法,那么stringify方法直接调用toJSON方法。我们在上面的对象中添加toJSON方法,所有stringify方法的执行结果都会发生变化。constuser={name:"alice",age:20,friends:["lisa","macus","windy"],info:{teacher:"kiki",},toJSON(){返回'helloworld'}};conststr1=JSON.stringify(user);conststr2=JSON.stringify(user,["name","friends"]);conststr3=JSON.stringify(user,(key,value)=>{if(key==="age"){返回值+1;}返回值;});conststr4=JSON.stringify(user,null,2);conststr5=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方法可以接收两个参数参数1(必传),json数据,表示将哪些json数据转化为对象参数2(可选),传入一个函数,表示对指定的key/value值进行const操作str='{"name":"alice","age":21,"friends":["lisa","macus","windy"],"info":{"teacher":"kiki"}}';constobj1=JSON.parse(str)constobj2=JSON.parse(str,(key,value)=>{if(key==='age'){returnvalue-1}returnvalue})console.将log(obj1)console.log(obj2)传入函数处理key值为age时的数据。此时,value-1copycopy有以下几种形式。复制的内存地址指向不同的值,直接通过等号赋值,一个对象可以赋值给另一个对象。constuser={name:"alice",info:{hobbies:"tennis",},};constperson=user;user.name="lisa";console.log("user",user);控制台日志(“人”,人);但它们实际上指向同一个对象。如果一个对象的值被操作,另一个对象也会改变。在内存中的表现如下。浅拷贝浅拷贝只遍历一层,如果object的值也有是对象或数组的情况,那么更深一层不会被拷贝,展开运算符或Object.assign可以进行浅拷贝。constuser={name:"alice",info:{hobbies:"tennis",},};constconsumer={...user};user.name="lisa";user.info.hobbies="游泳";console.log("用户",用户);console.log("消费者",消费者);浅拷贝后,user和consumer不是同一个对象,但是他们之间的info还是指向同一个对象,修改info中的其中一个属性,另外一个也会在内存中发生如下变化。深拷贝深拷贝是指复制的对象与原对象无关,任何属性的操作都不会相互影响。深拷贝可以通过stringify和parse方法实现。constuser={name:"alice",info:{hobbies:"tennis",},};consthuman=JSON.parse(JSON.stringify(user));user.name="lisa";user.info.hobbies="游泳";console.log("用户",用户);console.log("人类",人类);此时user和human指向的不是同一个对象,他们里面的info对象不是同一个对象。在内存中的表现如下Stringify和parse实现深拷贝有问题虽然stringify和parse可以实现深拷贝,但是这种方法还是存在一些问题。如果对象中有[method,undefined,Symbol],则直接移除。constuser={name:"alice",height:undefined,[Symbol("age")]:20,info:{hobbies:"tennis",},study(){console.log("我爱读书~");},};constpeople=JSON.parse(JSON.stringify(user));console.log("user",user);console.log("person",people);只留下符合json规范的数据,因为存在这种问题,所以stringify和parse方法一般不用,自己写方法处理深拷贝。至于自定义深拷贝的方法,会在后面的文章中详细介绍。以上是json相关的内容。关于高级js,开发者需要掌握的东西还是很多的。可以看看我写的其他博文,持续更新中~