摘要:當再次發生錯誤時,這將有助于更容易地解決問題如果正在編寫代碼,思考一下我不希望代碼拋出某種錯誤。
一、松耦合的一些建議我們認為,JavaScript的正確運行不應該依賴CSS-在缺少CSS情況下也要能夠正確運行,盡管兩者之間可能會有互動。
當你能夠做到修改一個組件而不需要更改其它組件的時候,你就做到了松耦合。
1、將JavaScript從CSS中抽出來(現在基本不會有如下的寫法)
.box{width: expression(document.body.offsetWidth + "px")} //不好的寫法
2、將CSS從JavaScript中抽離,利用增減class類名來控制樣式
element.style.color = "red"; //不好的寫法
3、將JavaScript從HTML抽離
上面的寫法在兩個UI層的深耦合,可能會出現用戶點擊的時候函數不存在的情形。或者,修改了doSomething之后,可能需要同時修改JavaScript和HTML代碼。利用DOM二級事件綁定時是更好的處理方法。
最好將所有的JavaScript代碼都放入外置文件中,以確保HTML代碼中不會有內聯的JavaScript代碼
4、將HTML從JavaScript中抽離
通常代碼中會出現這樣的寫法:
//不好的寫法 var div = document.getElementById("my-div"); div.innerHTML = "Error
invalid e-mail address
";
解決方法:
通過ajax,從服務器加載
利用客戶端模板
二、關于變量的一些建議全局變量所帶來的問題:
命名沖突
任何函數不經意間會修改全局變量,從而造成某處代碼出錯
難以測試
關于全局變量的一些解決tip:
所有變量都用var來定義,防止js不小心生成全局變量
避免意外的全局變量,利用jsLint來報警。推薦編輯器Bracket
使用嚴格模式來檢驗
使用單全局變量方式(單例模式)
三、事件處理的松耦合處理1、隔離應用層邏輯
//不好的寫法 function handleClick(event){ var popup = document.getElementById("popup"); popup.style.left = event.clientX + "px"; popup.style.top = event.clientY + "px"; } addEventListener(element, "click", handleClick);
上面的一段代碼看上去沒有任何的問題,但是邏輯層跟應用層耦合了。如果說其他的事件處理程序執行了同樣的程序。這樣多個事件的處理程序執行了同樣的邏輯,而你的代碼卻被不小心復制了多份。
修改之后:
//拆分應用層邏輯 var MyApplication = { handleClick:function(event){ this.showPopup(event); }, showPopup:function(event){ var popup = document.getElementById("popup"); popup.style.left = event.clientX + "px"; popup.style.top = event.clientY + "px"; } } addEventListener(element, "click", function(){ MyApplication.handleClick(event); });
看似多寫了幾行代碼,但更加好維護
2、不要分發事件對象e
上面代碼中定義的方法showPopup,每次調用需要傳入event對象,但是它只是用到了event其中的兩個屬性,其實可以通過值給其兩個明確的參數來改進代碼
//好的寫法 var MyApplication = { handleClick:function(event){ this.showPopup(event.clientX,event.clientY); }, showPopup:function(x, y){ var popup = document.getElementById("popup"); popup.style.left = x + "px"; popup.style.top = y + "px"; } } addEventListener(element, "click", function(){ MyApplication.handleClick(event); });
上面的代碼其實還有一個點可以優化:事件處理程序應當在進入應用邏輯之前針對event對象執行任何必要的操作,包括阻止默認事件或阻止事件冒泡都應當直接包含在事件處理程序中。如下:
var MyApplication = { handleClick:function(event){ //假設事件支持DOM level2 event.preventDefault(); event.stopPropagation(); //傳入應用層邏輯 this.showPopup(event.clientX,event.clientY); }, showPopup:function(x, y){ var popup = document.getElementById("popup"); popup.style.left = x + "px"; popup.style.top = y + "px"; } } addEventListener(element, "click", function(){ MyApplication.handleClick(event); });四、判斷語句中注意避免空比較
復習一下知識,檢測各類值的操作
1、檢測原始值(字符串、數字、布爾值、undefined):用typeof
2、檢測null:用===或!==來進行判斷(typeof null = "object")
3、檢測引用值:instanceof運算符
//檢測日期 if(value instanceof Date){ console.log("1") }
4、檢測函數:console.log(typeof myFunc === "function")
5、檢測數組:
鴨式辯型(具體解釋可以見犀牛書)
function isArray(value){ return typeof value.sort === "function" }
Kangax解決方法
function isArray(value){ return Object.prototype.toString.call(value) === "[object Array]"; }
ES5方法:Array.isArray
6、檢測屬性
我曾經寫過
//檢測假值 if(a[b]){...} //與null相比較 if(a[b] != null){...} //與undefined相比較 if(a[b] != undefined){...}
但是上面的寫法都不夠明確,都是通過給定的名字來檢查屬性的值,而非給定的名字所指的屬性是否存在,因此當屬性值為0,false,null,undefined會出錯
推薦下面的寫法:in運算符+hasOwnProperty
五、配置數據分離配置數據:應用中寫死的值
URL
需要展現給用戶的字符串
重復的值
設置(比如每頁的配置項)
任何可能發生變化的值
處理方式:
1、抽離配置數據,用多帶帶的變量存放,方便修改
2、保存配置數據:值得嘗試,將配置數據存放在非JavaScript文件中
JSON
JSONP
純JavaScript
六、錯誤拋出的方法1、拋出錯誤的方法:throw new Error("Something has happened")
2、拋出錯誤的經驗法則:
一旦修復了一個很難調試的錯誤,嘗試增加一個兩個自定義錯誤。當再次發生錯誤時,這將有助于更容易地解決問題
如果正在編寫代碼,思考一下:“我不希望代碼拋出某種錯誤”。這時,如果“某種錯誤發生”,就拋出一個錯誤
如果正在編寫的代碼別人也會使用,思考一下他們使用的方式,在特定的情況下拋出錯誤
3、try···catch語句
4、處理具體的錯誤類型
try { //有些代碼引發了錯誤 } catch (ex) { if(ex instanceof TypeError) { //處理TypeError錯誤 } else if(ex instanceof ReferenceError){ //處理Reference錯誤 } else { //其它處理 } }七、針對對象的處理
1、基于對象的繼承
var person = { name:"a", sayName:function(){ alert(this.name); } } var myPerson = Object.create(person); myPerson.sayName(); //彈出a
如果重新定義sayName方法,會自動切斷對person.sayName()的方法
myPerson.sayName = function(){ alert("b"); } myPerson.sayName();//彈出b person.sayName();//彈出a
Object.create()方法可以指定第二個參數,該參數對象中的屬性和方法將添加到新的對象中
var myPerson = Object.create(person,{ name:{ value:"Ge" } }); myPerson.sayName();//彈出Ge person.sayName();//彈出a
3、基于類型的繼承(兩步)
原型繼承
構造器繼承
function Person(name){ this.name;//屬性name實際上是由Person類管理 } function Author(name){ //繼承構造器 Person.call(this,name);//允許Person構造器繼續定義該屬性。Person構造器是在this上執行的,this指向一個Author對象,所以最終的name定義在這個Author對象上面 } Author.prototype = new Person();八、瀏覽器嗅探
1、user-Agent檢測
//不好的做法但是是通常的做法 if(navigator.userAgent.indexOf("MSIE") > -1) { //是Internet Explorer } else { //不是Internet Explorer }
瀏覽器的發展使得字符串檢測的用戶體驗越來越差,最佳的方法是只檢測舊的瀏覽器,比如IE8和之前的版本而不要試圖檢測IE9和更高版本
if( isInternetExplorer8OrEalier ){ //處理IE8以及更早版本 } else { //處理其它瀏覽器 }
參考資料:《編寫可維護的JavaScript》
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78735.html
摘要:從社區和過往的經驗而言異步編程的難題已經基本解決無論是通過事件還是通過模式或者流程控制庫。本章主要介紹了主流的幾種異步編程解決方案這是目前中主要使用的方案。最后因為人們總是習慣性地以線性的方式進行思考以致異步編程相對較為難以掌握。 前言 如果你想要深入學習Node,那你不能錯過《深入淺出Node.js》這本書,它從不同的視角介紹了 Node 內在的特點和結構。由首章Node 介紹為索引...
摘要:與響應不同的是,身份驗證并不能提供任何幫助,而且這個請求也不應該被重復提交。 JavaScript中幾個最重要的大知識點 面向對象 DOM事件 異步交互ajax AJAX AJAX是異步的javascript和xml(Asynchronous Javascript And XML)的縮寫,用于網頁局部刷新,提升用戶瀏覽體驗 通常前端程序員關于AJAX的掌握僅僅停留在會用AJAX發送...
閱讀 4624·2021-09-26 09:55
閱讀 1367·2019-12-27 12:16
閱讀 887·2019-08-30 15:56
閱讀 1905·2019-08-30 14:05
閱讀 992·2019-08-30 13:05
閱讀 1269·2019-08-30 10:59
閱讀 1442·2019-08-26 16:19
閱讀 1887·2019-08-26 13:47