好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

JavaScript JSON

JavaScript JSON

JSON 对象包含两个 方法 : 用于解析 JavaScript Object Notation (JSON) 的 parse() 方法 ,以及将对象/值转换为 JSON字符串的 stringify() 方法 。除了这两个 方法 , JSON 这个对象本身并没有其他作用,也不能被 调用 或者作为构造 函数 调用 。

JavaScript 内置的 JSON对象 用于处理 JSON 。

JSON(JavaScript Object Notation)是一种带有格式的文本,JavaScript 中的 JSON对象 用于处理这种文本。

JSON 对象只提供了两个 方法 , 一个 用于序列化 JSON , 一个 用于反序列化 JSON 。

这里的序列化可以理解成 将JavaScirpt对象转换成JSON ,反序列化则是 将JSON转换成JavaScript对象 。

1. JSON.parse

JSON.parse 用于解析 JSON 格式的字符串,将 JSON 转化成 JavaScript 对象。

 JSON .  parse  ( JSON字符串 ,  处理 函数  )  ; 
 

第 一个 参数是要转换成对象的 JSON 字符串,第二个参数可以不传递/

  var  str  =   '{ "name": "baba", "age": 12, "info": { "locate": "浙江" } }'  ; 

 var  user  =  JSON .  parse  ( str )  ; 

console .  log  ( user )  ;   //  输出  一个  JavaScript 对象 
 

传递给 JSON.parse 方法 的字符串要符合 JSON 标准,否则会报错。

第二个参数非常有趣,传入的是 一个 函数 ,这个 函数 会在每个 JSON 属性 被解析的时候 调用 ,同时会传递 属性 名和 属性 值给 函数 作为参数,传入参数的返回值会作为当前遍历到的 属性 的新值。

  var  str  =   '{ "name": "baba", "age": 12, "info": { "locate": "浙江" } }'  ; 

 var  user  =  JSON .  parse  ( str ,   function  ( key ,  value )   { 
  console .  log  ( key ,  value )  ; 

   return  value ; 
 }  )  ; 
 

可以发现上述例子打印的最后以想, 属性 名是可以空字符串, 属性 值是解析完的结果。

修改 一下例子,将返回值改成 一个 固定的值。

  var  str  =   '{ "name": "baba", "age": 12, "info": { "locate": "浙江" } }'  ; 

 var  user  =  JSON .  parse  ( str ,   function  ( key ,  value )   { 
  console .  log  ( key ,  value )  ; 

   return   '强行 修改 值'  ; 
 }  )  ; 
 

观察 输出 后,可以发现所有 属性 都被遍历了,并且赋值成功,但是最终 user 也变成了返回的字符串。

这是因为当解析完成后,传入的 函数 会被最后 调用 一次,传递进来的值就是最终 JSON.parse 的返回值,所以对其 修改 后,会影响到的最终结果。

  var  str  =   '{ "name": "baba", "age": 12, "info": { "locate": "浙江" } }'  ; 

 var  user  =  JSON .  parse  ( str ,   function  ( key ,  value )   { 
  console .  log  ( key ,  value )  ; 

   if   ( key  ===   ''  )   { 
     return  value ; 
   } 

   return   '强行 修改 值'  ; 
 }  )  ; 
 

对传递过来的 属性 名为空字符串 '' 进行单独处理即可避免这种特殊情况。

业务逻辑中很少会用第二个参数来处理解析 内容 。

2. JSON.stringify

JSON.stringify 用于将JavaScript对象转换成 JSON 格式的字符串。

 JSON .  stringify  ( JavaScript对象 ,  处理 函数  ,  缩进空格字符 数量  )  ; 
 

第 一个 参数是需要转换成 JSON 字符串的对象。

第二个参数可以是个 函数 ,也可以是个数组。
如果是 函数 ,则每 一个 属性 在处理的时候就被 调用 这个 函数 ,同时 属性 名和 属性 值作为参数传递给这个 函数 ,并且 函数 的返回值作为这个处理 属性 的值。
如果是数组,则只有 属性 名在数组中的 属性 才会被处理,不传递则 默 认处理整个对象。
如果第二个参数传递 null ,也就是不做特殊处理,在使用到第三个参数的时候,第二个参数会传递 null 。

第三个参数可以传递数字,也可以传递字符串,传递了这个参数会对结果做格式化,具有一定的格式,参数的值决定格式化的样式。
如果是数字,则使用对应长度的空格来缩进,长度 1 到 10 ,比 1 小则表示不缩进。
如果是字符串,则会使用传入的字符串进行缩进,传入的字符串长度超过 10 ,则会 截取 前 10 个作为缩进字符。

  var  user  =   { 
  name :   '小明'  , 
  age :   , 
  skill :   [  'HTML'  ,   'Java'  ]  , 
 }  ; 

 var  json  =  JSON .  stringify  ( user )  ; 

console .  log  ( json )  ; 
 //  输出 :{"name":"小明","age":14,"skill":["HTML","Java"]} 
 

第二个参数用起来和 parse 方法 的第二个参数类似。

  var  user  =   { 
  name :   '小明'  , 
  age :   , 
  skill :   [  'HTML'  ,   'Java'  ]  , 
 }  ; 

 var  json  =  JSON .  stringify  ( user ,   function  ( key ,  value )   { 
  console .  log  ( key ,  vlue )  ; 

   return  value ; 
 }  )  ; 

console .  log  ( json )  ; 
 

根据上述例子可以看到,先 输出 的 属性 为空字符串, 属性 值为被处理对象,所以如果不想操作原对象,需 要做 特殊处理。

  var  user  =   { 
  name :   '小明'  , 
  age :   , 
  skill :   [  'HTML'  ,   'Java'  ]  , 
 }  ; 

 var  json  =  JSON .  stringify  ( user ,   function  ( key ,  value )   { 
   if   ( key  ===   ''  )   { 
     return  value ; 
   } 

   return   '我是处理过的值'  ; 
 }  )  ; 

console .  log  ( json )  ; 
 

这样处理后,最终处理完的 JSON 字符串的 属性 值都是 函数 的返回值了。

第三个参数会在做一些工具类调试的时候常用到。

  var  obj  =   [ 
   { 
    path :   '/'  , 
    component :   'function() {}'  , 
    children :   [ 
       { 
        path :   'note'  , 
        component :   'function() {}'  , 
       }  , 
       { 
        path :   'friends'  , 
        component :   'function() {}'  , 
       } 
     ] 
   }  , 
   { 
    path :   '*'  , 
    component :   'function() {}'  , 
   } 
 ]  ; 

 var  json1  =  JSON .  stringify  ( obj ,   null  )  ; 
 var  json2  =  JSON .  stringify  ( obj ,   null  ,   )  ; 
 var  json3  =  JSON .  stringify  ( obj ,   null  ,   '*-*'  )  ; 

console .  log  ( json1 )  ;   // 没有格式 
console .  log  ( json2 )  ;   // 使用两个空格控制的缩进 
console .  log  ( json3 )  ;   // 使用 *-* 控制的缩进 
 

传入参数后就会将处理后的 JSON 字符串进行格式化,缩进部分根据传入的参数值决定。

3. 其他注意点

3.1 深拷贝

可以配合 JSON 的两个 方法 ,对对象进行深拷贝。

  var  obj  =   { prop :   'value'  }  ; 

 var  newObj  =  JSON .  parse  ( JSON .  stringify  ( obj )  )  ; 

newObj . prop  =   'new value'  ; 

console .  log  ( obj )  ; 
console .  log  ( newObj )  ; 
 

根据结果可以看到新的对象 修改 ,没有影响到原对象,两者之间不存在引用关系。

3.2 序列化规则

使用 JSON.stringify 有些内置规则。

如果对象中存在包装对象,则在转换过程中会变成原始值。

  var  obj  =   { 
  string :   new   String  (  'A promise is a promise.'  )  , 
  number :   new   Number  (  )  , 
 }  ; 

 var  result  =  JSON .  stringify  ( obj )  ; 

console .  log  ( result )  ;   //  输出 :"{"string":"A promise is a promise.","number":996}" 
 

如果转换的对象或者对象下的 属性 存在 toJSON 方法 ,那么这个 方法 的返回值会作为转换结果。

  var  user  =   { 
  nickname :   'joker'  , 

  toJSON :   function  (  )   { 
     return   'hahahahahahaha'  ; 
   }  , 
 } 

 var  result  =  JSON .  stringify  ( user )  ; 

console .  log  ( result )  ;   //  输出 :"hahahahahahaha" 
 

可以看到结果为 toJSON 方法 的返回值。

除了数组以外的对象,转换结果顺序为 随机 。

  var  obj  =   { 
  b :   , 
  c :   , 
  a :   , 
 }  ; 
 

如以上对象,转换的结果有可能是以下情况中的一种:

  "{" a ":1," b ":2," c ":3}" 
 "{" a ":1," c ":3," b ":2}" 
 "{" b ":2," a ":1," c ":3}" 
 "{" b ":2," c ":3," a ":1}" 
 "{" c ":3," b ":2," a ":1}" 
 "{" c ":3," a ":1," b ":2}" 
 

undefined、ES6 中的 symbol 值、 函数 在转换过程中都会被忽略,当然 函数 如果具有 toJSON 方法 依然会优先选择 toJSON 方法 的结果。

  var   fn   =   function  (  )   {  }  ; 
fn .  toJSON   =   function  (  )   {  return   '我是 函数 '  }  ; 

 var  result  =  JSON .  stringify  (  { 
	a :  fn , 
	b :   Symbol  (  )  , 
	c :  undefined , 
  d :   function  (  )   {  }  , 
 }  )  ; 

console .  log  ( result )  ; 
 

存在循环引用,则会报错

  var  obj1  =   { 
  prop1 :   , 
 }  ; 
 var  obj2  =   { 
  prop1 :   , 
 }  ; 

obj1 . prop2  =  obj2 ; 
obj2 . prop2  =  obj1 ; 

JSON .  stringify  ( obj1 )  ;   // TypeError: Converting cir cula r structure to JSON 
 

两个对象相互引用之后,进行系列化就会抛出 错误 。

在 ES6 中,symbol 可以作为对象的 属性 值,但在处理的时候都会被忽略。

  var  symbol  =   Symbol  (  )  ; 

 var  obj  =   { 
  prop1 :   'value1'  , 
   [ symbol ]  :   'value2'  , 
 }  ; 

console .  log  ( obj )  ; 

 var  result  =  JSON .  stringify  ( obj )  ; 

console .  log  ( result )  ;   //  输出 :{"prop1":"value1"} 
 

null、正负 Infinity、NaN 在序列化时都会被当作 null 。

  var  obj  =   { 
   null  :   null  , 
  infinity1 :   +  , 
  infinity2 :   -  , 
   :   , 
 }  ; 

 var  result  =  JSON .  stringify  ( obj )  ; 

console .  log  ( result )  ;   //  输出 :{"null":null,"infinity1":null,"infinity2":null,"NaN":null} 
 

4. 小结

JSON 几乎是目前前后端交互最常用的数据格式,所以 JSON 对象使用的频率也很高。

在使用 JSON.parse 反序列化的时候,如果 JSON 格式不符合规范,是会报错的,日常开发中建议封装一层 JSON 的 方法 ,将 错误 集中处理,方便定位与上报 错误 。

什么是 DOM ? ?JavaScript RegExp

查看更多关于JavaScript JSON的详细内容...

  阅读:37次

上一篇

下一篇

第1节:什么是 JavaScript    第2节:学习环境准备    第3节:调试方案    第4节:JavaScript 变量    第5节:JavaScript 数据类型    第6节:JavaScript if 语句    第7节:for 语句    第8节:JavaScript 算数运算符    第9节:JavaScript 比较运算符    第10节:JavaScript 逻辑运算符    第11节:JavaScript 函数    第12节:JavaScript 表达式    第13节:JavaScript 对象    第14节:JavaScript 字符串    第15节:JavaScript 数字    第16节:JavaScript 数组    第17节:JavaScript switch 语句    第18节:JavaScript while 语句    第19节:JavaScript 的 break 与 continue    第20节:JavaScript with    第21节:document.cookie    第22节:JavaScript Function    第23节:JavaScript Math    第24节:JavaScript Date    第25节:JavaScript RegExp    第26节:JavaScript JSON    第27节:什么是 DOM    第28节:DOM 和 JavaScript 的关系    第29节:获取和操作 DOM 节点    第30节:DOM 与事件    第31节:DOM 事件绑定    第32节:DOM 事件对象    第33节:DOM 事件流    第34节:事件相关的优化    第35节:自定义事件    第36节:表单校验    第37节:什么是 BOM    第38节:常用的 BOM 相关对象    第39节:BOM 常用属性和方法    第40节:AJAX    第41节:异常处理    第42节:三元运算符    第43节:逗号操作符    第44节:void    第45节:typeof    第46节:delete 操作符    第47节:debugger    第48节:getter & setter    第49节:new 运算符与构造函数    第50节:JavaScript 原型    第51节:JavaScript instanceof    第52节:JavaScript this    第53节:严格模式    第54节:作用域    第55节:闭包    第56节:变量提升    第57节:对象包装器    第58节:Lodash    第59节:moment    第60节:swiper    第61节:ECMAScript 6    第62节:Node.js    第63节:Babel    第64节:CSS 预处理器    第65节:代码规范    第66节:TypeScript    第67节:WebComponents    第68节:Vue、React、Angular    第69节:小程序    第70节:JavaScript 关键字    第71节:分号导致的问题    第72节:对象属性访问问题    第73节:this 使用问题    第74节:浮点数精度问题    第75节:独一无二的 NaN    第76节:避免全局污染    第77节:控制台观察对象问题    第78节:根据环境选择语言特性    第79节:相关资源