Home  >  Article  >  Web Front-end  >  JSON.stringify() usage introduction

JSON.stringify() usage introduction

巴扎黑
巴扎黑Original
2017-08-18 10:55:292380browse

Veteran drivers, do you know that JSON.stringify also has the second and third optional parameters? What are they? Doesn’t it feel incredible? The following article will introduce you to some related information about JSON.stringify that you may not know. The article introduces it in detail through sample code. Friends who need it can refer to it.

Preface

JSON has gradually replaced XML and is widely used by developers around the world. This article explains in depth some of the details of using JSON.stringify in JavaScript. First, a brief review of JSON and JavaScript:

  • Not all legal JSON is valid JavaScript;

  • JSON is just a text format;

  • Numbers in JSON are decimal.

1. JSON.stringify


let foo = { a: 2, b: function() {} };
JSON.stringify(foo);
// "{ "a": 2 }"

The JSON.stringify function will Convert a JavaScript object into textual JSON. Properties that cannot be textualized are ignored. The value of attribute b in foo is the function definition and is not converted and lost.

What other attributes cannot be converted?

1. Circular reference

If the attribute value of an object points back to the object itself in some indirect way, then it is a circular reference. For example:


var bar = {
 a: {
  c: foo
 }
};
var foo = {
 b: bar
};

The attribute c points to itself. If it is parsed layer by layer, it will enter an infinite loop. Let's try to print it out and see:


let fooStringified = JSON.stringify(foo);
console.log(fooStringified); // {"b":{"a":{}}}

The attribute of c points to the foo object, and the b attribute in the foo object points to the bar object and cannot be processed. The whole thing is ignored. Returns an empty object.

The following definition (example in the original text) cannot be compiled:


##

let foo = {b : foo};

Error message:


ReferenceError: foo is not defined
 at repl:1:14

In the functional language Haskell, because of the Lazy Evaluation technology, a similar definition method can be used.

2. Symbol and undefined

##

let foo = { b: undefined };
JSON.stringify(foo);
// {}
// Symbols
foo.b = Symbol();
JSON.stringify(foo);
// {}

Exceptions

in the array , elements that cannot be stringified are filled with null.

let foo = [Symbol(), undefined, function() {}, 'works']
JSON.stringify(foo);
// "[null,null,null,'works']"

This can maintain the "shape" of the array itself, that is, the original index of each element.

Why can’t some attributes be stringified?

Because JSON is a universal text format and has nothing to do with language. Imagine that if the function definition is also stringify, how to determine which language it is and present it in an appropriate way will become particularly complicated. Especially some features related to language, such as Symbol in JavaScript.

ECMASCript officials also specifically emphasized this point:

It does not attempt to impose ECMAScript's internal data representations on other programming languages. Instead, it shares a small subset of ECMAScript's textual representations with all other programming languages.

2. Rewrite the object toJSON function#A way to bypass the inability to stringify certain properties of an object is to implement the object's toJSON Method to customize the object being stringified. Since almost every AJAX call uses JSON.stringify, mastering this technique will be of great help in handling server interactions.

Similar to toString, which allows you to return elements in an object in the form of a string, toJSON provides a method to convert attributes in the object that cannot be stringify, so that the next JSON call is made. stringify can convert it into JSON format.

function Person (first, last) {
 this.firstName = first;
 this.last = last;
}
 
Person.prototype.process = function () {
 return this.firstName + ' ' +
   this.lastName;
};
 
let ade = new Person('Ade', 'P');
JSON.stringify(ade);
// "{"firstName":"Ade","last":"P"}"

The process function of Person instance ade is not stringify. Imagine that if the server only wants the full name of ade, instead of getting the last name and first name respectively, we can directly define toJSON to achieve the goal:

Person.prototype.toJSON = function () {
 return { fullName: this.process(); };
};
 
let ade = new Person('Ade', 'P');
JSON.stringify(ade);
// "{"fullName":"Ade P"}"

The advantage of defining toJSON is reuse For flexibility and stability, you can use ade with any library, and the data transferred will be the fullName returned by your toJSON definition.

// jQuery
$.post('endpoint', ade);
 
// Angular 2
this.httpService.post('endpoint', ade)

3. Optional parameters The complete definition of JSON.stringify is as follows:

JSON.stringify(value, replacer?, space?)

replacer and space are optional parameters, let’s explain them separately next.

Replacer

replacer is a filter function or an array containing the attribute names to be stringified. If not defined, all properties are stringified by default.

1. Array

Only the attributes in the array are stringify:

##
let foo = {
 a : 1,
 b : "string",
 c : false
};
JSON.stringify(foo, ['a', 'b']);
//"{"a":1,"b":"string"}"

Nested attributes are also It will also be filtered:

let bar = {
 a : 1,
 b : { c : 2 }
};
JSON.stringify(bar, ['a', 'b']);
//"{"a":1,"b":{}}"
 
JSON.stringify(bar, ['a', 'b', 'c']);
//"{"a":1,"b":{"c":2}}"

Defining the filter array sometimes does not meet the needs, then you can customize the filter function.

2. Function

The filter function takes each attribute and value in the object as input, and the return value has the following situations:

Returning undefined means ignoring the attribute;
  • Returns a string, Boolean value or number will be stringify;
  • The returned object will trigger a recursive call until a property of the basic type is encountered;
  • 返回无法stringify的值将会被忽略;


let baz = {
 a : 1,
 b : { c : 2 }
};
 
// 返回大于1的值
let replacer = function (key, value) {
 if(typeof === 'number') {
  return value > 1 ? value: undefined;
 }
 return value;
};
 
JSON.stringify(baz, replacer);
// "{"b":{"c":2}}"

通过改写上面的函数加入适当的输出,可以看到具体的执行步骤:


let obj = {
 a : 1,
 b : { c : 2 }
};
 
let tracer = function (key, value){
 console.log('Key: ', key);
 console.log('Value: ', value);
 return value;
};
 
JSON.stringify(obj, tracer);
// Key:
// Value: Object {a: 1, b: Object}
// Key: a
// Value: 1
// Key: b
// Value: Object {c: 2}
// Key: c
// Value: 2

space

你是否意识到调用默认的JSON.stringify返回的值只要一行,而且完全没有空格?如果想要更加美观的打印出来,那么就需要使用space这个参数了。

我告诉你一个非常简单的方法:通过tab(‘\t')来分割即可。


let space = {
 a : 1,
 b : { c : 2 }
};
 
// 使用制表符
JSON.stringify(space, undefined, '\t');
// "{
// "a": 1,
// "b": {
// "c": 2
// }
// }"
 
JSON.stringify(space, undefined, '');
// {"a":1,"b":{"c":2}}
 
// 自定义分隔符
JSON.stringify(space, undefined, 'a');
// "{
// a"a": 1,
// a"b": {
// aa"c": 2
// a}
// }"

一道三颗星的思考题:为什么打印结果的倒数第三行有两个a呢?

结论

本文介绍了一些使用toJSON的技巧:

  • 无法stringify的几种类型

  • 使用toJSON来自定义JSON.stringify的属性

  • 可选参数replacer的两种定义方法来过滤属性

  • 可选参数space用来格式化输出结果

  • 数组和对象中如果包含无法stringify的元素的时候的区别

The above is the detailed content of JSON.stringify() usage introduction. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn