何时使用 Vanilla JavaScript 与 jQuery?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4651923/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use Vanilla JavaScript vs. jQuery?
提问by jondavidjohn
I have noticed while monitoring/attempting to answer common jQuery questions, that there are certain practices using javascript, instead of jQuery, that actually enable you to write less and do... well the same amount. And may also yield performance benefits.
我在监视/尝试回答常见的 jQuery 问题时注意到,有一些使用 javascript 而不是 jQuery 的实践,实际上使您能够编写更少的内容并做……同样的数量。并且还可能产生性能优势。
A specific example
一个具体的例子
$(this)
vs this
$(this)
对比 this
Inside a click event referencing the clicked objects id
在引用被点击对象 id 的点击事件中
jQuery
jQuery
$(this).attr("id");
Javascript
Javascript
this.id;
Are there any other common practices like this? Where certain Javascript operations could be accomplished easier, without bringing jQuery into the mix. Or is this a rare case? (of a jQuery "shortcut" actually requiring more code)
还有其他类似的常见做法吗?某些 Javascript 操作可以更轻松地完成,而无需将 jQuery 混入其中。或者这是一个罕见的案例?(实际上需要更多代码的jQuery“快捷方式”)
EDIT :While I appreciate the answers regarding jQuery vs. plain javascript performance, I am actually looking for much more quantitative answers. While using jQuery, instances where one would actually be better off (readability/compactness) to use plain javascript instead of using $()
. In addition to the example I gave in my original question.
编辑:虽然我很欣赏有关 jQuery 与普通 javascript 性能的答案,但实际上我正在寻找更多定量的答案。 在使用 jQuery 时,使用纯 javascript 而不是使用$()
. 除了我在原始问题中给出的示例之外。
采纳答案by user113716
this.id
(as you know)this.value
(on most input types. only issues I know are IE when a<select>
doesn't havevalue
properties set on its<option>
elements, or radio inputs in Safari.)this.className
to get or set an entire "class" propertythis.selectedIndex
against a<select>
to get the selected indexthis.options
against a<select>
to get a list of<option>
elementsthis.text
against an<option>
to get its text contentthis.rows
against a<table>
to get a collection of<tr>
elementsthis.cells
against a<tr>
to get its cells (td & th)this.parentNode
to get a direct parentthis.checked
to get the checked state of acheckbox
Thanks @Tim Downthis.selected
to get the selected state of anoption
Thanks @Tim Downthis.disabled
to get the disabled state of aninput
Thanks @Tim Downthis.readOnly
to get the readOnly state of aninput
Thanks @Tim Downthis.href
against an<a>
element to get itshref
this.hostname
against an<a>
element to get the domain of itshref
this.pathname
against an<a>
element to get the path of itshref
this.search
against an<a>
element to get the querystring of itshref
this.src
against an element where it is valid to have asrc
this.id
(如你所知)this.value
(在大多数输入类型上。我知道的唯一问题是当 a的元素上<select>
没有value
设置属性时的 IE<option>
,或 Safari 中的无线电输入。)this.className
获取或设置整个“类”属性this.selectedIndex
针对 a<select>
获取所选索引this.options
针对 a<select>
获取<option>
元素列表this.text
针对 an<option>
获取其文本内容this.rows
针对 a<table>
获取<tr>
元素集合this.cells
针对 a<tr>
获取其单元格 (td & th)this.parentNode
得到一个直接的父母this.checked
获得感谢@Tim Down的检查状态checkbox
this.selected
获得感谢@Tim Down的选定状态option
this.disabled
获得感谢@Tim Down的禁用状态input
this.readOnly
获得感谢@Tim Down的只读状态input
this.href
针对一个<a>
元素来获取它的href
this.hostname
针对一个<a>
元素来获取其域href
this.pathname
针对一个<a>
元素来获取其路径href
this.search
针对一个<a>
元素获取其查询字符串href
this.src
针对一个元素是有效的src
...I think you get the idea.
...我想你应该已经明白了。
There will be times when performance is crucial. Like if you're performing something in a loop many times over, you may want to ditch jQuery.
有时性能至关重要。就像如果您在循环中多次执行某些操作一样,您可能想要放弃 jQuery。
In general you can replace:
一般来说,您可以替换:
$(el).attr('someName');
$(el).attr('someName');
with:
和:
Above was poorly worded. getAttribute
is not a replacement, but it does retrieve the value of an attribute sent from the server, and its corresponding setAttribute
will set it. Necessary in some cases.
以上措辞不好。getAttribute
不是替代品,但它确实检索从服务器发送的属性的值,并且其对应的setAttribute
将设置它。在某些情况下是必要的。
The sentences below sort of covered it. See this answerfor a better treatment.
下面的句子几乎涵盖了它。请参阅此答案以获得更好的治疗。
el.getAttribute('someName');
...in order to access an attribute directly. Note that attributes are not the same as properties (though they mirror each other sometimes). Of course there's setAttribute
too.
...为了直接访问属性。请注意,属性与属性不同(尽管它们有时会相互反映)。当然也有setAttribute
。
Say you had a situation where received a page where you need to unwrap all tags of a certain type. It is short and easy with jQuery:
假设您收到了一个页面,您需要打开某个类型的所有标签。jQuery 简短易行:
$('span').unwrap(); // unwrap all span elements
But if there are many, you may want to do a little native DOM API:
但是如果有很多,你可能想要做一点原生 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] );
}
This code is pretty short, it performs better than the jQuery version, and can easily be made into a reusable function in your personal library.
这段代码很短,它的性能比 jQuery 版本更好,并且可以很容易地在你的个人库中变成一个可重用的函数。
It may seem like I have an infinite loop with the outer while
because of while(spans[0])
, but because we're dealing with a "live list" it gets updated when we do the parent.removeChild(span[0]);
. This is a pretty nifty feature that we miss out on when working with an Array (or Array-like object) instead.
看起来我与外部有一个无限循环,while
因为while(spans[0])
,但是因为我们正在处理一个“实时列表”,当我们执行parent.removeChild(span[0]);
. 这是一个非常漂亮的功能,我们在使用 Array(或类似 Array 的对象)时会错过它。
回答by g.d.d.c
The correct answer is that you'll alwaystake a performance penalty when using jQuery instead of 'plain old' native JavaScript. That's because jQuery is a JavaScript Library. It is not some fancy new version of JavaScript.
正确的答案是,当使用 jQuery 而不是“普通的”原生 JavaScript 时,您总是会受到性能损失。那是因为 jQuery 是一个 JavaScript 库。它不是一些花哨的新版本的 JavaScript。
The reason that jQuery is powerful is that it makes some things which are overly tedious in a cross-browser situation (AJAX is one of the best examples) and smooths over the inconsistencies between the myriad of available browsers and provides a consistent API. It also easily facilitates concepts like chaining, implied iteration, etc, to simplify working on groups of elements together.
jQuery 之所以强大,是因为它在跨浏览器的情况下做了一些过于乏味的事情(AJAX 是最好的例子之一),并平滑了无数可用浏览器之间的不一致,并提供了一致的 API。它还可以轻松促进链接、隐含迭代等概念,以简化一起处理元素组的工作。
Learning jQuery is no substitute for learning JavaScript. You should have a firm basis in the latter so that you fully appreciate what knowing the former is making easier for you.
学习 jQuery 并不能代替学习 JavaScript。你应该对后者有一个坚实的基础,这样你才能充分体会到了解前者会让你变得更容易。
-- Edited to encompass comments --
-- 编辑以包含评论 --
As the comments are quick to point out (and I agree with 100%) the statements above refer to benchmarking code. A 'native' JavaScript solution (assuming it is well written) will outperform a jQuery solution that accomplishes the same thing in nearly every case (I'd love to see an example otherwise). jQuery does speed up development time, which is a significant benefit which I do not mean to downplay. It facilitates easy to read, easy to follow code, which is more than some developers are capable of creating on their own.
由于评论很快指出(我 100% 同意),上面的陈述指的是基准测试代码。“原生”JavaScript 解决方案(假设它编写得很好)将胜过几乎在所有情况下都完成相同事情的 jQuery 解决方案(否则我很想看到一个示例)。jQuery 确实加快了开发时间,这是一个我不想贬低的重要好处。它使代码易于阅读,易于遵循,这比某些开发人员能够自己创建的要多。
In my opinion then, the answer depends on what you're attempting to achieve. If, as I presumed based on your reference to performance benefits, you're after the best possible speed out of your application, then using jQuery introduces overhead every time you call $()
. If you're going for readability, consistency, cross browser compatibility, etc, then there are certainly reasons to favor jQuery over 'native' JavaScript.
在我看来,答案取决于您要实现的目标。如果,正如我根据您对性能优势的参考所推测的那样,您希望尽可能提高应用程序的速度,那么每次调用$()
. 如果您追求可读性、一致性、跨浏览器兼容性等,那么肯定有理由支持 jQuery 而不是“原生”JavaScript。
回答by Leniel Maccaferri
There's a framework called... oh guess what? Vanilla JS
. Hope you get the joke... :D It sacrifices code legibility for performance... Comparing it to jQuery
bellow you can see that retrieving a DOM
element by ID
is almost 35Xfaster. :)
有一个框架叫做...哦,你猜怎么着?Vanilla JS
. 希望你jQuery
能理解这个笑话... :D 它为了性能而牺牲了代码的易读性...与下面的比较,你可以看到检索DOM
元素的速度ID
几乎快了35倍。:)
So if you want performance you'd better try Vanilla JS and draw your own conclusions. Maybe you won't experience JavaScript hanging the browser's GUI/locking up the UI thread during intensive code like inside a for
loop.
所以如果你想要性能,你最好尝试 Vanilla JS 并得出你自己的结论。也许你不会遇到 JavaScript 挂起浏览器的 GUI/在像for
循环内那样的密集代码期间锁定 UI 线程。
Vanilla JS is a fast, lightweight, cross-platform framework for building incredible, powerful JavaScript applications.
Vanilla JS 是一个快速、轻量级、跨平台的框架,用于构建令人难以置信的强大 JavaScript 应用程序。
On their homepage there's some perf comparisons:
在他们的主页上有一些性能比较:
回答by slebetman
There's already an accepted answer but I believe no answer typed directly here can be comprehensive in its list of native javascript methods/attributes that has practically guaranteed cross-browser support. For that may I redirect you to quirksmode:
已经有一个可以接受的答案,但我相信这里直接输入的答案在其本机 javascript 方法/属性列表中是全面的,这些方法/属性实际上保证了跨浏览器支持。为此,我可以将您重定向到 quirksmode:
http://www.quirksmode.org/compatibility.html
http://www.quirksmode.org/compatibility.html
It is perhaps the most comprehensive list of what works and what doesn't work on what browser anywhere. Pay particular attention to the DOM section. It is a lot to read but the point is not to read it all but to use it as a reference.
它可能是最全面的列表,列出了在任何地方的浏览器上哪些有效,哪些无效。请特别注意 DOM 部分。阅读很多,但重点不是全部阅读,而是将其用作参考。
When I started seriously writing web apps I printed out all the DOM tables and hung them on the wall so that I know at a glance what is safe to use and what requires hacks. These days I just google something like quirksmode parentNode compatibility
when I have doubts.
当我开始认真地编写 Web 应用程序时,我打印了所有的 DOM 表并将它们挂在墙上,以便我一眼就知道什么是安全的,什么是需要破解的。这些天我只是quirksmode parentNode compatibility
在有疑问的时候用谷歌搜索。
Like anything else, judgement is mostly a matter of experience. I wouldn't really recommend you to read the entire site and memorize all the issues to figure out when to use jQuery and when to use plain JS. Just be aware of the list. It's easy enough to search. With time you will develop an instinct of when plain JS is preferable.
像其他任何事情一样,判断主要是经验问题。我真的不建议您阅读整个网站并记住所有问题来弄清楚何时使用 jQuery 以及何时使用纯 JS。请注意列表。搜索起来很容易。随着时间的推移,你会产生一种直觉,即什么时候使用纯 JS 是可取的。
PS: PPK (the author of the site) also has a very nice book that I do recommend reading
PS:PPK(该网站的作者)也有一本非常好的书,我推荐阅读
回答by Phrogz
When:
什么时候:
- you know that there is unflinching cross-browser support for what you are doing, and
- it is not significantly more code to type, and
- it is not significantly less readable, and
- you are reasonably confident that jQuery will not choose different implementations based on the browser to achieve better performance, then:
- 你知道你正在做的事情有坚定的跨浏览器支持,并且
- 输入的代码并不多,并且
- 它的可读性并没有显着降低,并且
- 您有理由相信 jQuery 不会根据浏览器选择不同的实现来获得更好的性能,然后:
use JavaScript. Otherwise use jQuery (if you can).
使用 JavaScript。否则使用 jQuery(如果可以的话)。
Edit: This answer applies both when choosing to use jQuery overall versus leaving it out, as well as choosing whether to to use vanilla JS inside jQuery. Choosing between attr('id')
and .id
leans in favor of JS, while choosing between removeClass('foo')
versus .className = .className.replace( new Regexp("(?:^|\\s+)"+foo+"(?:\\s+|$)",'g'), '' )
leans in favor of jQuery.
编辑:这个答案适用于选择整体使用 jQuery 还是不使用它,以及选择是否在 jQuery 中使用 vanilla JS。之间进行选择attr('id')
,并.id
有利于JS的斜靠,而之间的选择removeClass('foo')
与.className = .className.replace( new Regexp("(?:^|\\s+)"+foo+"(?:\\s+|$)",'g'), '' )
支持的jQuery的倾斜。
回答by Andrew Whitaker
Others' answers have focused on the broad question of "jQuery vs. plain JS." Judging from your OP, I think you were simply wondering when it's better to use vanilla JS if you've already chosen to use jQuery. Your example is a perfect example of when you should use vanilla JS:
其他人的回答集中在“jQuery 与普通 JS”的广泛问题上。从您的 OP 来看,我认为您只是想知道如果您已经选择使用 jQuery,那么什么时候使用 vanilla JS 更好。您的示例是何时应该使用 vanilla JS 的完美示例:
$(this).attr('id');
$(this).attr('id');
Is both slower and (in my opinion) less readable than:
比以下内容更慢并且(在我看来)可读性更低:
this.id
.
this.id
.
It's slower because you have to spin up a new JS object just to retrieve the attribute the jQuery way. Now, if you're going to be using $(this)
to perform other operations, then by all means, store that jQuery object in a variable and operate with that. However, I've run into many situations where I just need an attribute from the element (like id
or src
).
它较慢,因为您必须启动一个新的 JS 对象才能以 jQuery 方式检索属性。现在,如果您打算使用它$(this)
来执行其他操作,那么无论如何,将该 jQuery 对象存储在一个变量中并对其进行操作。但是,我遇到过很多情况,我只需要元素中的一个属性(如id
或src
)。
Are there any other common practices like this? Where certain Javascript operations could be accomplished easier, without bringing jQuery into the mix. Or is this a rare case? (of a jQuery "shortcut" actually requiring more code)
还有其他类似的常见做法吗?某些 Javascript 操作可以更轻松地完成,而无需将 jQuery 混入其中。或者这是一个罕见的案例?(实际上需要更多代码的jQuery“快捷方式”)
I think the most common case is the one you describe in your post; people wrapping $(this)
in a jQuery object unnecessarily. I see this most often with id
and value
(instead using $(this).val()
).
我认为最常见的情况是您在帖子中描述的情况;人们$(this)
不必要地包装在 jQuery 对象中。我最常使用id
和value
(而不是使用$(this).val()
)看到这一点。
Edit:Here's an article that explains whyusing jQuery in the attr()
case is slower. Confession: stole it from the tag wiki, but I think it's worth mentioning for the question.
编辑:这里有一篇文章解释了为什么在这种attr()
情况下使用 jQuery速度较慢。忏悔:从标签维基上偷来的,但我认为这个问题值得一提。
Edit again:Given the readability/performance implications of just accessing attributes directly, I'd say a good rule of thumb is probably to try to to use this.<attributename>
when possible. There are probably some instances where this won't work because of browser inconsistencies, but it's probably better to try this first and fall back on jQuery if it doesn't work.
再次编辑:鉴于直接访问属性的可读性/性能影响,我想说一个好的经验法则可能是尽可能尝试使用this.<attributename>
。在某些情况下,这可能会因为浏览器不一致而不起作用,但最好先尝试一下,如果不起作用,则返回 jQuery。
回答by Stephen
If you are mostly concerned about performance, your main example hits the nail on the head. Invoking jQuery unnecessarily or redundantly is, IMHO, the second main cause of slow performance (the first being poor DOM traversal).
如果您最关心性能,那么您的主要示例就一针见血。恕我直言,不必要或多余地调用 jQuery 是性能缓慢的第二个主要原因(第一个是糟糕的 DOM 遍历)。
It's not reallyan example of what you're looking for, but I see this so often that it bears mentioning: One of the best ways to speed up performance of your jQuery scripts is to cache jQuery objects, and/or use chaining:
这不是您正在寻找的真正示例,但我经常看到这一点,因此值得一提:加快 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();
回答by Dutchie432
I've found there is certainly overlap between JS and JQ. The code you've shown is a good example of that. Frankly, the best reason to use JQ over JS is simply browser compatibility. I always lean toward JQ, even if I can accomplish something in JS.
我发现 JS 和 JQ 之间肯定存在重叠。您展示的代码就是一个很好的例子。坦率地说,使用 JQ 而不是 JS 的最佳理由就是浏览器兼容性。我总是倾向于 JQ,即使我可以用 JS 完成一些事情。
回答by CodeVirtuoso
This is my personal view, but as jQuery is JavaScript anyway, I think theoretically it cannot perform better than vanilla JS ever.
这是我个人的观点,但由于 jQuery 无论如何都是 JavaScript,我认为理论上它的性能永远不会比 vanilla JS 更好。
But practically it may perform better than hand-written JS, as one's hand-written code may be not as efficient as jQuery.
但实际上它可能比手写 JS 执行得更好,因为手写代码可能不如 jQuery 高效。
Bottom-line - for smaller stuff I tend to use vanilla JS, for JS intensive projects I like to use jQuery and not reinvent the wheel - it's also more productive.
底线 - 对于较小的东西,我倾向于使用 vanilla JS,对于 JS 密集型项目,我喜欢使用 jQuery 而不是重新发明轮子 - 它也更有效率。
回答by lib3d
The first answer's live properties list of this
as a DOM element is quite complete.
this
作为 DOM 元素的第一个答案的实时属性列表非常完整。
You may find also interesting to know some others.
您可能会发现认识其他一些人也很有趣。
When this is the document :
当这是文件时:
this.forms
to get anHTMLCollection
of the current document forms,this.anchors
to get anHTMLCollection
of all theHTMLAnchorElements
withname
being set,this.links
to get anHTMLCollection
of all theHTMLAnchorElement
s withhref
being set,this.images
to get anHTMLCollection
of all theHTMLImageElement
s- and the same with the deprecated applets as
this.applets
this.forms
获取HTMLCollection
当前文档表单中的一个,this.anchors
得到的HTMLCollection
所有的HTMLAnchorElements
与name
被设定,this.links
获得HTMLCollection
所有HTMLAnchorElement
s 中的一个href
被设置,this.images
得到HTMLCollection
所有HTMLImageElement
s 中的一个- 与已弃用的小程序相同
this.applets
When you work with document.forms
, document.forms[formNameOrId]
gets the so named or identified form.
当您使用 时document.forms
,document.forms[formNameOrId]
获取如此命名或标识的表单。
When this is a form :
当这是一种形式时:
this[inputNameOrId]
to get the so named or identified field
this[inputNameOrId]
获取如此命名或标识的字段
When this is form field:
当这是表单字段时:
this.type
to get the field type
this.type
获取字段类型
When learning jQuery selectors, we often skip learning already existing HTML elements properties, which are so fast to access.
在学习 jQuery 选择器时,我们经常跳过学习已经存在的 HTML 元素属性,这些属性访问速度非常快。