使用JavaScript 對Cookie 操作的封裝
當(dāng)前位置:點(diǎn)晴教程→知識管理交流
→『 技術(shù)文檔交流 』
匿名函數(shù) 閉包的產(chǎn)生 JavaScript實(shí)現(xiàn)private 以及 public 訪問權(quán)限 document.cookie 的操作 Javascript 沒有 private , public 訪問權(quán)限設(shè)置的關(guān)鍵字,但是可以通過一定的技巧來模擬出相同的結(jié)果. 首先我們來看下面一行代碼: var i = (1, 2, 3, 4, 5); 變量 i 最后的結(jié)果為 5. 這是逗號操作符的結(jié)果,也就是說返回最后的一個(gè)值,小括號改變了這行代碼的優(yōu)先級,否則 var i = 1, 2, 3, 4, 5; 會報(bào)錯(cuò)缺少標(biāo)識符. var i = (1, 2, 3, 4, function(){ return 5 * 5;}); 變量 i 最后的結(jié)果為 一個(gè)函數(shù), 返回結(jié)果 25. 這就是Javascript 的靈活之處,能夠賦值任意類型而不必提前聲明.現(xiàn)在我們完全可以進(jìn)行如下調(diào)用: i(); alert( i() ); 來獲得返回25的一次方法調(diào)用. 我們繼續(xù), 變量 i 是通過賦值符來獲取函數(shù)的引用的, 也就是說在等號右邊的小括號運(yùn)算完后返回的最后一個(gè)結(jié)果的引用還在,雖然我們無法顯示調(diào)用,但它確實(shí)存在,如果要不通過變量的引用而調(diào)用呢? (1, 2, 3, 4, function(){ alert(5 * 5);})() 上面的代碼執(zhí)行后,彈出一個(gè)消息框,顯示25. 為了顯示方便,我將上個(gè)例子的函數(shù)改為彈出消息框了. 兩對小括號 () (); 前面一對表示返回一個(gè)結(jié)果,如果該結(jié)果為一個(gè)函數(shù),由第二對小括號發(fā)生調(diào)用. 也就是通過前面一對括號發(fā)生匿名函數(shù)的引用,以便在下面進(jìn)行引用.這就是對匿名函數(shù)的調(diào)用. 關(guān)于更多匿名函數(shù)的使用可以參考文尾的引用連接. 閉包產(chǎn)生的原因是因?yàn)樽饔糜虻牟煌?子作用域引用了父作用域的變量,而返回子作用域,父作用域按理來說執(zhí)行完畢后該銷毀掉了,只是子作用域一直存在,且一直握有父作用域的引用,所以才一直保留. 來看下面的代碼 1 function parent() { 2 var a = 1; 3 function child(){ 4 var b = 2; 5 alert(a); 6 alert(b); 7 } 8 } 父函數(shù) parent 中包含了一個(gè) child 子函數(shù),在子函數(shù)中有一個(gè)對父函數(shù)中 a 變量的引用(輸出其值). 我們來讓父函數(shù)執(zhí)行完后返回其聲明的子函數(shù) 1 function parent() { 2 var a = 1; 3 function child(){ 4 var b = 2; 5 alert(a); 6 alert(b); 7 } 8 return child; 9 } 10 var t = parent(); 11 t(); 在10行中, 我們執(zhí)行了parent 函數(shù),返回了在函數(shù)內(nèi)部聲明的函數(shù) child,這時(shí)變量 t 持有該返回對象(此時(shí)是一個(gè)可以執(zhí)行的函數(shù))的引用,在11行代碼中我們調(diào)用了它.結(jié)果分別輸出了 1 和 2. 注意,輸出 2, 是因?yàn)槲覀冊谧雍瘮?shù)體內(nèi)聲明了一個(gè)變量,而輸出 1, 我們在該函數(shù)體內(nèi)并沒有相應(yīng)的定義變量 a ,而是發(fā)生了對父函數(shù)里的變量的引用,也就是說引用了父作用域的變量. 而此時(shí)又能能夠完成輸出的,也就是說變量 a 還存在.可是我們無法直接對其引用 (比如 parent.a),因?yàn)楹瘮?shù)已經(jīng)執(zhí)行完畢,沒有了其相應(yīng)的引用,我們只能通過所返回的子函數(shù)的引用來進(jìn)行訪問. 假如我又在父函數(shù)中聲明了其他的變量呢? 結(jié)果是一樣的,子函數(shù)能夠訪問,而如果子函數(shù)并不返回相應(yīng)的引用的話,我們根本無法從外部訪問到.這就形成了閉包. 閉包能夠干些什么呢?如果你有一個(gè)不想讓外部隨意修改的變量該怎么做?那就去使用閉包. 1 myObj = {}; //聲明一個(gè)全局變量,它是一個(gè)window對象的屬性(window.myObj) 2 (function(){ 3 var i = 4; 4 myObj = { //引用全局變量,對其進(jìn)行賦值 5 getI : function() { //get方法,一個(gè)函數(shù) 6 return i; 7 }, 8 setI : function(val) { //set方法,限制值的設(shè)定 9 if(val > 100) { 10 alert("i connt > 100"); 11 return; 12 } 13 i = val; 14 } 15 } 16 })(); //匿名函數(shù)的調(diào)用,由于也是一個(gè)函數(shù),所以作為一個(gè)子作用域,在執(zhí)行完之后銷毀,避免代碼污染 17 myObj.setI(5); //成功 18 myObj.setI(101); //失敗 19 alert(myObj.getI()); 20 alert(myObj.i); //錯(cuò)誤,沒有該屬性 至此我們簡單的實(shí)現(xiàn)了public 訪問權(quán)限以及 private 訪問權(quán)限 (也就給你想給你的,不給你不想給你的) 在頁面中,我們通常使用 document.cookie 屬性來訪問,對其賦新值就會創(chuàng)建一個(gè)新的Cookie,一個(gè)Cookie通常具有五個(gè)屬性:value (存儲的值), date (UTC格式的時(shí)間,代表什么時(shí)間過期, domain (域,Cookie的所有者), Path (子目錄). 而在平常的開發(fā)中,如果僅僅使用 document.cookie 屬性進(jìn)行訪問,會很麻煩,因?yàn)橹荒芟蚱滟x值字符串,并且在讀取后還要進(jìn)行字符串切割,才能獲取指定變量名稱的值.document.cookie 讀取時(shí),返回的是所有賦值的值,而不包括過期時(shí)間,域之類的信息,只能再次獨(dú)設(shè)置. 下面就附上代碼,全部封裝到Cookie全局對象中,暴露出幾個(gè)方法. Get : 放回指定所有cookie字符串. Set : 設(shè)置cookie 字符串. Clear : 清除所有cookie對象. GetDayTime : 獲取指定距今val天的Date對象. Write : 寫cookie.已重載.詳見代碼. Query : 查詢cookie. 已重載.詳見代碼. Update : 修改cookie. Delete : 刪除cookie. 1 Cookie = {}; 2 /* 3 * Date對象的setTime方法是設(shè)置距離1970-01-01以來的毫秒數(shù),設(shè)置到對象里去,返回的是據(jù)那以后的毫秒數(shù)而不是原對象. 4 * 如果Cookie 不設(shè)置 expires 屬性,或者expires 時(shí)間比本地時(shí)間少,那么將會在下一次瀏覽時(shí)過期. 5 * document.cookie 對象返回的是所有值的字符串形式,不包含 expires 或者其他. 6 * 7 */ 8 (function() { 9 var nDay = 24 * 60 * 60 * 1000; 10 var isString = function(v) { 11 return typeof v === "string"; 12 } 13 var isArray = function(v) { 14 return Object.prototype.toString.apply(v) == "[object Array]"; 15 } 16 var isObject = function(v) { 17 return v && typeof v == "object"; 18 } 19 var isDate = function(v) { 20 return Object.prototype.toString.apply(v) == "[object Date]"; 21 } 22 var getTime = function() { 23 return new Date().getTime(); 24 } 25 var trim = function(val) { 26 return (val || "").replace(/^\s+|\s+$/g, ""); 27 } 28 var tryEval = function(val) { 29 var Obj, e; 30 try { 31 Obj = eval(val); 32 } catch (e) { 33 Obj = val; 34 } 35 return Obj; 36 } 37 var ObjectToString = function(o) { 38 var tstr = "{"; 39 for (var v in o) { 40 if (isArray(o[v])) { 41 tstr += v + ":" + ArrayToString(o[v]) + ","; 42 } else if (isObject(o[v])) { 43 tstr += v + ":" + ObjectToString(o[v]) + ","; 44 } else if (isString(o[v])) { 45 tstr += v + ":\"" + o[v].toString() + "\","; 46 } else { 47 tstr += v + ":" + o[v].toString() + ","; 48 } 49 } 50 return tstr.slice(0, -1) + "}"; 51 } 52 var ArrayToString = function(o) { 53 var tstr = "["; 54 for (var v in o) { 55 if (isArray(o[v])) { 56 tstr += ArrayToString(o[v]) + ","; 57 } else if (isObject(o[v])) { 58 tstr += ObjectToString(o[v]) + ","; 59 } else { 60 tstr += o[v].toString() + ","; 61 } 62 } 63 return tstr.slice(0, -1) + "]"; ; 64 } 65 Cookie = { 66 Get: function() { 67 return document.cookie; 68 }, 69 Set: function(val) { 70 document.cookie = val; 71 }, 72 Clear: function() { 73 var temp = this.Query(); 74 var o; 75 for (o in temp) { 76 this.Delete(o); 77 } 78 }, 79 GetDayTime: function(val) { 80 var texpires = new Date(); 81 texpires.setTime(texpires.getTime() + val * nDay); 82 return texpires; 83 }, 84 Write: function() { 85 /* 86 * Cookie.Write(Object); 寫入對象,名稱為main; 87 * Cookie.Write(varname, Object); varname:變量名, Object:寫入對象; 88 * Cookie.Write(Object, Date); Object:寫入對象, Date:過期時(shí)間; 89 * Cookie.Write(varname, Object, Date); varname:變量名, Object:寫入對象, Date:過期時(shí)間; 90 * Cookie.Write(varname, Object, Date, Domain, Path); varname:變量名, Object:寫入對象, Date:過期時(shí)間, Domain:域, Path: 子目錄; 91 */ 92 if (arguments.length == 1) { 93 var tvalue = arguments[0]; 94 var tstr = ""; 95 var texpires = new Date(); texpires.setTime(texpires.getTime() + 1 * nDay); 96 if (isArray(tvalue)) { 97 tstr = ArrayToString(tvalue); 98 } else if (isObject(tvalue)) { 99 tstr = ObjectToString(tvalue); 100 } else { 101 tstr = tvalue.toString(); 102 } 103 tstr = "main=" + escape(tstr) + ";expires=" + texpires.toGMTString() + ";"; 104 } else if (arguments.length == 2) { 105 var tname, tvalue, texpires, tstr = ""; 106 if (isDate(arguments[1])) { 107 tname = "main"; 108 tvalue = arguments[0]; 109 texpires = arguments[1]; 110 } else { 111 tname = arguments[0]; 112 tvalue = arguments[1]; 113 texpires = new Date(); texpires.setTime(texpires.getTime() + 1 * nDay); 114 } 115 116 if (isArray(tvalue)) { 117 tstr += ArrayToString(tvalue); 118 } else if (isObject(tvalue)) { 119 tstr += ObjectToString(tvalue); 120 } else { 121 tstr = tvalue.toString(); 122 } 123 tstr = tname + "=" + escape(tvalue) + ";expires=" + texpires.toGMTString() + ";"; 124 125 } else if (arguments.length == 3) { 126 var tname = arguments[0], tvalue = arguments[1], texpires = arguments[2], tstr = ""; 127 if (isArray(tvalue)) { 128 tstr = ArrayToString(tvalue); 129 } else if (isObject(tvalue)) { 130 tstr = ObjectToString(tvalue); 131 } else { 132 tstr = tvalue.toString(); 133 } 134 tstr = tname + "=" + escape(tvalue) + ";expires=" + texpires.toGMTString() + ";"; 135 } else if (arguments.length == 5) { 136 var tname = arguments[0], tvalue = arguments[1], texpires = arguments[2], tdomain = arguments[3], tpath = arguments[4], tstr = ""; 137 if (isArray(tvalue)) { 138 tstr = ArrayToString(tvalue); 139 } else if (isObject(tvalue)) { 140 tstr = ObjectToString(tvalue); 141 } else { 142 tstr = tvalue.toString(); 143 } 144 tstr = tname + "=" + escape(tvalue) + ";expires=" + texpires.toGMTString() + ";domain=" + tdomain + ";path=" + tpath + ";"; 145 } 146 alert(tstr); 147 this.Set(tstr); 148 }, 149 Query: function() { 150 /* 151 * Cookie.Query(); 返回所有Cookie值組成的Object; 152 * Cookie.Query(string); 返回指定名稱的Object; 失敗則返回 undefined; 153 * Cookie.Query(string, Object); 為指定對象寫入指定名稱的Object,并返回; 失敗則返回 undefined; 154 */ 155 var tname = tvalue = "", tright = -1; 156 var tstr = this.Get(); 157 var tObj = {}; 158 if (arguments.length == 0) { 159 var i = 0; 160 do { 161 tname = trim(tstr.slice(i, tstr.indexOf("=", i))); 162 tright = tstr.indexOf(";", i); 163 if (tright == -1) { 164 tvalue = unescape(tstr.slice(tstr.indexOf("=", i) + 1, tstr.length)); 165 } else { 166 tvalue = unescape(tstr.slice(tstr.indexOf("=", i) + 1, tright)); 167 } 168 tObj[tname] = tryEval(tvalue); 169 i = tstr.indexOf(";", i) == -1 ? -1 : tstr.indexOf(";", i) + 1; 170 } while (i != -1); 171 172 } else { 173 tname = arguments[0]; 174 if (tstr.indexOf(tname) == -1) return undefined; 175 var i = tstr.indexOf(tname); 176 tname = trim(tstr.slice(i, tstr.indexOf("=", i))); 177 tright = tstr.indexOf(";", tstr.indexOf(tname)) == -1 ? tstr.length : tstr.indexOf(";", tstr.indexOf(tname)); 178 tvalue = unescape(tstr.slice(tstr.indexOf(tname) + tname.length + 1, tright)); 179 180 if (arguments.length == 1) { 181 tObj = tryEval(tvalue); 182 } else if (arguments.length == 2) { 183 tObj = arguments[1]; 184 tObj[tname] = tryEval(tvalue); 185 } 186 } 187 return tObj; 188 }, 189 Update: function() { 190 return this.Write.apply(this, arguments); 191 }, 192 Delete: function() { 193 if (arguments.length == 1) { 194 var varname = arguments[0]; 195 if (this.Query(varname)) { 196 this.Update(varname, "", new Date(1970, 01, 01)); 197 } 198 } 199 } 200 } 201 其中有一個(gè)從字符串eval 成對象的執(zhí)行,以及從Object 或者 Array 對象獲得對應(yīng)字符串形式的功能函數(shù),模擬了一些JSON的操作.當(dāng)然,并不能存儲所有的JavaScript 對象,僅僅滿足一部分,我已經(jīng)感覺夠用了. 個(gè)人理解有限,請各位多多指教. Javascript的匿名函數(shù) : http://dancewithnet.com/2008/05/07/javascript-anonymous-function/
Javascript的閉包 : http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html Cookie 文件的格式 : http://www.cnblogs.com/sephil/archive/2008/05/06/cookiefmt.html 該文章在 2010/11/25 23:20:26 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |