前些天說過關于JavaScript的Literal Syntax問題,覺得挺有意思的,于是又研究了一下,能不能把對象再轉化為Literal形式呢?就像我們平時說的序列化和反序列化啥的。當然可以了,因為JavaScript對象自身都提供了一個toString()方法,默認就是返回簡單對象的Literal形式。

??? 我們需要作的就是判斷對象的具體類型,然后分別Serialize每種對象,再輸出為Object的Literal語法形式就行了。準確的判斷對象類型,使用我曾經說過的__typeof__方法就行了,序列化對象實例的代碼如下:
Object.prototype.Serialize?=?function()
{
????
var?type?=?__typeof__(this);
????
switch(type)
????{
?????????
case?'Array'?:
?????????{
??????????????
var?strArray?=?'[';?
??????????????
for?(?var?i=0?;?i?<?this.length?;?++i?)
??????????????{
???????????????????
var?value?=?'';?
???????????????????
if?(?this[i]?)
???????????????????{
????????????????????????value?
=?this[i].Serialize();
???????????????????}
???????????????????strArray?
+=?value?+?',';
??????????????}
??????????????
if?(?strArray.charAt(strArray.length-1)?==?','?)
??????????????{
???????????????????strArray?
=?strArray.substr(0,?strArray.length-1);
??????????????}
??????????????strArray?
+=?']';??
??????????????
return?strArray;
?????????}
?????????
case?'Date'?:
?????????{
??????????????
return?'new?Date('?+?this.getTime()?+?')';
?????????}
?????????
case?'Boolean'?:
?????????
case?'Function'?:
?????????
case?'Number'?:
?????????
case?'String'?:
?????????{
??????????????
return?this.toString();
?????????}
?????????
default?:
?????????{
??????????????
var?serialize?=?'{';?
??????????????
for?(?var?key?in?this?)
??????????????{
???????????????????
if?(?key?==?'Serialize'?)?continue;?
???????????????????
var?subserialize?=?'null';
???????????????????
if?(?this[key]?!=?undefined?)
???????????????????{
????????????????????????subserialize?
=?this[key].Serialize();
???????????????????}
???????????????????serialize?
+=?'\r\n'?+?key?+?'?:?'?+?subserialize?+?',';
??????????????}
??????????????
if?(?serialize.charAt(serialize.length-1)?==?','?)
??????????????{
???????????????????serialize?
=?serialize.substr(0,?serialize.length-1);
??????????????}
??????????????serialize?
+=?'\r\n}';
??????????????
return?serialize;
?????????}
????}
};

??? 其實就是Array和Object的屬性比較的麻煩,需要遞歸的做這個Serialize操作。不過需要注意,Serialize方法就不需要被序列化出來了。下面是測試示例,不過這個序列化方法沒有對環狀引用做檢查,能序列化的對象很有限。

var?obj1?=?[];?
alert(obj1.Serialize());

var?obj2?=?[1,[2,[3,[4,[5,[6,[7,[8,[9,[0]]]]]]]]]];
alert(obj2.Serialize());

var?obj3?=?
????{
?????????Properties1?:?
1,?Properties2?:?'2',?Properties3?:?[3],
?????????Method1?:?
function(){?return?this.Properties1?+?this.Properties3[0];},
?????????Method2?:?
function(){?return?this.Preperties2;?}
????};
alert(obj3.Serialize());??

var?obj4?=?[null,?1,?'string',?true,?function(){return?'keke';},?new?Object()];
alert(obj4.Serialize());

??? 至于反序列化就非常的容易了,把上面的序列化結果用eval執行一下,就得到類實例了。