json.stringify不处理对象方法 [英] json.stringify does not process object methods

查看:556
本文介绍了json.stringify不处理对象方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发一个适用于大多数现代浏览器(Chrome,Firefox,IE 9 +,Safari,Opera)的离线HTML5应用程序。由于Safari(尚未)支持IndexedDB,并且不推荐使用WebSQL,因此我决定使用localStorage存储用户生成的JavaScript对象,并使用 JSON.stringify() / JSON.parse()放入或拔出对象。但是,我发现 JSON.stringify()不处理方法。这是一个带有简单方法的示例对象:

  var myObject = {}; 
myObject.foo ='bar';
myObject.someFunction = function(){/ *此函数中的代码* /}

如果我将此对象进行字符串化(稍后将其放入localStorage),那么所有将保留的是 myObject.foo ,而不是 myObject.someFunction()

  //将对象放入localStorage 
localStorage.setItem('myObject',JSON .stringify(myObject的));

//将它拉出localStorage并将其设置为myObject
myObject = localStorage.getItem('myObject');

//未定义!
myObject.someFunction

我相信很多人可能已经知道这个限制/功能/无论你想要什么叫它。我提出的解决方法是使用方法创建一个对象( myObject = new objectConstructor()),从localStorage中提取对象属性,然后分配它们到我创建的新对象。我觉得这是一个迂回的方法,但我是JavaScript世界的新手,所以这就是我解决它的方法。所以这是我的大问题:我希望将整个对象(属性+方法)包含在localStorage中。我该怎么做呢?如果您可以向我展示一个更好的算法,或者我可能不知道的其他JSON方法,我会非常感激。

解决方案

javascript中的函数不仅仅是他们的代码。他们也有范围。代码可以被字符串化,但范围不能。



JSON.stringify()将编码JSON支持的值。具有可以是对象,数组,字符串,数字和布尔值的值的对象。其他任何内容都将被忽略或抛出错误。函数不是JSON中受支持的实体。 JSON只处理纯数据,函数不是数据,而是具有更复杂语义的行为。






这表示你可以改变方式 JSON.stringify()有效。第二个参数是 replacer 函数。所以你可以通过强制函数的强制来强制你想要的行为:

  var obj = {
foo:function (){
返回我是一个函数!;
}
};

var json = JSON.stringify(obj,function(key,value){
if(typeof value ==='function'){
return value.toString() ;
} else {
返回值;
}
});

console.log(json);
// {foo:function(){return \我是一个函数!\}}

但是当你读回来时,你必须评估函数字符串并将结果设置回对象,因为JSON 不支持函数。 / p>




JSON中的所有编码功能都可能非常多毛。你确定你要这么做吗?可能有更好的方法......



也许您可以保存原始数据,并将其传递给页面上加载的JS中的构造函数。 localStorage 只会保存数据,但是加载到页面上的代码会提供操作该数据的方法。

  //人为的例子...... 

var MyClass = function(data){
this.firstName = data.firstName;
this.lastName = data.lastName;
}

MyClass.prototype.getName(){
返回this.firstName +''+ this.lastName;
}

localStorage.peopleData = [{
firstName:'Bob',
lastName:'McDudeFace'
}];

var peopleData = localStorage.peopleData;

var bob = new MyClass(peopleData [0]);
bob.getName()//'Bob McDudeFace'

我们不需要将 getName()方法保存到 localStorage 。我们只需要将这些数据提供给将提供该方法的构造函数。


I am trying to develop an offline HTML5 application that should work in most modern browsers (Chrome, Firefox, IE 9+, Safari, Opera). Since IndexedDB isn't supported by Safari (yet), and WebSQL is deprecated, I decided on using localStorage to store user-generated JavaScript objects and JSON.stringify()/JSON.parse() to put in or pull out the objects. However, I found out that JSON.stringify() does not handle methods. Here is an example object with a simple method:

    var myObject = {};
    myObject.foo = 'bar';
    myObject.someFunction = function () {/*code in this function*/}

If I stringify this object (and later put it into localStorage), all that will be retained is myObject.foo, not myObject.someFunction().

    //put object into localStorage
    localStorage.setItem('myObject',JSON.stringify(myObject));

    //pull it out of localStorage and set it to myObject
    myObject = localStorage.getItem('myObject');

    //undefined!
    myObject.someFunction

I'm sure many of you probably already know of this limitation/feature/whatever you want to call it. The workaround that I've come up with is to create an object with the methods(myObject = new objectConstructor()), pull out the object properties from localStorage, and assign them to the new object I created. I feel that this is a roundabout approach, but I'm new to the JavaScript world, so this is how I solved it. So here is my grand question: I'd like the whole object (properties + methods) to be included in localStorage. How do I do this? If you can perhaps show me a better algorithm, or maybe another JSON method I don't know about, I'd greatly appreciate it.

解决方案

Functions in javascript are more than just their code. They also have scope. Code can be stringified, but scope cannot.

JSON.stringify() will encode values that JSON supports. Objects with values that can be objects, arrays, strings, numbers and booleans. Anything else will be ignored or throw errors. Functions are not a supported entity in JSON. JSON handles pure data only, functions are not data, but behavior with more complex semantics.


That said you can change how JSON.stringify() works. The second argument is a replacer function. So you could force the behavior you want by forcing the strinigification of functions:

var obj = {
  foo: function() {
    return "I'm a function!";
  }
};

var json = JSON.stringify(obj, function(key, value) {
  if (typeof value === 'function') {
    return value.toString();
  } else {
    return value;
  }
});

console.log(json);
// {"foo":"function () { return \"I'm a function!\" }"}

But when you read that back in you would have to eval the function string and set the result back to the object, because JSON does not support functions.


All in all encoding functions in JSON can get pretty hairy. Are you sure you want to do this? There is probably a better way...

Perhaps you could instead save raw data, and pass that to a constructor from your JS loaded on the page. localStorage would only hold the data, but your code loaded onto the page would provide the methods to operate on that data.

// contrived example...

var MyClass = function(data) {
  this.firstName = data.firstName;
  this.lastName = data.lastName;
}

MyClass.prototype.getName() {
  return this.firstName + ' ' + this.lastName;
}

localStorage.peopleData = [{
  firstName: 'Bob',
  lastName:  'McDudeFace'
}];

var peopleData = localStorage.peopleData;

var bob = new MyClass(peopleData[0]);
bob.getName() // 'Bob McDudeFace'

We don't need to save the getName() method to localStorage. We just need to feed that data into a constructor that will provide that method.

这篇关于json.stringify不处理对象方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆