2014-09-29 35 views
0

我知道所有关于JSON.stringify或JSON.parse的含义,即一个序列化一个对象并将一个字符串反序列化为一个对象。这很棒!将JSON转换为JavaScript对象类型X

不过,我有以下情况:

var i = new MyMagicalObject(); 
var oi = JSON.parse(JSON.stringify(i)); 
console.log(i.numFields()); // this is fine 
console.log(oi.numFields()); // this throws since Object has no method 'numFields' 

基本上,我想对待OI为“MyMagicalObject”的一个实例,因为这是它是什么。

我确定在oi或其他设置原型上有一些魔力,但我对JavaScript很陌生。任何帮助,将不胜感激。

回答

1

你的问题可以通过重新设计MyMagicalObject类迎刃而解。这里是JSON友好类的例子:

function MyMagicalObject(props) { 
    this.props = props || {}; 
} 

MyMagicalObject.prototype.get = function(key) { 
    return this.props[key]; 
}; 

MyMagicalObject.prototype.set = function(key, val) { 
    this.props[key] = val; 
    return this; 
}; 

MyMagicalObject.prototype.toJSON = function() { 
    return this.props; 
}; 

MyMagicalObject.prototype.numFields = function() { 
    return Object.keys(this.props).length; 
}; 

这实现如下两条规则:

  1. 它的构造函数接受JSON表示作为第一个参数。
  2. 它提供toJSON方法来告诉JS引擎如何将其实例转换为JSON。

检查下面的例子:

var obj = new MyMagicalObject(); 
obj.set('foo', 42).set('bar', 'baz'); 
alert(obj.numFields()); // 2 

var str = JSON.stringify(obj); 

var obj2 = new MyMagicalObject(JSON.parse(str)); 
alert(obj2.numFields()); // 2 
+0

我喜欢这样 - 感觉比从对象文字到我的对象实例的属性更优雅。谢谢。 – FreeMemory 2014-09-29 09:03:50

+0

如果你在其中一个道具中存放了某个功能,该怎么办? – Zim84 2014-09-29 09:13:27

+1

@ Zim84不要。我意识到这是一个精辟的回应,但道具 - 根据定义 - 是属性,而不是函数,并且无论如何您都不能通过JSON流式传递函数。 – FreeMemory 2014-09-29 09:15:48

1

您可以创建一个新的MyMagicalObject(),然后用oi中的一个覆盖它的属性。

var t = new MyMagicalObject(); 
for(var k in oi) t[k]=oi[k]; 

这应该做的伎俩。如果您有更复杂的对象(具有多个维度),请搜索复制所有属性的复制功能。

+0

我希望有更多的东西高性能和更低的O(n)的-ish,因为我已经有了对象? – FreeMemory 2014-09-29 08:20:52

+1

要做的“更高性能”的事情就是创建一个新的“MyMagicalObject”,传递解析的对象,并设置它的值。 – Cerbrus 2014-09-29 08:22:45

2

你不能用JSON字符串“存储”JavaScript函数。

可以存储在JSON唯一数据类型是:

  • 字符串
  • 布尔
  • 阵列
  • 对象

(source)

任何不为这些类型之一,被忽略:

function Test(){ 
 
    this.foo = function(){ 
 
     return 'bar'; 
 
    } 
 
    this.theAnswer = '42'; 
 
} 
 
var t = new Test(); 
 
alert(t.foo()); 
 
alert(JSON.stringify(t))

+0

是的 - 我不想在JSON字符串中存储函数。我想要做的就是将对象反序列化回到我的对象类型中。 – FreeMemory 2014-09-29 08:17:02

0

行之后添加oi.prototype = MyMagicalObject.prototype; 3.

创建新对象并复制特性:

var oi2 = new MyMagicalObject(); 
for (var p in oi) { 
    if (oi.hasOwnProperty(p)) { 
     oi2[p] = oi[p] 
    } 
} 
console.log(oi2.numFields()); 
+0

这实际上并没有工作。我已经尝试过 - 仍然会抛出TypeError(没有方法'numFields')。 – FreeMemory 2014-09-29 08:17:37