JSON.stringify()
- JSON.stringify() 方法用于将一个JavaScript对象或值转换为JSON字符串。这个方法可以接受三个参数:
- value:将要被转换成JSON字符串的JavaScript对象、数组或值。
- funcation或arr:如果这个参数是一个函数,那么每个成员都会调用这个函数进行处理;如果是一个数组,那么只有包含在这个数组中的属性名会被包含在最终的JSON字符串中。
- space:用于美化输出的空格数量。
- 示例:
const obj = { name: 'mmm', age: 18, others: ['1', '2'], } console.log(typeof obj) function str(key, value) { if (key === 'age') { return 28 } if (Array.isArray(value)) { return [] } return value } const b = JSON.stringify(obj) const c = JSON.stringify(obj, str, 2) const d = JSON.stringify(obj, ['name'], 4) console.log(b) console.log(c) console.log(d) console.log(typeof b)
- 使用场景
- 场景1:webstoreage存储对象
- 如果通过setItem直接存储对象,那么通过getItem读取的值是’[Object …]’
- 如果先通过JSON.stringify()把对象转成字符串,在存储对象,则读取的值就是字符串化后的对象。可以通过JSON.parse()还原成对象
- 场景2:对象的深拷贝
- 为什么要深拷贝?
- js中的对象都是引用类型,比如,定义一个a={x:1},然后在定义一个b=a,如果在操作b.x =2, 那么a.x的值也会被修改为2。
- 为什么呢?这涉及到栈内存与堆内存
- 栈内存:自动分配内存,系统会自动释放,存放基本类型值和指向堆内存的引用(指针)。
- 堆内存:动态分配内存,存储复杂对象,大小不定,不会自动释放。
- 当我们定义一个a={x:1}时,a实际上是的值是堆内存的对象的存放地址,a的值会被放在栈内存中。那么在操作b=a时,实际上是把对象的存放地址赋值给b了,这个时候a和b的堆内存地址是一样的,也就是a和b都指向了堆内存中的同一个对象,那么在修改b的时候,修改了堆内存的值,那么a也是指向的这个堆。因此a的值也在变化。在实际开发过程中,我们希望修改b,而不改变a。那么就将a先序列化成字符串,这样a的值就是常量字符串,存放在栈中了,在赋值给b的时候,这个时候就是完全复制了,会把栈中b的值改成字符串的值,然后再通过JSON.parse()把字符串解析成对象赋值给b。这个时候堆内存中就有两个一模一样的对象,但地址不一样,也就是a的堆内存引用地址和b的堆内存引用地址不一样了,那么在修改b就不会影响a了。
- 错误的用法:
const a = { x: 1 } const b = a b.x = 2 console.log(b) console.log(a)
- 正确的用法:
const a = { x: 1 } const b = JSON.parse(JSON.stringify(a)) b.x = 2 console.log(b) console.log(a)
JSON.parse()
- JSON.parse() 方法用于将JSON字符串解析成JavaScript对象或值。这个方法可以接受两个参数:
- JSON字符串:将要被解析成JavaScript对象的JSON字符串。
- 函数:如果这个参数是一个函数,它会对解析出的每个值进行处理。函数的使用方法和stringify的函数使用方法一样。