我试图将对象存储在redis中,这是一个类的实例,因此具有函数,这是一个例子:
function myClass(){
this._attr = "foo";
this.getAttr = function(){
return this._attr;
}
}
有没有办法将这个对象与函数一起存储在redis中?我试过了JSON.stringify()
,但只保留了属性。如何存储函数定义并能够执行以下操作:
var myObj = new myClass();
var stringObj = JSON.stringify(myObj);
// store in redis and retreive as stringObj again
var parsedObj = JSON.parse(stringObj);
console.log(myObj.getAttr()); //prints foo
console.log(parsedObj.getAttr()); // prints "Object has no method 'getAttr'"
如何在致电foo
时获得parsedObj.getAttr()
?
提前谢谢!
修改
有建议修改MyClass.prototype并存储值,但是这样的事情(除了setter / getter之外的函数):
function myClass(){
this._attr = "foo";
this._accessCounts = 0;
this.getAttr = function(){
this._accessCounts++;
return this._attr;
}
this.getCount = function(){
return this._accessCounts;
}
}
我试图说明一个函数,除了执行其他操作外,每当调用它时计算类似计数或平均值的函数。
答案 0 :(得分:10)
首先,你没有定义一个类。
它只是一个对象,其属性的值是一个函数(在构造函数中定义的所有成员函数在创建新的实例时将复制,这就是为什么我说它不是一个班级。)
使用JSON.stringify
时会被删除。
考虑到你使用的是使用V8的node.js,最好的方法是定义一个真正的类,并用__proto__
发挥一点魔力。无论你在类中使用了多少属性(只要每个属性都使用原始数据类型),哪个属性都可以正常工作。
以下是一个例子:
function MyClass(){
this._attr = "foo";
}
MyClass.prototype = {
getAttr: function(){
return this._attr;
}
};
var myClass = new MyClass();
var json = JSON.stringify(myClass);
var newMyClass = JSON.parse(json);
newMyClass.__proto__ = MyClass.prototype;
console.log(newMyClass instanceof MyClass, newMyClass.getAttr());
将输出:
true "foo"
答案 1 :(得分:5)
不,JSON不存储函数(这也是非常低效的)。相反,使用序列化方法和反序列化构造函数。例如:
function MyClass(){
this._attr = "foo";
this.getAttr = function(){
return this._attr;
}
}
MyClass.prototype.toJSON() {
return {attr: this.getAttr()}; // everything that needs to get stored
};
MyClass.fromJSON = function(obj) {
if (typeof obj == "string") obj = JSON.parse(obj);
var instance = new MyClass;
instance._attr = obj.attr;
return instance;
};
答案 2 :(得分:1)
deserialize: function (vstrString) {
//.parse: convert JSON string to object state
//Use JSON to quickly parse into temp object (does a deep restore of all properties)
var tmpObject = JSON.parse(vstrString);
//objZoo2.animal.move();
//Note: can't just do something like this:
// CopyProperties(tmpObject, this);
//because it will blindly replace the deep objects
//completely...inadvertently wiping out methods on it. Instead:
//1) set the properties manually/one-by-one.
//2) on objects, defer to the deserialize on the child object (if it inherits clsPersistableObject)
//2b) if it doesn't inherit it, it's an intrinsic type, etc...just do a JSON parse.
//loop through all properties
var objProperty;
for (objProperty in tmpObject) {
//get property name and value
var strPropertyName = objProperty;
var strPropertyValue = tmpObject[objProperty]; //note: doing this .toString() will cause
if (objProperty !== undefined) {
//check type of property
if (typeof strPropertyValue == "object") {
//object property: call it recursively (and return that value)
var strPropertyValue_AsString = JSON.stringify(strPropertyValue);
//see if has a deserialize (i.e. inherited from clsPeristableObject)
if ("deserialize" in this[objProperty]) {
//yes: call it
this[objProperty]["deserialize"](strPropertyValue_AsString);
}
else {
//no: call normal JSON to deserialize this object and all below it
this[objProperty] = JSON.parse(strPropertyValue_AsString);
} //end else on if ("deserialize" in this[objProperty])
}
else {
//normal property: set it on "this"
this[objProperty] = tmpObject[objProperty];
} //end else on if (typeof strPropertyValue == "object")
} //end if (objProperty !== undefined)
}
}
答案 3 :(得分:0)
你得到什么grom JSON.stringify()是一个字符串。字符串没有方法。 您需要首先评估该字符串,然后您才能获得原始对象 及其方法。
var myObj = new myClass();
var stringObj = JSON.stringify(myObj);
----编辑-----
//Sorry use this:
var getBackObj = JSON.parse(stringObj);
//Not this
var getBackObj = eval(stringObj);
console.log(getBackObj.getAttr()); // this should work now
答案 4 :(得分:-1)
看起来你试图对一个封闭的函数进行字符串化。您可以使用()=> {}来解决范围问题。
function myClass(){
this._attr = "foo";
this._accessCounts = 0;
this.getAttr = ()=>{
this._accessCounts++;
return this._attr;
}
this.getCount = ()=>{
return this._accessCounts;
}
}