读Ext之十(解析JSON)

首先,回到第一篇。使用Ext.apply为Ext对象添加了一些属性,

Ext.apply(Ext, {

USE_NATIVE_JSON : false,

});

USE_NATIVE_JSON 即为其中之一, 可以使用它来设置是否开启浏览器原始的JSON(即JSON.parse,JSON.stringify)来解析或反解析。这是ECMA5中加入的,在 字符串转换成JSON的三种方式中已经提到。

该值初始为false,即不开启。设置为true则开启如

Ext.USE_NATIVE_JSON = true;

Ext.util.JSON 内部定义了一些私有方法,对外公开的有三个方法

encodeDate 将日期对象转成字符串
encode 将JS对象转成字符串
decode 将字符串转成JS对象

此外,encode和decode分别赋值给了Ext.encode和Ext.decode。如

Ext.encode = Ext.util.JSON.encode;
Ext.decode = Ext.util.JSON.decode;

即开发时可以使用更简短的Ext.encode和Ext.decode而非冗长的Ext.util.JSON.encode和Ext.util.JSON.decode。

Ext.util.JSON的大体结构如下

Ext.util.JSON = new (function(){
var useHasOwn = !!{}.hasOwnProperty,
isNative = function() {
var useNative = null;

return function() {
if (useNative === null) {
useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == ‘[object JSON]’;
}

return useNative;
};
}(),

;

this.encodeDate = function(o){
};
this.encode = function() {

}();
this.decode = function() {

}();

})();

可看到new了一个匿名函数(类),即Ext.util.JSON为一个单体。

匿名类中定义了一些私有变量useHasOwn、isNative等,this上挂了三个方法,即上面提到的对外公开的三个接口方法。

isNative 函数用来判断是否开启浏览器原始解析JSON的API,当然该函数只在Ext.USE_NATIVE_JSON为true的时候起作用,否则永远使用私有的doDecode和doEncode来解析。

isNative = function() {
var useNative = null;
return function() {
if (useNative === null) {
useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == ‘[object JSON]’;
}
return useNative;
};
}(),

pad 函数用来计算日期,所传参数n小于10时添加个0, 如月份传3时返回03,自动补个0。 this.encodeDate方法中用到。

pad = function(n) {
return n < 10 ? “0” + n : n;
},

doDecode 函数将字符转成JS对象,这里采用eval方式,当然还可以使用new Function。

doDecode = function(json){
return eval(“(” + json + ‘)’);
},

别忘了eval中两旁的小括号,否则会有意想不到的bug。为何加小括号见:JavaScript中大括号“{}”的多义性

doEncode 函数将JS对象转换成符合JSON规范的字符串,这个函数比较复杂。先对基本类型和数组,日期进行转换,最后是对JS对象的处理。

doEncode = function(o){
if(!Ext.isDefined(o) || o === null){
return “null”;
}else if(Ext.isArray(o)){
return encodeArray(o);
}else if(Ext.isDate(o)){
return Ext.util.JSON.encodeDate(o);
}else if(Ext.isString(o)){
return encodeString(o);
}else if(typeof o == “number”){
//don’t use isNumber here, since finite checks happen inside isNumber
return isFinite(o) ? String(o) : “null”;
}else if(Ext.isBoolean(o)){
return String(o);
}else {
var a = [“{“], b, i, v;
for (i in o) {
// don’t encode DOM objects
if(!o.getElementsByTagName){
if(!useHasOwn || o.hasOwnProperty(i)) {
v = o[i];
switch (typeof v) {
case “undefined”:
case “function”:
case “unknown”:
break;
default:
if(b){
a.push(‘,’);
}
a.push(doEncode(i), “:”,
v === null ? “null” : doEncode(v));
b = true;
}
}
}
}
a.push(“}”);
return a.join(“”);
}
},

doEncode中对字符串的转换用到了encodeString及encodeArray函数。

最后是三个挂在this上的方法,以this.decode示例

this.decode = function() {
var dc;
return function(json) {
if (!dc) {
// setup decoding function on first access
dc = isNative() ? JSON.parse : doDecode;
}
return dc(json);
};
}();

dc = isNative() ? JSON.parse : doDecode 可以看到如果isNative()返回true则使用浏览器原始的JSON.parse,否则使用doDecode。

本文链接



You must enable javascript to see captcha here!

Copyright © All Rights Reserved · Green Hope Theme by Sivan & schiy · Proudly powered by WordPress

无觅相关文章插件,快速提升流量