JS从后台读取一串字符转换为对象的处理案例

JavaScript 2013-06-05 eval,JavaScript,字符串,对象

近期项目有这样一个需求,从服务器返回的json数据里有一段js源码,要把它转换为对象,然后填充到一个数组里,最后toString回一个字符串,然后再提交给后台保存。

首先,已有一个列表:

var list = [
	{
		'name' : '张三',
		'fun'  : function(){
			alert( this.name );
		}
	}
];

而服务器可能读取某个js文件,内容格式如下:

{
	'name' : 'lee',
	'fun'  : function(){
		alert( this.name );
	}
}

其实就是一个js对象,然后会返回这样一串json格式的数据

{"success":true,"data":"{\n\t'name' : 'lee',\n\t'fun' : function(){\n\t\talert( this.name );\n\t}\n}\n"}

data就是内容,我们打印一下data

$.get('a.php',function(result){
	alert(result.data);				
},'json');

执行结果:

{
	'name' : 'lee',
	'fun'  : function(){
		alert( this.name );
	}
}

现在,要把这个字符串处理成对象,然后填充到列表里,首先我们接收到的是字符串:

$.get('a.php',function(result){
	alert(typeof result.data);
},'json');

执行:

string

让它变成一个普通的对象

$.get('a.php',function(result){

	var obj = eval('(function(){ return '+result.data+' })();');

	for(var i in obj){
		document.write( i + '( ' + typeof obj[i] + ' ) = ' + obj[i] + "<br />" );	
	}

	obj.fun();

},'json');

执行,正确的打印出成员信息:

name( string ) = lee
fun( function ) = function (){ alert( this.name ); }

并且,执行obj.fun函数也能弹窗

接下来,就容易了,我们把obj push到数组里,最后toSring就可以

$.get('a.php',function(result){

	var obj = eval('(function(){ return '+result.data+' })();');
	list.push( obj );

	var arr = [];

	for(var i in  list){
		arr.push( obj2string(list[i]) );			
	}

	var str = arr.join('');

	alert(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")+"\"";
	}
	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();
}

执行结果

从执行结果截图中,我们看到服务器返回的对象已经转换成普通对象并添加到list中了。

另外需要注意的是,服务器返回的这一段js数据里不能有//双斜杠单行注释,如果有单行注释而你在eval的时候不过滤掉注释内容会报错

如我们给服务器读取的js文件加上注释内容:

/*
 * 这里是 * 号注释
 */

{
	// 这里是双斜杠注释
	'name' : 'lee',
	'fun'  : function(){
		alert( this.name );
	}
}

而服务器返回的数据如下:

{"success":true,"data":"\/*\n * \u8fd9\u91cc\u662f * \u53f7\u6ce8\u91ca\n *\/\n\n{\n\t\/\/ \u8fd9\u91cc\u662f\u53cc\u659c\u6760\u6ce8\u91ca\n\t'name' : 'lee',\n\t'fun' : function(){\n\t\talert( this.name );\n\t}\n}\n"}

但我们eval的时候会报错

$.get('a.php',function(result){

	var obj = eval('(function(){ return '+result.data+' })();');

},'json');

报错:

但,可以保留/**/注释

/*
 * 这里是 * 号注释
 */

{
	/*
	 * 这里又是一个注释
	 */

	'name' : 'lee',
	'fun'  : function(){
		alert( this.name );
	}
}

重新执行,居然还报错,咱再过滤掉换行符:

$.get('a.php',function(result){

	result.data = result.data.replace( /\r\n/g , "");
	result.data = result.data.replace( /\n/g , "");

	var obj = eval('(function(){ return '+result.data +' })();');

	alert(obj);

},'json');

再执行,就搞定了

其实//单行注释报错的原因是因为这种注释必须通过换行结束注释,如果你是写正常js文件没有任何问题,但你要把一个字符串丢到eval里运行,就行不通了,而/**/这种是有关闭注释的标记,所以没有问题。

文字链接:《JS从后台读取一串字符转换为对象的处理案例

文章地址:http://www.qttc.me/201306337.html

除非标注,琼台博客所有博文均为原创,转载请加文字链接注明来源

乳名?小名?昵称?网名?均可

email,放心,我不会给你乱投广告的

想获得回访就把你的站点URL写上(没有留空)

[NOTICE]木要投放广告
[NOTICE]木要骂人,说不该说的话
[NOTICE]自由言论,但要遵纪守法

Comments 0

    Hi,你想第一个做沙发么?