javascript開發(fā)經(jīng)驗總結(jié)一多重條件判斷_第1頁
javascript開發(fā)經(jīng)驗總結(jié)一多重條件判斷_第2頁
javascript開發(fā)經(jīng)驗總結(jié)一多重條件判斷_第3頁
javascript開發(fā)經(jīng)驗總結(jié)一多重條件判斷_第4頁
javascript開發(fā)經(jīng)驗總結(jié)一多重條件判斷_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、javascript是一門精巧的語言,可大可小,可伸可縮,如意金箍棒一般,運用恰當(dāng),可敵千夫。比如一個場景,有的人要寫上百行代碼,但是有的人寥寥幾筆即可實現(xiàn),思路就在彈指間。要想學(xué)好一門語言,就要掌握其要義,歸納其精髓,方可如魚得水,運籌帷幄。 js在開發(fā)大型組件庫的時候經(jīng)常會碰到很多的邏輯分支情況。比如博客園的編輯框編寫:if(target = "font") someFunction().else if(target = "code") someFunction(). else if(target = "table")

2、someFunction().else if(target = "images") someFunction().else if(target = "link") someFunction(). else if(target = "file") someFunction().   為了邏輯清晰當(dāng)然也可以這樣寫:switch(target) case : "font" : someFunction(). break; case : "code" : someFunction(). bre

3、ak; case : "table" : someFunction(). break; case : "images" : someFunction(). break; case : "link" : someFunction(). break;case : "file" : someFunction(). break;當(dāng)然這樣的一層邏輯很容易書寫和維護,但是,如果碰到下面還有多重分支的情況改如何處理呢,大部分人都是繼續(xù)if else或者switch case。于是代碼就變的越來越長,越來越難維護。就像下面的代碼一

4、樣:switch(target) case : "font" : someFunction(). break; case : "code" : switch(code) case : "java" : someFunction(). break; case : "c" : someFunction(). break; case : "c+" : someFunction(). break; break; case : "table" : someFunction(). bre

5、ak; case : "images" : someFunction(). break; case : "link" : someFunction(). break;case : "file" : someFunction(). break;  js是一門面向?qū)ο蟮恼Z言,我們能不能用面向?qū)ο蟮乃枷雭斫鉀Q這個問題呢?請看下面的源碼: editor = "font" : function(). "code" : function(). "table" : fu

6、nction(). "images" : function(). "file" : function().editortarget();  這樣是不是清晰明了了很多?而且效率也肯定提升了,因為是對象直接尋址。大致思路如下:先創(chuàng)建一個對象,把所有的判斷分支都放到這個對象里,然后再調(diào)用。 那么是么時候需要用這個方法,什么時候不需要用呢?先說需要用的:一、在判斷分支很多的情況下建議使用。條理清晰。二、在分支里的邏輯很復(fù)雜的情況下,可以起到邏輯拆分的作用。 再說不需要用的情況:一、簡單的邏輯判斷。二、分支比較少的情況。js模版對于一

7、個健壯的組件庫來說,至關(guān)重要。猶如建筑一棟大樓,模版就是鋼筋,數(shù)據(jù)就是水泥,事件就是布線和弱電。本文將從一個小函數(shù)講起,然后重點探討js模版的實現(xiàn)模式、易用性、可擴展性,然后再對ext的模版體系做簡單分析。 由于工作原因,本人一直在維護一個datagrid組件,datagrid的需求千變?nèi)f化,大概60%的需求都是對單元格的處理,剛剛開始的時候需要一個功能就加一個功能,比如單元格需要根據(jù)數(shù)據(jù)改變背景顏色,于是我便在表格生成之后直接操作dom,比如帶checkbox的datagrid,翻頁后需要保存已選狀態(tài),于是我便在表格生成之后查找checkbox然后再選中。需要在增加,datagri

8、d也慢慢變的臃腫起來,不堪重負(fù),leader也決定開始重構(gòu)了。在重構(gòu)之初,我便決定,在表格生成之前把需要處理的都完成,這樣就可以節(jié)省查詢dom的時間。這樣以來,前期創(chuàng)建需要處理的邏輯就會很多,所以這里就需要一個很完善的模版體系來做支持,否則玩到最后又會變的很臃腫。 于是我嘗試著寫了一個簡單的基于對象模式的模版,代碼如下: /* * * 對象模式創(chuàng)建模版 * * param Array attrs 生成的節(jié)點數(shù)組 * param String type 類型 * param Array|Object attr 屬性 * param Array|Object child 子節(jié)點

9、 * param Number num 子節(jié)生成個數(shù) * param Function func 處理函數(shù) * param Array data 數(shù)據(jù) * * param Element|String target */var tpl = function(ats, target) target = fast.id(target); if (fast.isArray(ats) && ats.length > 0 && target.appendChild) for (var i = 0, len = ats.length; i < len; i+)

10、var attrs = atsi, tag = attrs.tag, attr = attrs.attr | , data = attrs.data, func = attrs.func, child = attrs.child, num = attrs.num ? attrs.num : 1, j = 0; var fragment = document.createDocumentFragment(); for (; j < num; j+) var isFunc = false; if (data) if (child) if (fast.isArray(child) for (v

11、ar k = 0, l = child.length; k < l; k+) childk.data = dataj; else child.data = dataj; else if (func) attr = func(j, attr, data); isFunc = true; else data = fast.values(data); attr.text = dataj; (isFunc = false) && func && ( attr = func(j, attr, data); var nodes = fast.node(tag, att

12、r); fragment.appendChild(nodes); child && tpl(child, nodes); target.appendChild(fragment); ; 另外創(chuàng)建了一個基類,這個基類后面的例子都會用到,希望讀者注意。View Code var doc = window.document, _toString = Ototype.toString;var fast = isString : function(obj) return !(obj = '' | (obj && obj.char

13、CodeAt && obj.substr); , isNumber : function(obj) return _toString.call(obj) = 'object Number' , isArray : .isArray | function(obj) return _toString.call(obj) = 'object Array' , isObject : function(obj) return obj = null ? String(obj) = 'object' : _toString.call(obj)

14、= 'object Object' | true; , isEmptyObject : function(obj) for (var name in obj) return false; return true; , getID : function() var num1 = new Date().getTime(); var num2 = parseInt(Math.random() * 100000, 10); return num1 + num2; , id : function(id) if (this.isString(id) return doc.getElemen

15、tById(id); else if (id.nodeType) return id; return; , html : function(el, html) el = this.id(el); if (html) if (el != null && 'innerHTML' in el) el.innerHTML = html; else return el.innerHTML; , values : function(obj) var ret = ; for (var key in obj) ret.push(objkey); return ret; , se

16、tCssText : function(el, cssText) el.style.cssText = cssText; , setAttr : function(element, attrObj) var me = this, mapObj = "class" : function() element.className = attrObj"class" , "style" : function() me.setCssText(element, attrObj"style"); , "text"

17、; : function() if (attrObj"text".nodeType) element.appendChild(attrObj"text"); else element.appendChild(document.createTextNode(attrObj"text"); for (p in attrObj) if (mapObjp) mapObjp(); else element.setAttribute(p, attrObjp); , node : function(type, attrObj) var elemen

18、t = doc.createElement(type); if (!this.isEmptyObject(attrObj) this.setAttr(element, attrObj); return element; , testTime : function(get_as_float) var now = new Date().getTime() / 1000; var s = parseInt(now, 10); return (get_as_float) ? now : (Math.round(now - s) * 1000) / 1000) + ' ' + s; ,

19、/ext*/ _indexOf : Atotype.indexOf, inArray : function(elem, arr, i) var len; if (arr) if (this._indexOf) return this._indexOf.call(arr, elem, i); len = arr.length; i = i ? i < 0 ? Math.max(0, len + i) : i : 0; for (; i < len; i+) if ( i in arr && arri = elem) return i; return -

20、1; , isDate : function(o) return (null != o) && !isNaN(o) && ("undefined" != typeof o.getDate); , Format : , decodeHTML : function(str) str = String(str).replace(/&quot;/g, '"').replace(/&lt;/g, '<').replace(/&gt;/g, '>').repla

21、ce(/&amp;/g, "&"); /處理轉(zhuǎn)義的中文和實體字符 return str.replace(/&#(d+);/g, function(_0, _1) return String.fromCharCode(parseInt(_1, 10); ); , apply : function(object, config, defaults) if (defaults) this.apply(object, defaults); var enumerables = true, enumerablesTest = toString : 1 ; for

22、 (i in enumerablesTest) enumerables = null; if (enumerables) enumerables = 'hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor' if (object && config && typeof config =

23、 'object') var i, j, k; for (i in config) objecti = configi; if (enumerables) for ( j = enumerables.length; j-; ) k = enumerablesj; if (config.hasOwnProperty(k) objectk = configk; return object; ; 在模版使用之前,我們需要預(yù)先定義一組數(shù)據(jù),這組數(shù)據(jù)后面的幾個模版體系都會用到:View Code var data = name : "test1",sex :

24、 "man",age : "20",date : "2011-10-13 12:00:00:0",uid : "1", name : "test2",sex : "man",age : "20",date : "2011-10-13 12:00:00:0",uid : "2", name : "test3",sex : "man",age : "20",da

25、te : "2011-10-13 12:00:00:0",uid : "3", name : "test4",sex : "man",age : "20",date : "2011-10-13 12:00:00:0",uid : "4", name : "test5",sex : "man",age : "20",date : "2011-10-13 12:00:00:0",u

26、id : "5", name : "test6",sex : "man",age : "20",date : "2011-10-13 12:00:00:0",uid : "6", name : "test7",sex : "man",age : "20",date : "2011-10-13 12:00:00:0",uid : "7", name : "test8&q

27、uot;,sex : "man",age : "20",date : "2011-10-13 12:00:00:0",uid : "8", name : "test9",sex : "man",age : "20",date : "2011-10-13 12:00:00:0",uid : "9", name : "test10",sex : "man",age : "

28、20",date : "2011-10-13 12:00:00:0",uid : "10"for(var i = 10; i < 1000; i+) data.push(name : "test"+i,sex : "man",age : "20",date : "2011-10-13 12:00:00:0",uid : i); 這個模版的使用事例如下:var td = tag:"td",num:5,attr:text:"

29、text"var tr = tag:"tr",num:1000,child:td,data:data;var tbody = tag:"tbody",child:tr;tpl(tag:"table",attr:style:"width:100%",border:"1",child:tbody,"example");當(dāng)然,您也可以這樣寫:tpl(tag:"table",attr:style:"width:100%",border

30、:"1", child:tag:"tbody", child:tag:"tr",num:1000, child:tag:"td",num:5,attr:text:"text", data:data , "example"); 該模版的核心思路就是遞歸創(chuàng)建dom,支持對每個dom綁定數(shù)據(jù),支持外部函數(shù)調(diào)用(helper),支持內(nèi)嵌數(shù)據(jù)處理,支持一次創(chuàng)建多個平級dom。對于一個組件庫來說,感覺這樣很完美了,于是我興致沖沖的想拿其他的模版體系做對比。找了一大圈,發(fā)現(xiàn)別人玩

31、模版不是這樣玩的,大部分都是先拼裝字符串,然后再放到一個閉包里來處理,再返回。于是我模仿著別人寫了一個原型,代碼如下: /* * 字符串模式創(chuàng)建模版 * */var tp = function(str, data) var str = fast.id(str) ? fast.html(str) : str, str = str.replace(/<#(s|S)*?#>/g, function(p) return p.replace(/("|)/g, "$1").replace("<#", '_s.push(&

32、quot;').replace("#>", '");').replace(/<%(sS*?)%>/g, '",$1,"') ).replace(/r|n/g, ""), keys = , values = , i; for (i in data) keys.push(i); values.push(datai); return (new Function(keys, "var _s=;" + str + " return _s;"

33、;) ).apply(null, values).join("");調(diào)用方式大致如下:<div id="tptest" style="height:100px;overflow-y: auto"></div><script id="t1" type="text/tpl"><#<table width="100%" border="1">#> for (var i = 0, l = list.len

34、gth; i < l; i +) <#<tr>#> for(var p in listi) <#<td> <%listip%> </td>#> <#</tr>#> <#</table>#></script><script>var tpdata = list: data;fast.html("tptest",tp("t1",tpdata); 做了一下性能對比,乖乖,這個性能比對象模式更快,而且對象模

35、式能實現(xiàn)的,這個基本都能實現(xiàn)。但是對于處理單個dom的方式上,總感覺缺點什么,想來想去,原來這種方式不能把一個dom拿出來單獨玩,需要跳到模版里面去,這里就需要注意環(huán)境變量以及邏輯關(guān)系了。 還是不死心,于是一狠心把ext的模版抽筋剝皮拿了出來,代碼如下(運行需要上面的fast基類,未經(jīng)詳細(xì)測試,不建議用于生產(chǎn)環(huán)境):View Code extpl = constructor: function(html) var me = this, args = arguments, buffer = , i = 0, length = args.length, value; me.initial

36、Config = ; if (length > 1) for (; i < length; i+) value = argsi; if (typeof value = 'object') fast.apply(me.initialConfig, value); fast.apply(me, value); else buffer.push(value); html = buffer.join(''); else if (fast.isArray(html) buffer.push(html.join(''); else buffer.

37、push(html); / private me.html = buffer.join(''); if (piled) pile(); , isTemplate: true, disableFormats: false, re: /(w-+)(?:(w.*)(?:(.*?)?)?)?/g, _apply: function(values) var me = this, useFormat = me.disableFormats != true, fm = fast.Format, tpl = me, ret; if (piled) return piled(values).jo

38、in(''); function fn(m, name, format, args) if (format && useFormat) if (args) args = valuesname.concat(fast.functionFactory('return '+ args +'')(); else args = valuesname; if (format.substr(0, 5) = "this.") return tplformat.substr(5).apply(tpl, args); else r

39、eturn fmformat.apply(fm, args); else return valuesname != undefined ? valuesname : "" ret = me.html.replace(me.re, fn); /ret = pile(ret); /console.log(ret); return ret; , /* * Appends the result of this template to the provided output array. * param Object/Array values The template values.

40、 See link #apply. * param Array out The array to which output is pushed. * return Array The given out array. */ _applyOut: function(values, out) var me = this; if (piled) out.push.apply(out, piled(values); else out.push(me.apply(values); return out; , apply: function(values) return this.applyOut(val

41、ues, ).join(''); , applyOut: function(values, out) var me = this; if (!me.fn) me.fn = pile(me.html); /console.log(me.fn); /console.log(values); out = me.fn(values); /這里玩的很精妙,以后有時間再分析一下 /console.log(me.fn); /try / me.fn.call(me, out, values, , 1, 1); / catch (e) /console.log(out); return out;

42、 , /* * method applyTemplate * member Ext.Template * Alias for link #apply. * inheritdoc Ext.Template#apply */ applyTemplate: function () return this.apply.apply(this, arguments); , /* * Sets the HTML used as the template and optionally compiles it. * param String html * param Boolean compile (optio

43、nal) True to compile the template. * return Ext.Template this */ set: function(html, compile) var me = this; me.html = html; piled = null; return compile ? pile() : me; , compileARe: /g, compileBRe: /(rn|n)/g, compileCRe: /'/g, /* * Applies the supplied values to the template and inserts the new

44、 node(s) as the first child of el. * * param String/HTMLElement/Ext.Element el The context element * param Object/Array values The template values. See link #applyTemplate for details. * param Boolean returnElement (optional) true to return a Ext.Element. * return HTMLElement/Ext.Element The new nod

45、e or Element */ insertFirst: function(el, values, returnElement) return this.doInsert('afterBegin', el, values, returnElement); , /* * Applies the supplied values to the template and inserts the new node(s) before el. * * param String/HTMLElement/Ext.Element el The context element * param Ob

46、ject/Array values The template values. See link #applyTemplate for details. * param Boolean returnElement (optional) true to return a Ext.Element. * return HTMLElement/Ext.Element The new node or Element */ insertBefore: function(el, values, returnElement) return this.doInsert('beforeBegin',

47、 el, values, returnElement); , /* * Applies the supplied values to the template and inserts the new node(s) after el. * * param String/HTMLElement/Ext.Element el The context element * param Object/Array values The template values. See link #applyTemplate for details. * param Boolean returnElement (optional) true to return a Ext.Element. * return HTMLElement/Ext.Element The new node or Element */ insertAfter: function(el, v

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論