从 JSON 重构 JS objects
Reconstructing JS objects from JSON
不要这样做
这个问题有一些评论对重建 object 的概念持低估态度。评论者无法或不愿解释 为什么 他们认为这是个坏主意,但自从问起我就得出了同样的结论。原因如下。
如果您考虑 MVVM,拥有模型和 view-model 的目的是将行为与数据分开。这有点有趣,因为 object-orientation 的目的是将它们结合起来。但在分布式世界中,数据必须四处传输。如果您的代码和数据都混在一起,那么您必须发明 MVVM 或保留 de- and re-constructing objects.
de-和re-constructobjects的代码是你不需要的测试和维护time-sink,并引入了两种故障模式。不要这样做。有一个 method-less class 来保存状态和一个无状态的 class 在 method-less class 上运行。这是 MVVM 的本质,实际上无非是 Memento 模式的应用。
Memento (283)
Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.
Design Patterns, Gamma et al, 1995
原问题
我的视图模型的数据作为 JSON 在客户端 JS 和服务器 Web API 之间来回传递。
众所周知,JSON.stringify(object)
仅序列化 non-null 值不是 Function
的成员。因此,JSON.parse(JSON.stringify(someObject))
将从 object.
中删除所有方法
我当前的实现是将每个图节点实现为带有序列化和反序列化方法的 Typescript class。 JQuery.ajax 调用 Web API 并将结果 JSON 隐式解析为 object 定义的 DAG,每个定义都有一个类型 属性 指示哪种类型的 class 这是在连载之前。我有一个按名称索引的构造函数映射,检索适当的构造函数并将数据作为构造函数参数传递。
根据类型可能有 children;如果是这样,事情将递归地向下进行。
我一直在想,除了复制所有 属性 值,我是否不能只分配一个合适的原型。把山带给穆罕默德,你可能会说。这将消除我的代码库中的相当多的混乱。
在我写的时候我突然想到我可以使用 $.extend,但是我正在逐步清除我的代码库的 jQuery out 所以这将是一个逆行.
- 我欺骗原型的提议是否存在任何已知的危险?
- 有没有人有更好的主意?除了 $.extend,我是说。优先使用 TypeScripty。
在评论中观察到,分配原型意味着永远不会调用构造函数。这无关紧要。 object 状态已经设置,所需要的只是使方法可用。
我最近构建了 object 使用可以序列化然后重建内容的方法。
我只是添加了一个参数,它可以接受一个 JSON object 并将其分配给自己。
使用普通 object 的示例:
function myObject() {
this.valueA = 1;
this.valueB = 2;
this.valueC = 3;
this.add = function() {
return this.valueA + this.valueB + this.valueC;
};
}
var o = new myObject();
console.log(o.add());
console.log(JSON.stringify(o));
如果你序列化这个你会得到:
{"valueA":1,"valueB":2,"valueC":3}
现在,要重构它,您可以将 Object.assign()
添加到 object 中,就像这样接受参数并将其与 self:
合并
function myObject(json) {
this.valueA = 0;
this.valueB = 0;
this.valueC = 0;
this.add = function() {
return this.value1 + this.value2 + this.value3;
};
Object.assign(this, json); // will merge argument with itself
}
如果我们现在将解析后的 JSON object 作为参数传递,它将自身与 object 合并,重新创建您拥有的内容:
var json = JSON.parse('{"valueA":1,"valueB":2,"valueC":3}')
function myObject(json) {
this.valueA = 0;
this.valueB = 0;
this.valueC = 0;
this.add = function() {
return this.valueA + this.valueB + this.valueC;
};
Object.assign(this, json); // will merge argument with itself
}
var o = new myObject(json); // reconstruct using original data
console.log(o.add());
如果您现在通过数组获得 children,您只需沿着链向下递归地重复该过程。
(一个好处是你也可以通过这种方式传递选项)。
不要这样做
这个问题有一些评论对重建 object 的概念持低估态度。评论者无法或不愿解释 为什么 他们认为这是个坏主意,但自从问起我就得出了同样的结论。原因如下。
如果您考虑 MVVM,拥有模型和 view-model 的目的是将行为与数据分开。这有点有趣,因为 object-orientation 的目的是将它们结合起来。但在分布式世界中,数据必须四处传输。如果您的代码和数据都混在一起,那么您必须发明 MVVM 或保留 de- and re-constructing objects.
de-和re-constructobjects的代码是你不需要的测试和维护time-sink,并引入了两种故障模式。不要这样做。有一个 method-less class 来保存状态和一个无状态的 class 在 method-less class 上运行。这是 MVVM 的本质,实际上无非是 Memento 模式的应用。
Memento (283) Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.
Design Patterns, Gamma et al, 1995
原问题
我的视图模型的数据作为 JSON 在客户端 JS 和服务器 Web API 之间来回传递。
众所周知,JSON.stringify(object)
仅序列化 non-null 值不是 Function
的成员。因此,JSON.parse(JSON.stringify(someObject))
将从 object.
我当前的实现是将每个图节点实现为带有序列化和反序列化方法的 Typescript class。 JQuery.ajax 调用 Web API 并将结果 JSON 隐式解析为 object 定义的 DAG,每个定义都有一个类型 属性 指示哪种类型的 class 这是在连载之前。我有一个按名称索引的构造函数映射,检索适当的构造函数并将数据作为构造函数参数传递。
根据类型可能有 children;如果是这样,事情将递归地向下进行。
我一直在想,除了复制所有 属性 值,我是否不能只分配一个合适的原型。把山带给穆罕默德,你可能会说。这将消除我的代码库中的相当多的混乱。
在我写的时候我突然想到我可以使用 $.extend,但是我正在逐步清除我的代码库的 jQuery out 所以这将是一个逆行.
- 我欺骗原型的提议是否存在任何已知的危险?
- 有没有人有更好的主意?除了 $.extend,我是说。优先使用 TypeScripty。
在评论中观察到,分配原型意味着永远不会调用构造函数。这无关紧要。 object 状态已经设置,所需要的只是使方法可用。
我最近构建了 object 使用可以序列化然后重建内容的方法。
我只是添加了一个参数,它可以接受一个 JSON object 并将其分配给自己。
使用普通 object 的示例:
function myObject() {
this.valueA = 1;
this.valueB = 2;
this.valueC = 3;
this.add = function() {
return this.valueA + this.valueB + this.valueC;
};
}
var o = new myObject();
console.log(o.add());
console.log(JSON.stringify(o));
如果你序列化这个你会得到:
{"valueA":1,"valueB":2,"valueC":3}
现在,要重构它,您可以将 Object.assign()
添加到 object 中,就像这样接受参数并将其与 self:
function myObject(json) {
this.valueA = 0;
this.valueB = 0;
this.valueC = 0;
this.add = function() {
return this.value1 + this.value2 + this.value3;
};
Object.assign(this, json); // will merge argument with itself
}
如果我们现在将解析后的 JSON object 作为参数传递,它将自身与 object 合并,重新创建您拥有的内容:
var json = JSON.parse('{"valueA":1,"valueB":2,"valueC":3}')
function myObject(json) {
this.valueA = 0;
this.valueB = 0;
this.valueC = 0;
this.add = function() {
return this.valueA + this.valueB + this.valueC;
};
Object.assign(this, json); // will merge argument with itself
}
var o = new myObject(json); // reconstruct using original data
console.log(o.add());
如果您现在通过数组获得 children,您只需沿着链向下递归地重复该过程。
(一个好处是你也可以通过这种方式传递选项)。