Javascript 从JSON重构JS对象 不要这样做

Javascript 从JSON重构JS对象 不要这样做,javascript,json,typescript,json-deserialization,Javascript,Json,Typescript,Json Deserialization,这个问题有一些评论,对重建物体的概念评价很低。评论者要么不能,要么不愿解释为什么他们认为这是一个坏主意,但自从问起我就得出了同样的结论。原因如下 如果您考虑MVVM,那么拥有一个模型和一个视图模型的目的是将行为与数据分离。这有点可笑,因为面向对象的重点是将它们结合起来。但在一个分布式世界中,数据必须四处传送。如果您的代码和数据都是混合在一起的,那么您要么发明MVVM,要么继续去构造和重新构造对象 用于解构和重新构造对象的代码是您不需要的测试和维护时间接收器,并且引入了两种故障模式。不要这样做。有

这个问题有一些评论,对重建物体的概念评价很低。评论者要么不能,要么不愿解释为什么他们认为这是一个坏主意,但自从问起我就得出了同样的结论。原因如下

如果您考虑MVVM,那么拥有一个模型和一个视图模型的目的是将行为与数据分离。这有点可笑,因为面向对象的重点是将它们结合起来。但在一个分布式世界中,数据必须四处传送。如果您的代码和数据都是混合在一起的,那么您要么发明MVVM,要么继续去构造和重新构造对象

用于解构和重新构造对象的代码是您不需要的测试和维护时间接收器,并且引入了两种故障模式。不要这样做。有一个无方法类来保存状态,还有一个无状态类在无方法类上操作。这是MVVM的精髓,实际上只不过是Memento模式的应用

纪念品(283) 在不违反封装的情况下,捕获并外部化对象的内部状态,以便以后可以将对象恢复到此状态

设计模式,Gamma等人,1995年


原始问题 我的视图模型的数据作为JSON在客户端JS和服务器Web API之间来回传递

众所周知,
JSON.stringify(object)
只序列化具有非空值且不是
函数的成员。因此,
JSON.parse(JSON.stringify(someObject))
将从对象中删除所有方法

我当前的实现将每个图形节点实现为带有序列化和反序列化方法的Typescript类。ajax调用Web API并隐式地将生成的JSON解析为对象定义的DAG,每个对象定义都有一个类型属性,指示序列化之前的类类型。我有一个按名称索引的构造函数映射,检索相应的构造函数,并将数据作为构造函数参数传递

根据类型,可能有儿童;如果是这样的话,事情就会沿着图表递归进行

我一直在想,与其复制所有的属性值,我是否不能只分配一个合适的原型。你可能会说,把这座山带到马霍米德。这将消除我的代码库中相当多的混乱

在我写的时候,我突然想到我可以使用$.extend,但我正在逐步将jQuery从代码库中剔除,所以这将是一个倒退的步骤

  • 我骗取原型的提议是否存在已知的危险
  • 有人有更好的主意吗?我是说,除了美元以外。某种类型的东西,根据喜好

在注释中观察到,分配原型意味着永远不会调用构造函数。这无关紧要。对象状态已经设置好,所需的只是使方法可用。

我最近用方法构建了对象,内容可以序列化然后重新构建

我只是添加了一个参数,它可以接受JSON对象并将其分配给自身

使用普通对象的示例:

函数myObject(){
该值a=1;
该值b=2;
该值c=3;
this.add=函数(){
返回this.valueA+this.valueB+this.valueC;
};
}
var o=新的myObject();
console.log(o.add());

log(JSON.stringify(o))“我的视图模型和其他所有人的一样,通过连接序列化为JSON。”。不,作为一个整体,我不是这样发展的。我们有相互通信的服务器端和客户端应用程序。传输的是数据,而不是模型和视图。@实际上是未定义的。我可以理解序列化/重新水化客户端模型以用于本地存储,但不能用于远程共享。无论如何,添加原型并不能完成所有需要的工作,比如调用构造函数。如果您想这样做,有多个库专门为此目的而设计。我已经用
--pedant
兼容性标志重新编译了。你现在应该可以解析它了,太好了。这与我的建议正好相反,但您已经实现了一步合并的基本目标,即一次不复制一个属性。因此基本上,
Object.assign
就是答案。问题可能是:什么是jQuery的
$.extend
函数的替代品。也就是说,@未定义,但以这种方式规范化问题将使其他遵循此查询路径的人无法发现。目标是在(反)序列化后,通过导线将Typescript方法与属性重新结合起来。