json.stringfy不处理对象方法
json.stringify does not process object methods
我正在尝试开发一个离线HTML5应用程序,该应用程序应该适用于大多数现代浏览器(Chrome、Firefox、IE 9+、Safari、Opera)。由于Safari还不支持IndexedDB,而且WebSQL也不受欢迎,所以我决定使用localStorage来存储用户生成的JavaScript对象,并使用JSON.stringify()
/JSON.parse()
来放入或取出对象。但是,我发现JSON.stringify()
不处理方法。下面是一个带有简单方法的示例对象:
var myObject = {};
myObject.foo = 'bar';
myObject.someFunction = function () {/*code in this function*/}
如果我将这个对象字符串化(稍后将其放入localStorage),那么将保留的只是myObject.foo
,而不是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
我相信你们中的许多人可能已经知道这个限制/功能/你想怎么称呼它。我想出的解决办法是用方法(myObject = new objectConstructor()
)创建一个对象,从localStorage中提取对象属性,并将它们分配给我创建的新对象。我觉得这是一种迂回的方法,但我是JavaScript世界的新手,所以我就是这样解决的。所以我的大问题是:我希望整个对象(属性+方法)都包含在localStorage中。我该怎么做?如果你能给我看一个更好的算法,或者另一个我不知道的JSON方法,我将不胜感激javascript中的函数不仅仅是它们的代码。它们也有范围。代码可以字符串化,但作用域不能。
JSON.stringify()
将对JSON支持的值进行编码。值可以是对象、数组、字符串、数字和布尔值的对象。其他任何内容都将被忽略或引发错误。函数不是JSON中支持的实体。JSON只处理纯数据,函数不是数据,而是具有更复杂语义的行为。
也就是说,你可以改变JSON.stringify()
的工作方式。第二个参数是replacer
函数。因此,你可以通过强制函数的字符串化来强制你想要的行为:
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!'" }"}
但是,当您读回来时,您必须评估函数字符串并将结果设置回对象,因为JSON不支持函数。
JSON中的所有编码函数都会变得非常棘手。你确定要这样做吗?可能还有更好的方法。。。
也许您可以保存原始数据,并将其从页面上加载的JS传递给构造函数。localStorage
将只保存数据,但加载到页面上的代码将提供对该数据进行操作的方法。
// 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'
我们不需要将getName()
方法保存到localStorage
。我们只需要将数据输入一个构造函数,该构造函数将提供该方法。
如果您想字符串化对象,但它们有函数,可以将JSON.stringify()
与第二个参数replacer
一起使用。为了防止对对象的循环依赖,可以使用var cache = []
。
在我们的项目中,我们使用lodash。我们使用以下函数来生成日志。可以使用它将对象保存到localStorage
。
var stringifyObj = function(obj) {
var cache = []
return JSON.stringify(obj, function(key, value) {
if (
_.isString(value) ||
_.isNumber(value) ||
_.isBoolean(value)
) {
return value
} else if (_.isError(value)) {
return value.stack || ''
} else if (_.isPlainObject(value) || _.isArray(value)) {
if (cache.indexOf(value) !== -1) {
return
} else {
// cache each item
cache.push(value)
return value
}
}
})
}
// create a circular object
var circularObject = {}
circularObject.circularObject = circularObject
// stringify an object
$('body').text(
stringifyObj(
{
myBooblean: true,
myString: 'foo',
myNumber: 1,
myArray: [1, 2, 3],
myObject: {},
myCircularObject: circularObject,
myFunction: function () {}
}
)
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
不按请求修复函数,而是一种本地存储变量的方法。。。
<html>
<head>
<title>Blank</title>
<script>
if(localStorage.g===undefined) localStorage.g={};
var g=JSON.parse(localStorage.g);
</script>
</head>
<body>
<input type=button onClick="localStorage.g=JSON.stringify(g, null, ' ')" value="Save">
<input type=button onClick="g=JSON.parse(localStorage.g)" value="Load">
</body>
</html>
将所有变量保留在对象g
中。示例:
g.arr=[1,2,3];
- 注意某些类型,例如
Date
,您需要执行以下操作:
g.date=new Date(g.date);
- 按页面本地存储:不同的页面具有不同的
g
- 从 javascript 中的对象方法返回一个对象
- 在Javascript中调用对象方法时不是函数类型错误
- Java Script将对象方法映射到数组中的对象
- 将数据从promise then方法传递到对象方法
- 设置显示后Flash对象方法不可用:无
- 通过引用Javascript中的另一个函数来传递对象方法
- Javascript库对象方法声明
- JavaScript对象范围-在对象方法中使用对象变量
- jQuery:如何使用文字对象方法中的方法来获取全局变量
- Javascript 对象方法不更新变量
- setInterval 只在对象方法上运行一次
- 对象方法中函数中的上下文
- 用JavaScript编写对象方法的最佳方式是什么
- 使用回调处理程序调用函数内部的父对象方法
- 从Javascript中的对象方法中访问全局变量
- 将此(对象)传递到一个对象方法嵌套方法中
- 为什么我得到“;不是函数错误”;对于我的对象方法
- 带有回调的Javascript对象方法中的递归
- 更正Node.js异步管道中的对象方法调用
- 如何在对象方法上调用requestAnimFrame