日期:2014-05-16 浏览次数:20581 次
首先,回到第一篇 。使用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 = fun