何时使用 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 13:27:57  来源:igfitidea点击:

When to use Vanilla JavaScript vs. jQuery?

javascriptjqueryperformance

提问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 have valueproperties set on its <option>elements, or radio inputs in Safari.)
  • this.classNameto get or set an entire "class" property
  • this.selectedIndexagainst a <select>to get the selected index
  • this.optionsagainst a <select>to get a list of <option>elements
  • this.textagainst an <option>to get its text content
  • this.rowsagainst a <table>to get a collection of <tr>elements
  • this.cellsagainst a <tr>to get its cells (td & th)
  • this.parentNodeto get a direct parent
  • this.checkedto get the checked state of a checkboxThanks @Tim Down
  • this.selectedto get the selected state of an optionThanks @Tim Down
  • this.disabledto get the disabled state of an inputThanks @Tim Down
  • this.readOnlyto get the readOnly state of an inputThanks @Tim Down
  • this.hrefagainst an <a>element to get its href
  • this.hostnameagainst an <a>element to get the domain of its href
  • this.pathnameagainst an <a>element to get the path of its href
  • this.searchagainst an <a>element to get the querystring of its href
  • this.srcagainst an element where it is valid to have a src
  • 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. getAttributeis not a replacement, but it does retrieve the value of an attribute sent from the server, and its corresponding setAttributewill 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 setAttributetoo.

...为了直接访问属性。请注意,属性与属性不同(尽管它们有时会相互反映)。当然也有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 whilebecause 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 jQuerybellow you can see that retrieving a DOMelement by IDis 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 forloop.

所以如果你想要性能,你最好尝试 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:

在他们的主页上有一些性能比较:

enter image description here

在此处输入图片说明

回答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 compatibilitywhen 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:

什么时候:

  1. you know that there is unflinching cross-browser support for what you are doing, and
  2. it is not significantly more code to type, and
  3. it is not significantly less readable, and
  4. you are reasonably confident that jQuery will not choose different implementations based on the browser to achieve better performance, then:
  1. 你知道你正在做的事情有坚定的跨浏览器支持,并且
  2. 输入的代码并不多,并且
  3. 它的可读性并没有显着降低,并且
  4. 您有理由相信 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 .idleans 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 idor src).

它较慢,因为您必须启动一个新的 JS 对象才能以 jQuery 方式检索属性。现在,如果您打算使用它$(this)来执行其他操作,那么无论如何,将该 jQuery 对象存储在一个变量中并对其进行操作。但是,我遇到过很多情况,我只需要元素中的一个属性(如idsrc)。

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 idand value(instead using $(this).val()).

我认为最常见的情况是您在帖子中描述的情况;人们$(this)不必要地包装在 jQuery 对象中。我最常使用idvalue(而不是使用$(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 thisas a DOM element is quite complete.

this作为 DOM 元素的第一个答案的实时属性列表非常完整。

You may find also interesting to know some others.

您可能会发现认识其他一些人也很有趣。

When this is the document :

当这是文件时:

  • this.formsto get an HTMLCollectionof the current document forms,
  • this.anchorsto get an HTMLCollectionof all the HTMLAnchorElementswith namebeing set,
  • this.linksto get an HTMLCollectionof all the HTMLAnchorElements with hrefbeing set,
  • this.imagesto get an HTMLCollectionof all the HTMLImageElements
  • and the same with the deprecated applets as this.applets
  • this.forms获取HTMLCollection当前文档表单中的一个,
  • this.anchors得到的HTMLCollection所有的HTMLAnchorElementsname被设定,
  • this.links获得HTMLCollection所有HTMLAnchorElements 中的一个href被设置,
  • this.images得到HTMLCollection所有HTMLImageElements 中的一个
  • 与已弃用的小程序相同 this.applets

When you work with document.forms, document.forms[formNameOrId]gets the so named or identified form.

当您使用 时document.formsdocument.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.typeto 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 元素属性,这些属性访问速度非常快。