原文:http://lea.verou.me/2015/04/jquery-considered-harmful/**
(第一次翻譯,望你們多批評指正)javascript
嗨,我總想寫一個「X」是有害的帖子。前端
在開始寫前,我想說jquery 很大程度上促進了前端的發展。它讓開發人員實現了之前不敢想象的事情,並促使瀏覽器開發商作他們原本就該作的事。(沒有jquery咱們估計如今還不可能用到document.querySelectorAll)對於那些不支持現有新技術的IE8及其如下瀏覽器jQuery依然頗有必要。java
但不管怎麼說那些低端瀏覽器畢竟是少數,不少開發人員不須要支持只佔很小份額的老版本瀏覽器。別忘了還有那些非專業開發人員:學生和研究人員,他們不只不須要支持低版本瀏覽器,並且只需一個瀏覽器支持就夠了。如您所願,在學術界人人都津津樂道於使用網絡開放平臺的新技術,對吧?然而我卻從未見過jQuery在業界這麼突出。爲何?由於衆所周知,他們沒有時間或興趣追隨網絡開放平臺的最新動態。他們不知道他們須要什麼樣的jquery,致使他們只是單純的使用jquery。然而這並非我拋棄jquery的惟一理由。jquery
我固然不是第一個指出jQuery的依賴程度影響你原生js的能力,所以我不想浪費時間重複別人以前所寫,你只需訪問如下連接:api
你不須要jquery!瀏覽器
...還有不少,你只需谷歌一下「you don’t need jQuery」你將發現更多。我也再也不花時間贅述jQuery文件大小以及原生js方法有多高效,這些我以前都講過。今天,我想說一個不常被說起的要點。函數
爲了不擴展本地元素的原型,jquery使用它本身的包裝對象,擴展本地對象在過去是一個龐大的 不,不。不只由於潛在衝突,還有低版本IE瀏覽器內存泄漏。所以當你運行$(「div」)時返回的並非一個元素引用或一個節點集合而是一個jQuery對象。這意味着對於,jquery對象的實現方式徹底不一樣於一個DOM元素的引用、一個數組或其餘類型的節點列表。然而,對於這些本地對象,就像jquery試圖提取出他們同樣,你總要不得不處理他們,哪怕他們包裝在$()中。例如:當回掉函數經過jQuery的bind()方法調用時上下文就是一個對HTML元素的引用而不是jquery的一組對象。更別提你的代碼仍是多源的,有些想固然是jQuery代碼,有些則不是,最終代碼總會混淆着jQuery對象、本地對象、節點列表,而這正是地獄的開始。
若是開發人員遵循一個命名規則:用變量包裹jQuery對象(我認爲在變量名頭部添加一個$是常見的一種)和本地元素,這將再也不是個問題(但人們老是記不住規則,這裏就先假定一個理想世界)然而,現實中並無那麼多規則被遵照,結果就是對於不熟悉代碼的人來講代碼變得極其難懂。如今每一次編寫代碼都須要不少嘗試和錯誤(「哦!這不是一個jQuery對象,我要用$()來包裹它」或者「哦!這不是一個元素,我要用[0]來獲取其中的元素」) 爲了不混淆,開發人員編碼時常防護性的用$()包裹全部東西,所以總覽代碼,相同的變量通過$()的多重包裹,一樣的緣由,這會變得很難重構其餘jQuery代碼,你徹底被困住了。
即便遵循了命名規則,也不能只用在jQuery對象上,你常常須要用到本地DOM方法或調用不屬於jQuery而來自其於他腳本中的函數。很快,屢次折騰jQuery對象弄獲得處都是,把你的代碼搞的很亂。
除此以外,當你往代碼庫中添加代碼的時候,你每每會用$()來包裹每一個元素或節點列表。由於你不知道你獲得了什麼樣的輸入。因此被困住的不只僅是你本身,你之後爲同一個代碼庫所寫的代碼也被困住了。
得到任何帶有jQuery依賴性的隨機腳本,你沒有本身寫並試圖重構它,這樣它就不須要jQuery。我敢說,你會發現你的主要問題將不會是如何轉換功能使用本地APIs, 而是理解這究竟是怎麼一回事。
固然,如今許多函數庫須要jQuery,就像最近我在推特上所說的那樣,若是你迴避jQuery那麼感受你像是個數碼素食者。固然,這並不意味着你必需要使用它。當好的非jQuery代替品可用的時候,函數庫也將會被取代。
一樣的,大多數函數庫的寫法不須要用$做爲jQuery的別名。用jQuery.noConflict()方法可更改默認的$而且你也可改爲其餘你看着順眼的符號,例如,受命令行API的啓發,我常常定義這些幫助函數:
//返回匹配到expr的第一個元素 //查詢範圍限制在container的後代中 function $(expr, container) { return typeof expr === "string"? (container || document).querySelector(expr) : expr || null; } //以數組的形式返回全部匹配到的expr //查詢範圍限制在container的後代中 function $$(expr, container) { return [].slice.call((container || document).querySelectorAll(expr)); }
此外,我認爲在你每次敲出jQuery來代替$時你會考慮若是真的不須要,是否還要這麼過分的使用它,或許我猜錯了 。
同時,若是你喜歡jquery API 但又不喜歡他的臃腫,那麼你能夠考慮使用Zepto。
很明顯,咱們的標題顯而易見帶有開玩笑的意味,可是,這是互聯網,沒有什麼是顯而易見的。因此在這裏我很清楚Eric的經典文章會很反對這種標題。