当前位置:网站首页>Almost because of json Stringify lost his bonus
Almost because of json Stringify lost his bonus
2022-06-27 04:20:00 【Program ape DD_】
translate | Yang Xiaoai
english | https://medium.com/frontend-canteen/my-friend-almost-lost-his-year-end-bonus-because-of-json-stringify-9da86961eb9e
This is the true story that happened to my friend , His nickname is fat head . because JSON.stringify The wrong use of , After one of the business modules he was responsible for went online bug, Make a page unusable , And then affect the user experience , He almost lost his year-end bonus .
In this article , I will share this sad story . Then we will discuss JSON.stringify Various functions of , To help you avoid making the same mistakes in the future .
Let's start now
Here's the story .
His company , A colleague left , Then the fat man was asked to accept the job of leaving his colleagues .
little does one think , Soon after he took over this part of the business , There is one in the project bug.
at that time , In the communication group of the company , Many people are discussing this problem .
The product manager first complains : There is one in the project bug, The user cannot submit the form , The customer complained about this . Please repair as soon as possible .
Then the test engineer said : I have tested this page before , Why can't it work after the launch ?
And back-end developers say : The data sent by the front end is missing value Field , This causes an error in the server interface .
Find a colleague to complain about , The problem lies in the module he is responsible for , My friend pangtou really has a headache .
After some inspection , My friend finally found the mistake .
That's what happened .
Find a form on the page that allows users to submit data , The front end should then parse the data from the form and send it to the server .
The form is like this :( Here is my simulation )
These fields are optional .
Usually , The data shall be as follows :
let data = {
signInfo: [
{
"fieldId": 539,
"value": "silver card"
},
{
"fieldId": 540,
"value": "2021-03-01"
},
{
"fieldId": 546,
"value": "10:30"
}
]
}
Then they should be converted to :
But the problem is , These fields are optional . If the user does not fill in some fields , Then the data will become like this :
let data = {
signInfo: [
{
"fieldId": 539,
"value": undefined
},
{
"fieldId": 540,
"value": undefined
},
{
"fieldId": 546,
"value": undefined
}
]
}
They will become like this :
JSON.stringify The value of... Is ignored during conversion undefined Field of .
therefore , After such data is uploaded to the server , Server cannot resolve value Field , And that leads to errors .
Once problems are found , The solution is simple , In order to convert data into JSON Leave after string value Field , We can do that :
let signInfo = [
{
fieldId: 539,
value: undefined
},
{
fieldId: 540,
value: undefined
},
{
fieldId: 546,
value: undefined
},
]
let newSignInfo = signInfo.map((it) => {
const value = typeof it.value === 'undefined' ? '' : it.value
return {
...it,
value
}
})
console.log(JSON.stringify(newSignInfo))
// '[{"fieldId":539,"value":""},{"fieldId":540,"value":""},{"fieldId":546,"value":""}]'
If the value of a field is found to be undefined, We change the value of this field to an empty string .
Although the problem has been solved , however , We also need to think about how this problem came about .
Originally, this is a page that has been online for several days , Why does this problem suddenly appear ? Check carefully , It turns out that the product manager proposed a small optimization point before , then , Fat head made a little change to the code . But fat head is right JSON.stringify Is not familiar with , meanwhile , He thinks the changes are small , So there was not enough testing , Finally, the project appears bug.
Fortunately, he found the problem , The problem was soon solved . This bug Few users are affected , So the boss didn't blame him , My friend didn't lose his bonus , Otherwise , If the impact is great , It is estimated that the bonus is really gone , Even let him leave directly .
next , Let's see JSON.stringify, Why is it so “ severe ”, I almost lost my friend's bonus .
Get to know JSON.stringify
Actually , This bug Mainly because fat head is right JSON.stringify Unfamiliarity causes , therefore , Here we will analyze some features of this built-in function .
Basically ,JSON.stringify() Methods will JavaScript Object or value to JSON character string :
meanwhile ,JSON.stringify Here are the rules .
1、 If the target object has toJSON() Method , It is responsible for defining which data will be serialized .
2、 Boolean、Number、String Object is converted to the corresponding original value in the process of stringing , Conform to traditional transformation semantics .
3、 undefined、Functions and Symbols It's not effective JSON value . If any of these values are encountered during the conversion , Then they are either ignored ( Found in object ), Or be changed to null( When found in the array ).
4、 all Symbol-keyed Properties will be completely ignored
5、 Date By returning a string toJSON() function ( And date.toISOString() identical ). therefore , They are treated as strings .
6、 Numbers Infinity and NaN as well as null Values are considered to be null.
7、 All the others Object example ( Include Map、Set、WeakMap and WeakSet) Only its enumerable properties will be serialized .
8、 Thrown when a circular reference is found TypeError(“ Loop object value ”) abnormal .
9、 Try to be on BigInt Thrown when a value is stringed TypeError(“BigInt Value cannot be in JSON Serialization in ”).
Realize it by yourself JSON.stringify
The best way to understand a function is to implement it yourself . Now I write a simulation JSON.stringify A simple function of .
const jsonstringify = (data) => {
// Check if an object has a circular reference
const isCyclic = (obj) => {
// Use a Set to store the detected objects
let stackSet = new Set()
let detected = false
const detect = (obj) => {
// If it is not an object, we can skip it directly
if (obj && typeof obj != 'object') {
return
}
// When the object to be checked already exists in the stackSet,
// it means that there is a circular reference
if (stackSet.has(obj)) {
return detected = true
}
// save current obj to stackSet
stackSet.add(obj)
for (let key in obj) {
// check all property of `obj`
if (obj.hasOwnProperty(key)) {
detect(obj[key])
}
}
// After the detection of the same level is completed,
// the current object should be deleted to prevent misjudgment
/*
For example: different properties of an object may point to the same reference,
which will be considered a circular reference if not deleted
let tempObj = {
name: 'bytefish'
}
let obj4 = {
obj1: tempObj,
obj2: tempObj
}
*/
stackSet.delete(obj)
}
detect(obj)
return detected
}
// Throws a TypeError ("cyclic object value") exception when a circular reference is found.
if (isCyclic(data)) {
throw new TypeError('Converting circular structure to JSON')
}
// Throws a TypeError when trying to stringify a BigInt value.
if (typeof data === 'bigint') {
throw new TypeError('Do not know how to serialize a BigInt')
}
const type = typeof data
const commonKeys1 = ['undefined', 'function', 'symbol']
const getType = (s) => {
return Object.prototype.toString.call(s).replace(/\[object (.*?)\]/, '$1').toLowerCase()
}
if (type !== 'object' || data === null) {
let result = data
// The numbers Infinity and NaN, as well as the value null, are all considered null.
if ([NaN, Infinity, null].includes(data)) {
result = 'null'
// undefined, arbitrary functions, and symbol values are converted individually and return undefined
} else if (commonKeys1.includes(type)) {
return undefined
} else if (type === 'string') {
result = '"' + data + '"'
}
return String(result)
} else if (type === 'object') {
// If the target object has a toJSON() method, it's responsible to define what data will be serialized.
// The instances of Date implement the toJSON() function by returning a string (the same as date.toISOString()). Thus, they are treated as strings.
if (typeof data.toJSON === 'function') {
return jsonstringify(data.toJSON())
} else if (Array.isArray(data)) {
let result = data.map((it) => {
// 3# undefined, Functions, and Symbols are not valid JSON values. If any such values are encountered during conversion they are either omitted (when found in an object) or changed to null (when found in an array).
return commonKeys1.includes(typeof it) ? 'null' : jsonstringify(it)
})
return `[${result}]`.replace(/'/g, '"')
} else {
// 2# Boolean, Number, and String objects are converted to the corresponding primitive values during stringification, in accord with the traditional conversion semantics.
if (['boolean', 'number'].includes(getType(data))) {
return String(data)
} else if (getType(data) === 'string') {
return '"' + data + '"'
} else {
let result = []
// 7# All the other Object instances (including Map, Set, WeakMap, and WeakSet) will have only their enumerable properties serialized.
Object.keys(data).forEach((key) => {
// 4# All Symbol-keyed properties will be completely ignored
if (typeof key !== 'symbol') {
const value = data[key]
// 3# undefined, Functions, and Symbols are not valid JSON values. If any such values are encountered during conversion they are either omitted (when found in an object) or changed to null (when found in an array).
if (!commonKeys1.includes(typeof value)) {
result.push(`"${key}":${jsonstringify(value)}`)
}
}
})
return `{${result}}`.replace(/'/, '"')
}
}
}
}
At the end
From a bug Start , We talked about JSON.stringify And implemented it myself .
Today I share this story with you , I hope you will encounter this problem in the future , Know how to deal with , Don't make the same mistake .
If you find it useful , Please praise me , Pay attention to me , Last , Thanks for reading , Happy programming !
We have created a high-quality technical exchange group , With good people , I will be excellent myself , hurriedly Click Add group , Enjoy growing up together . in addition , If you want to change jobs recently , Years ago, I spent 2 A wave of large factory classics were collected in a week , Those who are ready to change jobs after the festival can Click here to get !
Recommended reading
blockbuster !Spring Cloud Add a new kit to the ecology :Spring Cloud Tencent
Read... For the first time “Clean” series , I don't think this is a good book
Stealing super 1 Data of 100 million people ! Former Amazon employees face 20 Year imprisonment
··································
Hello , I'm a procedural ape DD,10 Old driver developed in 、 Alibaba cloud MVP、 Tencent cloud TVP、 I have published books and started a business 、 State-owned enterprises 4 In the Internet 6 year . From ordinary developers to architects 、 Then to the partner . Come all the way , My deepest feeling is that I must keep learning and pay attention to the frontier . As long as you can hold on , Think more 、 Don't complain 、 Do it frequently , It's easy to overtake on a curve ! therefore , Don't ask me what I'm doing now, whether it's in time . If you are optimistic about one thing , It must be persistence to see hope , Instead of sticking to it when you see hope . believe me , Just stick to it , You must be better than now ! If you don't have any direction , You can pay attention to me first , Some cutting-edge information is often shared here , Help you accumulate the capital to overtake on the curve .
边栏推荐
- 【B站UP DR_CAN学习笔记】Kalman滤波1
- 日志收集系統
- Nignx configuring single IP current limiting
- Fplan power planning
- Cultural tourism light show breaks the time and space constraints and shows the charm of night tour in the scenic spot
- Advanced Mathematics (Seventh Edition) Tongji University exercises 1-10 personal solutions
- Agile development - self use
- 015 C语言基础:C结构体、共用体
- Description of replacement with STM32 or gd32
- Mysql database foundation: DQL data query language
猜你喜欢
Fplan power planning
Baidu PaddlePaddle's "universal gravitation" first stop in 2022 landed in Suzhou, comprehensively launching the SME empowerment plan
fplan-Powerplan实例
MySQL development environment
[promise I] introduction of promise and key issues of hand rolling
2021:Beyond Question-Based Biases:Assessing Multimodal Shortcut Learning in Visual Question Answeri
Facing the "industry, University and research" gap in AI talent training, how can shengteng AI enrich the black land of industrial talents?
MobileNet系列(4):MobileNetv3网络详解
ERP需求和销售管理 金蝶
[array]bm94 rainwater connection problem - difficult
随机推荐
MATLAB | 基于分块图布局的三纵坐标图绘制
Games101 job 7 improvement - implementation process of micro surface material
[BJDCTF2020]The mystery of ip
Fplan power planning
DAST 黑盒漏洞扫描器 第六篇:运营篇(终)
实践 DevOps 时,可能面临的六大挑战
019 C语言基础:C预处理
010 C语言基础:C函数
Basic functions of promise [IV. promise source code]
[数组]BM94 接雨水问题-较难
[array]bm94 rainwater connection problem - difficult
halcon常用仿射变换算子
LDR6028 手机设备一边充电一边OTG传输数据方案
Building lightweight target detection based on mobilenet-yolov4
022 C语言基础:C内存管理与C命令行参数
733. image rendering
014 C语言基础:C字符串
How to make ef core 6 support dateonly type
Network structure and model principle of convolutional neural network (CNN)
2021:Beyond Question-Based Biases:Assessing Multimodal Shortcut Learning in Visual Question Answeri