Skip to content

64.深度使用 JSON.stringify() #69

Description

@ccforward

深度使用 JSON.stringify()

按照 JSON 的规范,使用 JSON.stringify() 做对象序列化时,如果一个属性为函数,那这个属性就会被忽略。

const data1 = {
  a: 'aaa',
  fn: function() {
    return true
  }
}
JSON.stringify(data)

// 结果是  "{"a":"aaa"}"

还有一种情况,一个属性的值为 undefined

const data2 = {
  a: 'abc',
  b: undefined
}
JSON.stringify(data2)

// 结果是  "{"a":"abc"}"

如果属性为 null 则可以正常序列化这个属性:

const data3 = {
  a: 'abc',
  b: null
}
JSON.stringify(data3)

// 结果是  "{"a":"abc","b":null}"

因为 null 可表示已经赋值,而 undefined 表示未定义、未赋值,所以执行 JSON.stringify 不会处理。

stringify 函数

stringify 函数的定义为 JSON.stringify(value [, replacer [, space]])

后面还带有我不常用两个可选参数 replacer 和 space

value 参数不多解释,replacer 其实就是一个自定义函数,可以改变 JSON.stringify 的行为,space 就是格式化输出,最大值为 10,非整数时取值为 1

stringify 输出 Function

本质上无论怎么改,stringify 还是不会输出 Function,但是 Function 可以调用 toString() 方法的,所以思路就很明了了。

const data1 = {
  a: 'aaa',
  fn: function() {
    return true
  }
}

const replace = function(k ,v) {
  if(typeof v === 'function') {
    return Function.prototype.toString.call(v)
  }
  return v
}

JSON.stringify(data1, replace)

// 结果  "{"a":"aaa","fn":"function () {\n    return true\n  }"}"

同理可证 undefined 也能输出了

const replace = function(k ,v) {
  if(v === undefined){
    return 'undefined'
  }
  return v
}

stringify 格式化输出

JSON.stringify 的第三个参数很简单,相当于我们编辑器的 tab_size

const data4 = {
  a: 'abc',
  b: null,
  c: {
    x: 'xxx',
    y: 'yyy',
    z: 2046
  },
  d: 9527
}

JSON.stringify(data4, null, 2);

// 输出结果

/*
"{
  "a": "abc",
  "b": null,
  "c": {
    "x": "xxx",
    "y": "yyy",
    "z": 2046
  },
  "d": 9527
}"
*/

toJSON 方法

toJSON 是个覆盖函数,尽量少用,看了代码就懂了:

const data5 = {
  a: 'abc',
  b: null,
  c: {
    x: 'xxx',
    y: 'yyy',
    z: 2046
  },
  d: 9527,
  toJSON: function() {
    return 'WTF'
  }
}

JSON.stringify(data5, null, 2);

// 结果返回  "WTF"

直接覆盖掉所有的序列化处理,返回了 "WTF"

下面的评论中 @yingyuk 给出了详细的 stringify转换demo

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions