检查对象是否可在JavaScript中序列化的可靠方法

tre*_*nik 6 javascript serialization json

是否有已知的方法或库已经有一个帮助器来评估对象是否可以在JavaScript中序列化?

我尝试了以下但它没有涵盖原型属性,因此它提供误报:

_.isEqual(obj, JSON.parse(JSON.stringify(obj))
Run Code Online (Sandbox Code Playgroud)

还有另一个lodash功能可能让我更接近事实_.isPlainObject.但是,_.isPlainObject(new MyClass())返回false_.isPlainObject({x: new MyClass()})返回true,因此需要递归应用.

在我自己冒险之前,有没有人知道一种已经可靠的方法来检查是否JSON.parse(JSON.stringify(obj))真的会导致同一个对象obj

bar*_*sny 5

function isSerializable(obj) {
  var isNestedSerializable;
  function isPlain(val) {
    return (typeof val === 'undefined' || typeof val === 'string' || typeof val === 'boolean' || typeof val === 'number' || Array.isArray(val) || _.isPlainObject(val));
  }
  if (!isPlain(obj)) {
    return false;
  }
  for (var property in obj) {
    if (obj.hasOwnProperty(property)) {
      if (!isPlain(obj[property])) {
        return false;
      }
      if (typeof obj[property] == "object") {
        isNestedSerializable = isSerializable(obj[property]);
        if (!isNestedSerializable) {
          return false;
        }
      }
    }
  }
  return true;
}
Run Code Online (Sandbox Code Playgroud)

递归迭代所有给定的对象属性。它们可以是:

  • 普通对象(“由 Object 构造函数创建的对象或 [[Prototype]] 为 null 的对象。 ” - 来自 lodash 文档)
  • 数组
  • 字符串数字布尔值
  • 不明确的

pass 内任何其他值都obj将导致其被理解为“不可序列化”。

(说实话,我并不绝对肯定我没有省略对某些可序列化/不可序列化数据类型的检查,实际上我认为这取决于“可序列化”的定义 - 欢迎任何评论和建议。)


tre*_*nik 5

最后,我创建了自己的方法,利用 Underscore/Lodash 的_.isPlainObject. 我的函数最终与 @bardzusny 提出的类似,但我也发布了我的函数,因为我更喜欢简单/清晰。请随意概述优点/缺点。

var _ = require('lodash');

exports.isSerializable = function(obj) {
  if (_.isUndefined(obj) ||
      _.isNull(obj) ||
      _.isBoolean(obj) ||
      _.isNumber(obj) ||
      _.isString(obj)) {
    return true;
  }

  if (!_.isPlainObject(obj) &&
      !_.isArray(obj)) {
    return false;
  }

  for (var key in obj) {
    if (!exports.isSerializable(obj[key])) {
      return false;
    }
  }

  return true;
};
Run Code Online (Sandbox Code Playgroud)