摘要:圖對可復用代碼挑戰最大的五項問題五大開發問題如下。瀏覽器的缺陷修復。瀏覽器缺失的功能。復雜的地方是,當前瀏覽器會在未來的瀏覽器版本中被修復。假設瀏覽器引起常見的網站問題為解決瀏覽器使用特殊技巧,將來瀏覽器發布新版本修復了,就會出現問題。
任意一段重要的代碼都需要關注無數的開發問題。但是,其中對可復用JavaScript代碼挑戰最大的五項問題如圖14.2所示。
圖14.2 對可復用JavaScript代碼挑戰最大的五項問題
五大開發問題如下。
瀏覽器缺陷。
瀏覽器的缺陷修復。
外部代碼。
瀏覽器回歸。
瀏覽器缺失的功能。
我們需要權衡解決這些問題所花費的時間與得到的收益。這些是不得不回答的問題。你分析潛在受眾、開發資源、開發排期等,這些都是決定性因素。
當試圖開發可復用的JavaScript代碼,我們需要考慮所有的因素,還需要考慮目前最流行的瀏覽器,因為這些瀏覽器是我們的目標受眾最可能使用的瀏覽器。其他不那么流行的瀏覽器,我們至少保證代碼可以優雅降級。例如,如果一個瀏覽器不支持某API,我們應該小心我們的代碼不會拋出任何異常,這樣剩下的代碼仍然可以順利執行。
在接下來的小節中,我們將講解這些問題,以便更好地理解我們面對的挑戰以及如何應對。
1 瀏覽器的bug和差異當我們開發可復用性JavaScript代碼時,需要考慮解決的問題之一是處理我們確定需要兼容的多種瀏覽器bug以及API的差異。盡管瀏覽器越來越標準化,但是代碼還是必須得完全符合瀏覽器提供的特性。
實現這一目標的方法很直接:我們需要完整的測試工具,足以覆蓋代碼常用的和不常用的用例。充分測試之后,在知道開發的代碼將在支持的瀏覽器中工作后,我們會感到安全。假設瀏覽器沒有后續變化,不會打破向后兼容性,我有一個模糊的預感,代碼甚至會在未來版本的瀏覽器中工作。在14.3節中,我們會觀察特定的策略來處理瀏覽器bug和差異。
復雜的地方是,當前瀏覽器bug會在未來的瀏覽器版本中被修復。
2 瀏覽器的bug修復瀏覽器永遠存在特定的錯誤是很愚蠢的——大部分瀏覽器bug最終都會修復,把希望寄托在瀏覽器bug上是很危險的開發策略。最佳方式是使用14.3節中的技術,使用不會過時的變通方案。
在編寫一個可重用的JavaScript代碼時,我們希望它可以持續運行很長時間。編寫任何方面的網站(CSS、HTML等),瀏覽器發布新版本后,我們不希望再回去修復代碼。
假設瀏覽器bug引起常見的網站問題:為解決瀏覽器bug使用特殊技巧,將來瀏覽器發布新版本修復了bug,就會出現問題。
處理瀏覽器漏洞的問題是雙重的:
當bug最終被修復,我們的代碼容易損壞。
我們無法為了避免網站損壞而說服瀏覽器廠商不修復bug。
最近恰好發生了第2種情況的有趣的事例,關于scrollTop的bug(https://dev.opera.com/article...)。
當處理HTML DOM時,可以使用scrollTop和scrollLeft屬性,修改當前元素的滾動位置。但是當我們對根元素使用這些屬性時,根據規范,將會返回滾動的位置,IE11與Firefox瀏覽器嚴格遵循了這則規范。而Safari、Chrome和Opera并沒有遵守。如果試圖修改根元素的滾動位置時,不會發生任何事情。為了實現相同的效果,我們只能在body元素上使用scrollTop和scrollLeft屬性。
當面對瀏覽器的不一致性時,Web開發者們常常檢測當前瀏覽器的名字(通過用戶代理字符串,后續會詳細介紹),然后在IE11和Firefox上對HTML元素使用scrollTop和scrollLeft屬性,而在Safari、Chrome和Opera上則對body元素使用scrollTop和scrollLeft屬性。規避這類問題將會造成災難性后果。因為許多網頁明確編碼指定在Safari、Chrome或Opera上使用body元素,這些瀏覽器無法真正修復這個bug,因為一旦修復,許多網頁都無法運行。
這引出了另一個關于bug的觀念:在確定某一功能是否是潛在的錯誤時,使用規范進行驗證!
瀏覽器的bug不同于未指明的API。參考瀏覽器規范非常重要,因為規范提供了確切的標準,瀏覽器使用這些標準進行開發和完善代碼。相比之下,一個未指明的API的實現可能會在任何時候發生改變(特別是試圖成為標準化的實現)。在未指明的API不一致的情況下,你應該對預期輸出進行測試。警惕這些API未來可能發生的變化。
另外,bug修復和API的變化是有區別的。bug修復是很容易預見的——瀏覽器最終將修復bug,即使要花很長的時間,API變化更難發現。標準API不太可能改變,盡管不是完全聞所未聞,變化更有可能出現未指明的API中。
幸運的是,大多數Web應用程序出問題的情況很少發生。萬一出現問題,有效地提前預知是無效的辦法(除非我們逐一測試相關的API——但是這樣一個過程的開銷是可怕的)。這種API的變化應該做回歸處理。
下一個需要關心的問題是,沒有人是一座孤島,我們的代碼也不是,讓我們研究代碼的影響范圍。
3 外部代碼和標記任何可重用代碼必須與圍繞它的代碼共存。我們希望代碼運行在自己編寫的網站或是他人開發的網站上,我們都需要確保代碼可以與其他代碼共存。
這是一把雙刃劍:我們的代碼不僅必須能夠經受住可能寫得很遭的外部代碼,還必須得克服環境對代碼的不利影響。
我們需要警惕的程度很大程度上取決于所使用的代碼對環境的關注。例如,如果我們僅為單個或有限個網站編寫可重用的代碼,在某種程度上可以控制,可以少一些擔心,因為我們知道代碼的運行對外部代碼的影響程序,而且一旦有問題,我們可以自行修復。
{注意 }這個問題的重要程度足以用一本書來闡述。如果你想更深入地探究,我們強烈推薦Ben Vinegar 和 Anton Kovalyov 編寫的《第三方JavaScript》一書(Manning, 2013, https:// www.manning.com/books/third-party-javascript)。
如果開發代碼將廣泛用于未知環境(不可控的)中,則我們需要雙重確認代碼的健壯性。接下來討論一些實現代碼健壯性的策略。
代碼封裝為了避免我們的代碼影響頁面上的其他代碼,最佳實踐是使用封裝。通常來說,封裝指代碼(如同)存放在容器里。從廣義上來說,是一種限制訪問其他對象組件的語言機制。Aunt Mathilda也許會總結為“各人自掃門前雪,莫管他人瓦上霜”。
在頁面上引入我們的代碼時,盡可能少地影響全局代碼,將會使Aunt Mathilda非常開心。事實上,盡可能少地使用全局變量,甚至最好僅限一個,是很容易的。
第12章中的jQuery,它是最流行的客戶端JavaScript庫,也是最好的范例。jQuery引入一個名為jQuery的全局變量(一個函數),別名為$,它甚至允許其他網頁為$設置別名避免沖突。
jQuery中幾乎所有的操作都通過jQuery函數完成。其他函數(工具函數)被定義為jQuery的屬性(第3章介紹如何將函數定義為另一個函數的屬性),使用jQuery作為命名空間。我們可以使用相同的策略。假設我們需要定義一組函數,我們將其定義在命名空間ninja下。
與jQuery類似,我們可以定義名為ninja()的全局函數以操作傳入的變量。例如:
var ninja = function(){ /* implementation code goes here */ }
使用我們設定好的命名空間定義工具函數:
ninja.hitsuke = function(){ /* code to distract guards with fire here */ }
如果我們不需要ninja作為函數,僅作為一個命名空間即可,我們可以使用如下定義方式:
var ninja = {};
創建空對象,隨后在該對象上定義屬性或方法即可。為了保證代碼的封裝,需要避免其他操作,如修改已經存在的變量、函數原型甚至DOM元素。修改我們自己代碼之外的任何內容,都可能引起潛在的沖突和混淆。另外,盡管我們小心翼翼地嚴格遵守最佳實踐封裝代碼,但我們仍然無法保證代碼的行為。
模范代碼有一個老笑話Grace Hopper在Cretaceous時期為接替人員清除蛀蟲時說:“你最不惡心的代碼就是你自己寫的代碼。”看起來很諷刺,但是當我們的代碼與不可控的代碼同時運行時,為了安全起見,我們需要假設最糟的情況。
盡管一些代碼編寫工整,但也有可能潛在地做一些出乎意料的事,例如修改函數屬性、對象屬性和DOM元素的方法。這些都可能設有陷阱。
在這種情況下,我們的代碼只能做一些無傷大雅的事,例如使用JavaScript數組,一般情況下JavaScript數組只能是JavaScript數組。但是,如果一些頁面上修改了數組的行為,我們的代碼將無法運行,當然不是我們自身的原因。
遺憾的是,處理這種問題沒有固定的原則標準,但是我們可以采取一些措施。我們將在后續小節中介紹保護性方法。
應對ID濫用大部分瀏覽器具有一些反特性(我們不能稱之為bug,因為這些特性是有意而為之),這些特性會使得代碼不可預期地落入陷阱從而運行失敗。這些特性使得原始元素與添加在元素上的id或name屬性產生關聯。但是當id或name屬性與元素上已經存在的部分屬性產生沖突時,就會發生一些意料之外的情況。
查看以下HTML代碼片段,觀察id屬性的濫用:
現在,在瀏覽器中可以這樣調用:
var what = document.getElementById("form").action;
我們期望返回合理的form的action屬性。大部分情況下是可以返回的。但是當檢查值的時候你會發現,返回的卻是input#action元素。為什么?讓我們試試其他元素:
document.getElementById("form").submit();
這條語句本應引起form提交,但是卻返回script錯誤:
Uncaught TypeError: Property "submit" of object #is not a function
發生了什么呢?
瀏覽器將
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/109397.html
目錄 一、禪道 一、測試工具背景 二、測試管理工具 三、測試工具介紹 四、禪道介紹 五、禪道操作 7. 創建發布 8. 測試團隊 二、缺陷報告 三、測試報告 一、概要 二、測試過程 三、缺陷分析 四、測試總結 四、接口測試以及用例編寫 五、Fiddler 好文推薦 一、禪道 一、測試工具背景 當測試環境搭建完成后,測試人員將在自己搭建的環境上執行測試用例,開展測試工作。測試人員在執行測試用例的過...
摘要:如果數據從舊系統遷移到新系統是當前版本發布的主要目的,那么更要關注報表數據數據遷移缺陷如果一個舊系統要被新系統取代,舊系統里的數據要移到新系統。 對任何軟件產品來說,軟件上線永遠是一件大事。完全確保所有功能生效以及發布高質量軟件給用戶非常重要。 不好的、不成熟的、不穩定的、難以使用的產品會引...
閱讀 585·2023-04-25 21:29
閱讀 1112·2023-04-25 21:27
閱讀 1053·2021-11-25 09:43
閱讀 1088·2021-09-29 09:43
閱讀 3624·2021-09-03 10:30
閱讀 2863·2019-08-29 15:26
閱讀 2811·2019-08-29 12:52
閱讀 1751·2019-08-29 11:10