首先声明,不推荐使用eval,这是非常危险且不稳定因素太多的做法
近期项目有这样一个需求,从服务器端返回的JSON里有一段JavaScript代码,需要在浏览器端执行它,把结果填充到一个数组里,最后toString回一个字符串,然后再提交到服务器保存。
首先,已有一个列表:
var list = [
{
name: '张三',
fun: function () {
console.log(this.name);
}
}
];
而服务器可能读取某个js文件,内容格式如下:
{
name: '李四',
fun: function () {
console.log(this.name);
}
}
其实就是一个JavaScript对象,然后会返回这样一串JSON格式的数据
{"success":true,"data":"{\n\tname: '李四',\n\tfun: function(){\n\t\tconsole.log(this.name);\n\t}\n}\n"}
data就是内容,我们打印一下data
$.get('/getdata', function (result) {
console.log(result.data);
}, 'json');
Output:
{
name: '李四',
fun: function () {
console.log(this.name);
}
}
现在,要把这个字符串处理成对象,然后填充到列表里,首先我们接收到的是字符串
$.get('/getdata', function (result) {
console.log(typeof result.data);
}, 'json');
Output:
string
让它变成一个对象
$.get('/getdata', function (result) {
var obj = eval('(function(){ return '+result.data+' })();');
for (var i in obj) {
console.log( i + '( ' + typeof obj[i] + ' ) = ' + obj[i]);
}
obj.fun();
}, 'json');
Output:
name( string ) = 李四
fun( function ) = function (){ alert( this.name ); }
李四
接下来,就容易了,我们把obj添加到数组里,最后toSring就可以
var list = [
{
name: '张三',
fun: function () {
console.log(this.name);
}
}
];
$.get('/getdata', function (result) {
var obj = eval('(function(){ return '+result.data+' })();');
list.push(obj);
var str = obj2string(str);
console.log(str);
}, 'json');
function obj2string(o){
var r=[];
if (typeof o === 'string') {
return "\""+o.replace(/([\'\"\\])/g,"\\$1").replace(/(\n)/g,"\\n").replace(/(\r)/g,"\\r").replace(/(\t)/g,"\\t")+"\"";
} else if (typeof o === 'object') {
if (!o.sort) {
for(var i in o){
r.push(i+":"+obj2string(o[i]));
}
if(!!document.all&&!/^\n?function\s*toString\(\)\s*\{\n?\s*\[native code\]\n?\s*\}\n?\s*$/.test(o.toString)){
r.push("toString:"+o.toString.toString());
}
r = "{"+r.join()+"}";
} else {
for (var i = 0; i < o.length; i++) {
r.push(obj2string(o[i]))
}
r = "["+r.join()+"]";
}
return r;
}
return o.toString();
}
这里不能把它当作一个普通JSON互转是因为里边有function