【无标题】,卧槽

JSON.stringify 作为日常开发中经常使用的方法,你真的能灵活运用它吗?

学习本文之前,小包想让大家带着几个问题,一起来深入学习 stringify 。

  • stringify 函数有几个参数,每个参数分别有啥用啊?

  • stringify 序列化准则有哪些啊?

  • 函数序列化中会如何处理?

  • null、undefined、NaN 等特殊的值又会如何处理?

  • ES6 后增加的 Symbol 类型、BigInt 序列化过程中会有特别处理吗?

  • stringify 为什么不适合做深拷贝?

  • 你能想到那些 stringify 的妙用?

整个文章的脉络跟下面思维导图一致,大家可以先留一下印象。

三参数


在日常编程中,我们经常 JSON.stringify 方法将某个对象转换成 JSON 字符串形式。

const stu = {

name: ‘zcxiaobao’,

age: 18

}

// {“name”:“zcxiaobao”,“age”:18}

console.log(JSON.stringify(stu));

但 stringify 真的就这么简单吗?我们先来看一下 MDN 中对 stringify 的定义。

MDN 中指出: JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串,如果指定了一个 replacer 函数,则可以选择性地替换值,或者指定的 replacer 是数组,则可选择性地仅包含数组指定的属性。

看完定义,小包就一惊,stringfy 不止一个参数吗?当然了,stringify 有三个参数。

咱们来看一下 stringify 语法和参数介绍:

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

  • value: 将要序列后成 JSON 字符串的值。

  • replacer(可选)

  1. 如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;

  2. 如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中

  3. 如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。

  • space(可选): 指定缩进用的空白字符串,用于美化输出
  1. 如果参数是个数字,它代表有多少的空格。上限为10。

  2. 该值若小于1,则意味着没有空格

  3. 如果该参数为字符串(当字符串长度超过10个字母,取其前10个字母),该字符串将被作为空格

  4. 如果该参数没有提供(或者为 null),将没有空格

replacer

我们来尝试一下 replacer 的使用。

  1. replacer 作为函数

replacer 作为函数,它有两个参数,键(key) 和 值(value),并且两个参数都会被序列化。

在开始时,replacer 函数会被传入一个空字符串作为 key 值,代表着要被 stringify 的这个对象。理解这点很重要,replacer 函数并非是上来就把对象解析成键值对形式,而是先传入了待序列化对象。随后每个对象或数组上的属性会被依次传入。 如果函数返回值为undefined或者函数时,该属性值会被过滤掉,其余按照返回规则。

// repalcer 接受两个参数 key value

// key value 分别为对象的每个键值对

// 因此我们可以根据键或者值的类型进行简单筛选

function replacer(key, value) {

if (typeof value === “string”) {

return undefined;

}

return value;

}

// function 可自己测试

function replacerFunc(key, value) {

if (typeof value === “string”) {

return () => {};

}

return value;

}

const foo = {foundation: “Mozilla”, model: “box”, week: 45, transport: “car”, month: 7};

const jsonString = JSON.stringify(foo, replacer);

JSON 序列化结果为 {"week":45,"month":7}

但如果序列化的是数组,若 replacer 函数返回 undefined 或者函数,当前值不会被忽略,而将会被 null 取代。

const list = [1, ‘22’, 3]

const jsonString = JSON.stringify(list, replacer)

JSON 序列化的结果为 ‘[1,null,3]’

  1. replacer 作为数组

作为数组比较好理解,过滤数组中出现的键值。

const foo = {foundation: “Mozilla”, model: “box”, week: 45, transport: “car”, month: 7};

const jsonString = JSON.stringify(foo, [‘week’, ‘month’]);

JSON 序列化结果为 {"week":45,"month":7}, 只保留 week 和 month 属性值。

前端面试题库小程序  wx   搜索  【MST题宝库】


九特性


特性一: undefined、函数、Symbol值

  1. 出现在非数组对象属性值中: undefined、任意函数、Symbol 值在序列化过程中将会被忽略

  2. 出现在数组中: undefined、任意函数、Symbol值会被转化为 null

  3. 单独转换时: 会返回 undefined

// 1. 对象属性值中存在这三种值会被忽略

const obj = {

name: ‘zc’,

age: 18,

// 函数会被忽略

sayHello() {

console.log(‘hello world’)

},

// undefined会被忽略

wife: undefined,

// Symbol值会被忽略

id: Symbol(111),

// [Symbol(‘zc’)]: ‘zc’,

}

// 输出结果: {“name”:“zc”,“age”:18}

console.log(JSON.stringify(obj));

// 2. 数组中这三种值会被转化为 null

const list = [

‘zc’,

18,

// 函数转化为 null

function sayHello() {

console.log(‘hello world’)

},

// undefined 转换为 null

undefined,

// Symbol 转换为 null

Symbol(111)

]

// [“zc”,18,null,null,null]

console.log(JSON.stringify(list))

// 3. 这三种值单独转化将会返回 undefined

console.log(JSON.stringify(undefined)) // undefined

console.log(JSON.stringify(Symbol(111))) // undefined

console.log(JSON.stringify(function sayHello() {

console.log(‘hello world’)

})) // undefined

特性二: toJSON() 方法

转换值如果有 toJSON() 方法,toJSON() 方法返回什么值,序列化结果就返回什么值,其余值会被忽略。

const obj = {

name: ‘zc’,

toJSON(){

return ‘return toJSON’

}

}

// return toJSON

console.log(JSON.stringify(obj));

特性三: 布尔值、数字、字符串的包装对象

布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值

JSON.stringify([new Number(1), new String(“zcxiaobao”), new Boolean(true)]);

// [1,“zcxiaobao”,true]

特性四: NaN Infinity null

特性四主要针对 JavaScript 里面的特殊值,例如 Number 类型里的 NaN 和 Infinity 及 null 。此三种数值序列化过程中都会被当做 null 。

// [null,null,null,null,null]

JSON.stringify([null, NaN, -NaN, Infinity, -Infinity])

// 特性三讲过布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值

// 隐式类型转换就会调用包装类,因此会先调用 Number => NaN

// 之后再转化为 null

// 0/0 => Infinity => null

JSON.stringify([Number(‘123a’), +‘123a’, 0/0])

特性五: Date对象

Date 对象上部署了 toJSON 方法(同 Date.toISOString())将其转换为字符串,因此 JSON.stringify() 将会序列化 Date 的值为时间格式字符串。

// “2022-03-06T08:24:56.138Z”

JSON.stringify(new Date())

特性六: Symbol

特性一提到,Symbol 类型当作值来使用时,对象、数组、单独使用分别会被忽略、转换为 null 、转化为 undefined

同样的,所有以 Symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。

const obj = {

name: ‘zcxiaobao’,

age: 18,

}

function replacer(key, value) {

if (typeof key === ‘symbol’) {

return value;

}

}

// undefined

JSON.stringify(obj, replacer);

通过上面案例,我们可以看出,虽然我们通过 replacer 强行指定了返回 Symbol 类型值,但最终还是会被忽略掉。

特性七: BigInt

JSON.stringify 规定: 尝试去转换 BigInt 类型的值会抛出 TypeError

const bigNumber = BigInt(1)

// Uncaught TypeError: Do not know how to serialize a BigInt

console.log(JSON.stringify(bigNumber))

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
img

性能优化

1.webpack打包文件体积过大?(最终打包为一个js文件)

2.如何优化webpack构建的性能

3.移动端的性能优化

4.Vue的SPA 如何优化加载速度

5.移动端300ms延迟

6.页面的重构

所有的知识点都有详细的解答,我整理成了280页PDF《前端校招面试真题精编解析》。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】


A 如何优化加载速度

5.移动端300ms延迟

6.页面的重构

所有的知识点都有详细的解答,我整理成了280页PDF《前端校招面试真题精编解析》。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 30
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值