你真的理解JSON.stringify吗?

528 阅读3分钟

这是我参与更文挑战的第26天,活动详情查看: 更文挑战

前言

JSON.stringify,我们应该是比较了解的,当我们需要把对象转成字符串的时候,比如:

var obj = {
 name: '答案cp3',
 age: 18
}
console.log(JSON.stringify(obj)) // '{"name":"答案cp3","age":18}'

但是我今天发现JSON.stringify接受的参数可不止一个,我顿时惊呆了,小丑竟然是我自己。

image.png

诚如我这种在职场摸爬滚打几年的老油条,感觉像发现了新世界,今天要好好总结一下,争取下次惊艳所有人。

JSON.stringify

上面发的例子是JSON.stringify最基础的用法,但是远远不止于此。它还可以对你传入的对象做筛选转化,还可以对你传入的对象做格式化,缩进。

语法

JSON.stringify(value[, replacer [, space]])

参数:

value

必需,需要转成JSON字符串的值,一般是对象或者数组。如果含有toJSON方法,则直接返回toJSON方法返回的值。

如果传入的是对象,如果key的值是undefined函数以及symbol,则这些key会被过滤掉,不会输出。

replacer

选填,用于对传入的值做转化筛选,一般是数组或者函数。如果不传该参数,则不做任何转化筛选。

如果是数组,则对传入的值仅筛选数组里面的值,不在数组的值则被过滤掉。

如果是函数,则对传入的值,调用该函数,依次传入对应的keyvalue。第一次key为空字符串, value是传入的值,后面才是依次传入对应的keyvalue。然后根据传入的keyvalue,做对应的操作,然后把值return

如果函数返回值是是undefined或者函数,则会过滤对应的key这个针对对象有效,如果是数组, 则会用null代替。

space

对转成的文本添加缩进。如果是数字,代表加的空格数,最大是到10。如果是字符串,代表缩进使用的就是这些字符串。

例子

现在通过一些例子来说明。

  1. 过滤属性

    var obj = {
     name: '答案cp3',
     age: 18
    }
    console.log(JSON.stringify(obj, ['name'])) // '{"name":"答案cp3"}'
    

    第二个参数,传入数组['name'],输出的字符串只包含name属性

  2. 替换对象的值

    var obj = {
     name: '答案cp3',
     age: 18
    }
    console.log(JSON.stringify(obj, (key, val) => {
      if(key === 'age') return 17
      else return val
    })) // '{"name":"答案cp3", age: 17}'
    

    第二个参数,传入函数,然后对key做判断, 如果key等于 age,则返回17

  3. 格式化(美化)对象

    var obj = {name: '答案cp3',age: 18}
    console.log(JSON.stringify(obj, null, 4)) 
    // 输出如下
    /*
    {
        "name": "答案cp3",
        "age": 18
    }
    */
    

    第三个参数,传入4,代表key与左边间距是4个空格,适合美化对象

  4. 可能是最简单的深拷贝

     var obj = {
      name: '答案cp3',
      age: 18,
      info: {
        test: 'test'
      },
      test: undefined,
      test1: function () {},
      test2: Symbol()
     }
     var deepObj = JSON.parse(JSON.stringify(obj))
     deepObj.name = 'cp3'
     deepObj.info.test = 'cp3'
     console.log(obj)
     console.log(deepObj) 
     
     /*
     obj:{
      name: '答案cp3',
      age: 18,
      info: {
        test: 'test'
      },
      test: undefined,
      test1: function () {},
      test2: Symbol()
     }
      deepObj:{
      name: 'cp3',
      age: 18,
      info: {
        test: 'cp3'
      }
     }
     */
    

    可以看到深拷贝是有效的,但是上面也说过,如果key的值是undefined函数以及symbol,则这些key会被过滤掉,不会输出。

  5. 如果对象有toJSON法,则直接调用该方法返回,如果是返回基本类型,则直接输出,如果是引用类型,则继续调用JSON.stringify输出字符串。

    var obj = {
      name: '答案cp3',
      age: 18,
      toJSON () {
        return '答案cp3'
      }
     }
     console.log(JSON.stringify(obj)) // 答案cp3
     
     var obj = {
      name: '答案cp3',
      age: 18,
      toJSON () {
        return {name: '答案cp3'}
      }
     }
     console.log(JSON.stringify(obj)) // '{"name":"答案cp3"}'
    

最后

今天才发现JSON.stringify功能这么强大, 之前一直使用的是把对象转字符串这个基本的方法。今天好好总结了下,希望下次可以在项目中用上,加油,继续努力学习~

image.png