fea*_*ool 6 javascript serialization json class node.js
我正在为一些特定于应用程序的对象编写一个简单的序列化/反序列化框架.
考虑以下:
"use strict";
function Dog(name) { this._name = name; };
Dog.prototype.constructor = Dog;
Dog.prototype.getName = function() { return this._name; }
var d1 = new Dog('fido');
var d2 = JSON.parse(JSON.stringify(d1)); // serialize / deserialize
> d1
Dog { _name: 'fido' }
> d1.getName()
'fido'
> d2
{ _name: 'fido' }
> d2.getName()
TypeError: d2.getName is not a function
Run Code Online (Sandbox Code Playgroud)
在这一点上,我们可以问"这是什么d1
有d2
没有?"
部分工作的一种方法是手动将d1的方法分配给d2:
> d2.constructor = d1.constructor
> d2.getName = d1.getName
> d2.getName()
'fido'
Run Code Online (Sandbox Code Playgroud)
这有几个缺点.首先,我必须手动将d1的每个方法分配给d2.其次,d2获取自己的属性,并且不使用原型机制共享插槽:
> d2
Dog {
_name: 'fido',
constructor: [Function: Dog],
getName: [Function] }
Run Code Online (Sandbox Code Playgroud)
所以我提出的问题是:给定一个对象(例如d2
),有没有办法将它与另一个对象的原型相关联(例如d1
),所以它继承了相同的行为?
Object.create()
而Object.getOwnPropertyDescriptors()
这正是您所需要的。
const obj = JSON.parse(JSON.stringify(d1))
const d3 = Object.create(Dog.prototype, Object.getOwnPropertyDescriptors(obj))
Run Code Online (Sandbox Code Playgroud)
此方法与OP方法之间的区别在于,此方法prototype
在原型上设置属性,而OP方法直接在对象上设置属性。当您使用带有hasOwnProperty()
方法的for-in循环遍历对象自身的属性时,可以看到以下内容:
for (const i in d1) {
if (d3.hasOwnProperty(i)) {
console.log(i)
}
}
Run Code Online (Sandbox Code Playgroud)
在我的方法中,它仅输出_name
,而在OP的方法中,它也输出getName
。
不幸的是,它Object.getOwnPropertyDescriptors()
是ECMAScript 2017的一部分,目前仅在Firefox中受支持,因此您需要使用Babel。
或者,您可以使用Object.setPrototypeOf()
。它具有比更好的浏览器支持Object.getOwnPropertyDescriptors()
,但是MDN不推荐使用它,因为它速度慢。
const d3 = JSON.parse(JSON.stringify(d1))
Object.setPrototypeOf(d3, Dog.prototype)
Run Code Online (Sandbox Code Playgroud)