[英]When to use Vanilla JavaScript vs. jQuery?
我注意到在監控/嘗試回答常見的jQuery問題時,有一些使用javascript而不是jQuery的實踐,實際上可以讓你寫得更少,並做 ...相同的數量。 並且還可以產生性能優勢。
一個具體的例子
$(this)
vs this
在單擊事件中引用單擊的對象id
jQuery的
$(this).attr("id");
使用Javascript
this.id;
還有其他類似的常見做法嗎? 可以更輕松地完成某些Javascript操作,而無需將jQuery添加到組合中。 或者這是一個罕見的情況? (jQuery“快捷方式”實際上需要更多代碼)
編輯:雖然我很欣賞有關jQuery與普通javascript性能的答案,但實際上我正在尋找更多的定量答案。 在使用jQuery時 ,使用普通javascript代替使用$()
實際上會更好(可讀性/緊湊性)的實例。 除了我在原始問題中給出的例子。
this.id
(如你所知) this.value
(在大多數輸入類型上。當<select>
沒有在其<option>
元素上設置value
屬性或Safari中的無線電輸入時,我知道的唯一問題是IE。) this.className
獲取或設置整個“class”屬性 this.selectedIndex
對<select>
獲取所選索引 this.options
針對<select>
獲取<option>
元素列表 this.text
反對<option>
獲取其文本內容 this.rows
針對<table>
獲取<tr>
元素的集合 this.cells
反對<tr>
獲取其單元格(td&th) this.parentNode
獲取直接父級 this.checked
以獲取checkbox
的選中狀態謝謝@Tim Down this.selected
得到一個option
的選擇狀態謝謝@Tim Down this.disabled
獲取input
的禁用狀態謝謝@Tim Down this.readOnly
獲取input
的readOnly狀態謝謝@Tim Down this.href
針對<a>
元素獲取其href
this.hostname
對<a>
元素獲取其href
的域 this.pathname
針對<a>
元素獲取其href
的路徑 this.search
針對<a>
元素獲取其href
的查詢字符串 this.src
對一個有src
的元素 ...我想你應該已經明白了。
有時性能至關重要。 就像你在循環中多次執行某些操作一樣,你可能想拋棄jQuery。
一般來說,您可以替換:
$(el).attr('someName');
有:
上面的措辭很差。 getAttribute
不是替換,但它確實檢索從服務器發送的屬性的值,並且其對應的setAttribute
將設置它。 在某些情況下是必要的。
下面的句子有點覆蓋它。 請參閱此答案以獲得更好的治療。
el.getAttribute('someName');
...以便直接訪問屬性。 請注意,屬性與屬性不同(盡管它們有時會互相鏡像)。 當然也有setAttribute
。
假設你遇到一個情況,你需要打開一個頁面,你需要打開某個類型的所有標簽。 使用jQuery簡單易行:
$('span').unwrap(); // unwrap all span elements
但是如果有很多,你可能想做一些原生的DOM API:
var spans = document.getElementsByTagName('span');
while( spans[0] ) {
var parent = spans[0].parentNode;
while( spans[0].firstChild ) {
parent.insertBefore( spans[0].firstChild, spans[0]);
}
parent.removeChild( spans[0] );
}
此代碼非常簡短,它的性能優於jQuery版本,並且可以輕松地在您的個人庫中實現可重用的功能。
看起來我有一個無限循環與外部while
因為while(spans[0])
,但因為我們正在處理一個“實時列表”,它會在我們執行parent.removeChild(span[0]);
時更新parent.removeChild(span[0]);
。 這是一個非常漂亮的功能,我們在使用Array(或類似Array的對象)時錯過了這個功能。
正確的答案是,在使用jQuery而不是“普通舊”本機JavaScript時,您總是會受到性能損失。 那是因為jQuery是一個JavaScript庫。 它不是一些奇特的新版JavaScript。
jQuery功能強大的原因在於它在跨瀏覽器的情況下會產生一些過於繁瑣的東西(AJAX是最好的例子之一),並且平滑了無數可用瀏覽器之間的不一致性並提供了一致的API。 它還可以輕松地促進諸如鏈接,隱含迭代等概念,以簡化對元素組的處理。
學習jQuery不能替代學習JavaScript。 你應該在后者中有一個堅實的基礎,這樣你才能完全理解前者對你更容易的了解。
- 編輯包含評論 -
由於評論很快指出(我同意100%),上述陳述是指基准代碼。 一個“本機”JavaScript解決方案(假設編寫得很好)將勝過jQuery解決方案,幾乎在所有情況下都能完成同樣的事情(我很樂意看到一個例子)。 jQuery確實加快了開發時間,這是一個重要的好處,我並不打算淡化。 它易於閱讀,易於遵循代碼,這比一些開發人員能夠自己創建的更多。
在我看來,答案取決於你想要實現的目標。 如果,正如我根據您對性能優勢的引用所假設的那樣,您可以在應用程序之后獲得最佳速度,那么每次調用$()
時使用jQuery都會引入開銷。 如果您想要提高可讀性,一致性,跨瀏覽器兼容性等,那么肯定有理由支持jQuery優於“本機”JavaScript。
有一個框架叫做......哦,猜怎么着? Vanilla JS
。 希望你得到這個笑話......:D它犧牲了代碼的易讀性......與jQuery
相比,你可以看到通過ID
檢索DOM
元素的速度提高了近35倍。 :)
因此,如果你想要表現,你最好嘗試Vanilla JS並得出你自己的結論。 也許你不會遇到JavaScript掛起瀏覽器的GUI /在強化代碼中鎖定UI線程,比如在for
循環中。
Vanilla JS是一個快速,輕量級的跨平台框架,用於構建令人難以置信的強大JavaScript應用程序。
在他們的主頁上有一些性能比較:
已經有一個已接受的答案,但我相信這里沒有直接輸入的答案可以在其原生javascript方法/屬性列表中全面,這些方法/屬性實際上保證了跨瀏覽器支持。 為此,我可以將您重定向到quirksmode:
http://www.quirksmode.org/compatibility.html
它可能是最全面的列表,其中包含哪些有效,哪些無效。 特別注意DOM部分。 要閱讀的內容很多,但重點不在於閱讀全部內容,而是將其作為參考。
當我開始認真地編寫Web應用程序時,我打印出所有DOM表並將它們掛在牆上,這樣我就可以一眼就知道什么是安全的,什么需要黑客攻擊。 這些天我只是有點像quirksmode parentNode compatibility
東西,當我有疑慮。
像其他任何事情一樣,判斷主要是經驗問題。 我不會真的建議你閱讀整個網站並記住所有問題,以確定何時使用jQuery以及何時使用普通JS。 請注意清單。 搜索很容易。 隨着時間的推移,你會發展出一種當普通JS更受歡迎的本能。
PS:PPK(該網站的作者)也有一本非常好的書我推薦閱讀
什么時候:
使用JavaScript。 否則使用jQuery(如果可以的話)。
編輯 :這個答案適用於選擇使用jQuery整體而不是將其遺漏,以及選擇是否在jQuery中使用vanilla JS。 選擇attr('id')
和.id
傾向於支持JS,同時在removeClass('foo')
和.className = .className.replace( new Regexp("(?:^|\\\\s+)"+foo+"(?:\\\\s+|$)",'g'), '' )
傾向於支持jQuery。
其他人的回答集中在“jQuery vs.普通JS”的廣泛問題上。 從您的OP來看,我認為您只是想知道如果您已經選擇使用jQuery,最好使用vanilla JS。 您的示例是何時應該使用vanilla JS的完美示例:
$(this).attr('id');
是慢還是(在我看來)可讀性低於:
this.id
它的速度較慢,因為你必須啟動一個新的JS對象,只是為了以jQuery的方式檢索屬性。 現在,如果你打算使用$(this)
來執行其他操作,那么無論如何,將jQuery對象存儲在變量中並使用它進行操作。 但是,我遇到了許多需要元素屬性的情況(比如id
或src
)。
還有其他類似的常見做法嗎? 可以更輕松地完成某些Javascript操作,而無需將jQuery添加到組合中。 或者這是一個罕見的情況? (jQuery“快捷方式”實際上需要更多代碼)
我認為最常見的情況是你在帖子中描述的情況; 人們不必要地在jQuery對象中包裝$(this)
。 我經常看到id
和value
(而不是使用$(this).val()
)。
編輯: 這里的解釋了為什么在使用jQuery的文章attr()
情況下慢。 懺悔:從標簽維基中偷走它,但我認為這個問題值得一提。
再次編輯:鑒於直接訪問屬性的可讀性/性能影響,我會說一個好的經驗法則可能是嘗試使用this.<attributename>
。 可能有些情況下由於瀏覽器的不一致而無法正常工作,但是如果它不起作用,最好先嘗試這個並回到jQuery上。
如果你最關心的是表現,那么你的主要例子就會擊中頭部。 不必要地或冗余地調用jQuery是,恕我直言,性能緩慢的第二個主要原因(第一個是糟糕的DOM遍歷)。
這不是真的你正在尋找一個例子,但我看到這個如此頻繁,它蘊藏着提:其一,以加快您的jQuery腳本性能的最好方法是緩存jQuery的對象,和/或使用鏈接:
// poor
$(this).animate({'opacity':'0'}, function() { $(this).remove(); });
// excellent
var element = $(this);
element.animate({'opacity':'0'}, function() { element.remove(); });
// poor
$('.something').load('url');
$('.something').show();
// excellent
var something = $('#container').children('p.something');
something.load('url').show();
我發現JS和JQ之間肯定存在重疊。 您展示的代碼就是一個很好的例子。 坦率地說,使用JQ而不是JS的最佳理由就是瀏覽器兼容性。 我總是傾向於JQ,即使我可以在JS中完成某些事情。
這是我個人的觀點,但是無論如何jQuery都是JavaScript,我認為理論上它不能比vanilla JS表現更好。
但實際上它可能比手寫JS更好,因為一個人的手寫代碼可能沒有jQuery那么高效。
底線 - 對於較小的東西我傾向於使用vanilla JS,對於JS密集型項目我喜歡使用jQuery而不是重新發明輪子 - 它也更有效率。
的第一個答案的實時屬性列表this
是一個DOM元素還是比較齊全的。
你可能會發現其他人也很有趣。
當這是文件時:
this.forms
獲取當前文檔表單的HTMLCollection
, this.anchors
得到一個HTMLCollection
所有的HTMLAnchorElements
與name
被設置, this.links
得到一個HTMLCollection
所有的HTMLAnchorElement
s的href
存在集, this.images
得到一個HTMLCollection
的所有HTMLImageElement
小號 this.applets
一樣,棄用的applet也是this.applets
使用document.forms
, document.forms[formNameOrId]
將獲得如此命名或標識的表單。
當這是一個形式:
this[inputNameOrId]
來獲取如此命名或標識的字段 當這是表單字段時:
this.type
獲取字段類型 在學習jQuery選擇器時,我們經常跳過學習已經存在的HTML元素屬性,這些屬性的訪問速度非常快。
像往常一樣,我遲到了這個派對。
這並不是讓我決定使用jQuery的額外功能,就像那樣有吸引力。 畢竟沒有什么能阻止你編寫自己的功能。
事實上,在修改DOM以避免內存泄漏時需要學習很多技巧(我在談論你的IE)。 有一個中央資源為我管理所有這些問題,由那些比我以前更好的JS編碼人員寫的,正在不斷審查,修改和測試的是上帝發送。
我猜這種情況屬於跨瀏覽器支持/抽象參數。
當然,jQuery並不排除在需要時使用直接JS。 我總覺得這兩個似乎無縫地協同工作。
當然,如果jQuery不支持您的瀏覽器,或者您支持低端環境(舊手機?),那么大型.js文件可能會出現問題。 還記得jQuery過去很小嗎?
但通常情況下,性能差異不是一個值得關注的問題。 它只需要足夠快。 隨着Gigahertz的CPU周期每秒都在浪費,我更關心的是我的編碼器的性能,這是唯一一個每18個月不會增加一倍功率的開發資源。
這就是說我目前正在研究可訪問性問題,顯然.innerHTML對此有點不對。 jQuery當然取決於.innerHTML,所以現在我正在尋找一個框架,它將取決於允許的有些繁瑣的方法。 我可以想象這樣一個框架會比jQuery運行得慢,但只要它表現得足夠好,我就會高興的。
這是一個非技術性的答案 - 許多工作可能不允許某些庫,例如jQuery。
事實上,事實上,谷歌不允許在他們的任何代碼中使用jQuery(也不是React,因為它由Facebook擁有),在面試官說“對不起,但你不能使用jQuery,它不是XYZ公司批准的名單“。 Vanilla JavaScript每次都可以在任何地方使用,並且永遠不會給你這個問題。 如果你依賴圖書館是的,你會得到速度和輕松,但你失去了普遍性。
另外,談到面試,另一個缺點是,如果你說你需要使用一個庫來解決代碼測驗中的JavaScript問題,那就會發現你實際上並沒有理解這個問題,這看起來有點糟糕。 然而,如果你用原始的vanilla JavaScript解決它,它表明你實際上理解並且可以解決他們面前拋出的任何問題的每一部分。
$(this)
與this
不同:
通過使用$(this)
您可以確保將jQuery原型傳遞給對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.