简体   繁体   English

序列化嵌套的javascript对象,同时删除某些属性

[英]Serializing nested javascript objects while removing certain properties

We have a javascript object that contains (a) ordinary properties (strings, arrays of other objects, dates), (b) methods, (c) properties that are jQuery objects. 我们有一个javascript对象,其中包含(a)普通属性(字符串,其他对象的数组,日期),(b)方法和(c)是jQuery对象的属性。

We need to serialize the parent object and all nested objects to a JSON string to send to the server. 我们需要将父对象和所有嵌套对象序列化为JSON字符串以发送到服务器。 As part of this process we want to remove properties that the server doesn't need, and any jQuery objects (which won't serialize due to circular references). 作为此过程的一部分,我们希望删除服务器不需要的属性以及所有jQuery对象(由于循环引用而不会序列化)。

We've tried using the "remover" argument of JSON.stringify but it seems to be ignoring nested objects. 我们尝试使用JSON.stringify的“ remover”参数,但它似乎忽略了嵌套对象。 We have lodash available. 我们有lodash可用。 What methodology should we be looking at for this? 我们应该寻找什么方法?

var Form = function ($elem, config) {
    this.$elem = $elem;
    this.config = config;
    this.init();
};
$.extend(Form.prototype, {
    constructor: Form,
    config: null,
    $elem: null,
    categoryid: null,
    $sectionModal: null,
    sections: [],
    $sectionList: null,
    addSection: function (data) {
        . . .
    },
    validate: function () {
        . . .
    },
    serialize: function () {
        console.log(JSON.stringify(this, function (key, value) {
            if (value instanceof jQuery) {
                return undefined;
            }
            return value;
        }));
    },
    init: function () {
        this.sections.push(new Section(1, "Section one"));
        this.sections.push(new Section(2, "Section two"));
    }
});

You can employ a convention for transient properties, such as a property name starting with $ . 您可以对瞬态属性采用约定,例如以$开头的属性名称。

var o = {
  a: "a",
  b: 1,
  c: [2, 3],
  d: {
    a: 1,
    $e: "not this one"
  },
  f: function(y) {},
  $e: "not this one"
};

var serialize = function(x) {
  return JSON.stringify(x, function(k, v) {
    if (!k.startsWith("$"))
      return v;
  });
};

console.log(serialize(o));
// {"a":"a","b":1,"c":[2,3],"d":{"a":1}}

We have got to the bottom of our original problem, although it raises other questions. 尽管它提出了其他问题,但我们已深入到原始问题的底部。 Regard the following code (also at https://jsfiddle.net/osy4cook/1/ ). 考虑以下代码(也位于https://jsfiddle.net/osy4cook/1/ )。 It seems that properties are only included in the serialization if their values are initialized in the object constructor OR set via methods on the object, but NOT if the properties are initialized by adding them to the prototype. 似乎只有在对象构造函数中对属性值进行了初始化或通过对象上的方法进行设置的情况下,属性才包含在序列化中,而如果通过将属性添加到原型中来初始化属性,则不包括在内。 I'm sure there's a simple explanation for this - does anyone know what it is? 我敢肯定有一个简单的解释-有人知道这是什么吗?

EDIT : we had two reasons for defining properties on the prototype. 编辑 :我们有两个原因定义原型上的属性。 First, so all methods/properties for the "class" were defined in the same place, for clarity. 首先,为清楚起见,“类”的所有方法/属性都在同一位置定义。 Second, to provide defaults. 第二,提供默认值。 What we overlooked is that properties of the constructor function are specific to each object created with it, while properties of the prototype are shared by ALL objects. 我们忽略的是,构造函数的属性特定于使用它创建的每个对象,而原型的属性由所有对象共享。 Evidently serializing an object just ignores properties on the prototype. 显然,序列化对象只会忽略原型上的属性。 (source: Why defining properties in the prototype is considered an antipattern ) (来源: 为什么在原型中定义属性被视为反模式

var Section = function(id, title) {
    this.id = id;
    this.title = title;
}
var Form = function () {
    this.sections = [];
    this.myvar1 = 123;
    this.init();
};
$.extend(Form.prototype, {
    constructor: Form,
    myvar1: null,
    myvar2: null,
    myvar3: 999,    
    $sectionModal: $("<div></div>"),
    sections: [],
    myarray: [],
    addSection: function (data) {
        //. . .
    },
    serialize: function () {
        console.log(JSON.stringify(this, function (key, value) {
            if (value instanceof jQuery) {
                return undefined;
            }
            return value;
        }));
    },
    init: function () {
        this.myvar2 = 999;
        this.sections.push(new Section(1, "Section one"));
        this.myarray.push(new Section(2, "Section two"));
        this.serialize();
    }
});
var form = new Form();

Result... 结果...

{"sections":[{"id":1,"title":"Section one"}],"myvar1":123,"myvar2":999}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM