一些JSON相关的函数

JSON作为一种轻量的数据传输格式,越来越受到人们的青睐。下面是我仿照Prototype的一些实现。

JSONFilter:/^\/\*-secure-([\s\S]*)\*\/\s*$/,
unfilterJSON:function(json,filter) {
return json.replace((filter || dom.JSONFilter), function(a,b){
return b || ""
});
},

JSONFilter完全抄自Prototype,因为后台基本上只会传输两种格式的东西给我们——文本(xmlhttp.responseText)与XML(xmlhttp.responseXML)。如果要json,我们可以eval一下,或者使用现代浏览器提供的JSON.parse方法。但问题就出在eval中,很容易出现XSS攻击。如果文本是注释就可以避免这问题,在Prototype中还检察一下请求的来源。对于自家的网站的请求,我们完全可以在请求前处理一下,让它变成如下格式:

var text = '/*-secure-\n{"name": "Violet", "occupation": "character", "age": 25}\n*/'
dom.unfilterJSON(text)
// -> '{"name": "Violet", "occupation": "character", "age": 25}'

到时我们用unfilterJSON函数提取合法的字段来eval就没问题了。

第二个函数,判断字符串是否符合JSON的格式。JSON是有固定的格式,要求键必须被双引号括起来。下面的函数提取自json2

isJSONText:function(json){//
return /^[\],:{}\s]*$/.test(json.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
.replace(/(?:^|:|,)(?:\s*\[)+/g, ""));
},

第三个函数,将符合JSON的格式的文本变成JSON对象。第二参数用于指明此文本是否安全(如,是否同源请求)。如果能用原生对象的parse方法就用原生的,否则动态解析它。之所以不用eval,是因为ecma那帮人头脑发热,想禁掉它。

evalJSON: function( json ,sanitize) {
if ( !is(json,"String") || !json )
return null;
json = dom.unfilterJSON(json);
//判定是否符合JSON的格式 from http://json.org/json2.js
if ( !sanitize || dom.isJSONText(json) ) {
return window.JSON && window.JSON.parse ?
window.JSON.parse( json ) : (new Function("return " + json))();
} else {
throw "Invalid JSON: " + json;
}
}
//http://www.21kaiyun.com
var data =dom.evalJSON( '{ "name": "Violet", "occupation": "character" }');
data.name;
//-> "Violet"

第四函数,将JSON对象变成文本。

// http://www.21kaiyun.com

//21世纪开运网

// var a = [1,2,3,4,{aa:8}]; puts(dom.toJSON(a))
toJSON:function(obj){
if (window.JSON && window.JSON.stringify) {
return JSON.stringify(obj)
}
if (typeof window.uneval == 'function') {
return uneval(obj);
}
if (typeof obj == 'object') {
if (!obj) {
return 'null';
}
var list = [];
if (dom.is(obj,"Array")) {
for (var i=0,n=obj.length;i <n;i++) {
list.push(dom.toJSON(obj[i]));
}
return '[' + list.join(',') + ']';
} else {
for (var prop in obj) {
if(obj[has](prop))
list.push('"' + prop + '":' + dom.toJSON(obj[prop]));
}
return '{' + list.join(',') + '}';
}
} else if (typeof obj == 'string') {
return '"' + obj.replace(/(["'])/g, '\\$1') + '"';
} else {
return new String(obj);
}
},
toJSON : function(obj) {
if(is(window.JSON,"JSON")){
return JSON.stringify(obj)
}
function f(n) {
return n < 10 ? '0' + n : n;
}
var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
var meta = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
};
function _char(c) {
return meta[c] ? meta[c] :'\\u'+('0000'+(+(c.charCodeAt(0))).toString(16)).slice(-4);
}
function _string(s) {
return '"' + s.replace(escapable, _char) + '"';
}
if(is(obj,"Date")){
return '"' + obj.getUTCFullYear() + '-' +
f(obj.getUTCMonth() + 1) + '-' +
f(obj.getUTCDate()) + 'T' +
f(obj.getUTCHours()) + ':' +
f(obj.getUTCMinutes()) + ':' +
f(obj.getUTCSeconds()) + 'Z"' ;
}else if(is(obj,"Number")){
return isFinite(obj) ? obj+'' : 'null';
}else if(is(obj,"Boolean")){
return obj+''
}else if(is(obj,"String")){
return _string(obj)
}else if(obj === null){
return "null"
}else if(is(obj,"Array")){
return '[' + (dom.filter(obj,function(value){
return dom.toJSON(value) !== undefined;
})).join(', ') + ']';
}else if(is(obj,"Object")){
var results = [];
dom.each(obj,function(value,key){
value = dom.toJSON(value)
if (!value)
results.push(dom.toJSON(key) + ': ' + value);
});
return '{' + results.join(', ') + '}';
}else {
return undefined;
}
},

Is函数

目前最精确的判定方法(不包括自定义类型)

//2010.6.1更新
var is = function (obj,type) {
return (type === "Null" && obj === null) ||
(type === "Undefined" && obj === void 0 ) ||
(type === "Number" && isFinite(obj)) ||
Object.prototype.toString.call(obj).slice(8,-1) === type;
},

用法如下:

//***************示例一,判定数组与函数
var forEach = function(array,fn,bind){
if(is(array,"Array") && is(Array.forEach,"Function")){
array.forEach(fn,bind);
}else{
for(var i=0,n=array.length;i<n;i++){
i in array && fn.call(bind,array[i],i,array)
}
}
}
//***************示例二,判定null
var a = null
alert(is(a,"Null"))
//***************示例二,判定undefined
var b
alert(is(b,"Undefined"))

另一个变种,直接返回表示类型的字符串

var getType = function (obj) {
var _toString = Object.prototype.toString,undefined;
return obj === null? "Null":
obj === undefined ? "Undefined":
_toString.call(obj).slice(8,-1);
};

用法:

var arr = [1,2,3,4]
alert(getType(arr));//Array
var nil = null
alert(getType(nil))//Null
var und ;
alert(getType(und))//Undefined
var spans = document.getElementsByTagName("span");
alert(getType(spans)) //HTMLCollection
alert(getType(spans[0].childNodes))//NodeList
//2010.7.20
function isA (thing, canon) {
// special case for null and undefined
if (thing == null || canon == null) {
return thing === canon;
}
return Object.getPrototypeOf(Object(thing)) == Object.getPrototypeOf(Object(canon));
}
function isBool (thing) {
return isA(thing, true);
}
function isNumber (thing) {
return isA(thing, 0) && isFinite(thing);
}
function isString (thing) {
return isA(thing, "");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值