什么时候使用 Vanilla JavaScript 和 jQuery?

IT技术 javascript jquery performance
2021-01-22 06:02:55

我注意到,在监视/尝试回答常见的 jQuery 问题时,有一些使用 javascript 而不是 jQuery 的做法,实际上使您能够编写更少的内容并做……同样的数量。并且还可能产生性能优势。

一个具体的例子

$(this) 对比 this

在引用被点击对象 id 的点击事件中

jQuery

$(this).attr("id");

Javascript

this.id;

还有其他类似的常见做法吗?某些 Javascript 操作可以更轻松地完成,而无需将 jQuery 混入其中。或者这是一个罕见的案例?(实际上需要更多代码的jQuery“快捷方式”)

编辑:虽然我很欣赏有关 jQuery 与普通 javascript 性能的答案,但实际上我正在寻找更多定量的答案。 在使用 jQuery 时,使用纯 javascript 而不是使用$(). 除了我在原始问题中给出的示例之外。

6个回答
  • 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

...我想你应该已经明白了。

有时性能至关重要。就像如果您在循环中多次执行某些操作一样,您可能想要放弃 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]);. 这是一个非常漂亮的功能,我们在使用 Array(或类似 Array 的对象)时会忽略它。

@jondavidjohn:嗯,在某些情况下有一些很好的修复,比如在某些情况this.value下有几个浏览器怪癖。这一切都取决于您的需要。有许多不错的技术在没有 jQuery 的情况下也很容易,尤其是在性能至关重要的时候。我会试着想更多。
2021-03-18 06:02:55
很好...所以它主要围绕 this 关键字不必要地包装到 jQuery 对象中。
2021-03-23 06:02:55
我正要写一个答案,但我会为您添加建议。通常,attr()被大量过度使用。如果您只处理一个元素,那么您将很少需要attr(). 我最喜欢的两个是周围的混乱checked复选框的财产(各种围绕着一个神秘的咒语:$(this).attr("checked", "checked")$(this).is(":checked")等等),同样的selected财产<option>元素。
2021-03-23 06:02:55
Aaargh,@patrick,noooo:你推荐了getAttribute(). 你几乎从来不需要它:它在 IE 中坏了,并不总是反映当前状态,无论如何它不是 jQuery 所做的。只需使用属性。stackoverflow.com/questions/4456231/...
2021-03-27 06:02:55
我使用 JS 这么久,我不知道 className,谢谢。
2021-03-30 06:02:55

正确答案是,当使用 jQuery 而不是“普通的”原生 JavaScript 时,您总是会遭受性能损失。那是因为 jQuery 是一个 JavaScript 库。它不是一些花哨的 JavaScript 新版本。

jQuery 之所以强大,是因为它在跨浏览器的情况下做了一些过于乏味的事情(AJAX 是最好的例子之一),并平滑了无数可用浏览器之间的不一致,并提供了一致的 API。它还可以轻松促进链接、隐含迭代等概念,以简化一起处理元素组的工作。

学习 jQuery 并不能代替学习 JavaScript。你应该对后者有一个坚实的基础,这样你才能充分体会到了解前者会让你变得更容易。

-- 编辑以包含评论 --

由于评论很快指出(我 100% 同意),上面的陈述指的是基准测试代码。“原生”JavaScript 解决方案(假设它写得很好)将胜过几乎在所有情况下都完成相同事情的 jQuery 解决方案(否则我很乐意看到一个示例)。jQuery 确实加快了开发时间,这是一个我不想贬低的重要好处。它使代码易于阅读,易于遵循,这比某些开发人员能够自己创建的要多。

在我看来,答案取决于您要实现的目标。如果,正如我根据您对性能优势的参考所推测的那样,您希望尽可能提高应用程序的速度,那么每次调用$(). 如果您追求可读性、一致性、跨浏览器兼容性等,那么肯定有理由支持 jQuery 而不是“原生”JavaScript。

写得不好的自制解决方案可能会更慢。jQuery 团队在包中执行了一些高效的 JavaScript。请参阅@Freelancer 的回答。
2021-03-13 06:02:55
我很想看到一个例子,说明 jQuery 可以胜过纯 JS 中的实现。无论您做什么,如果您使用 jQuery(或任何其他与此相关的库),您都会有不可避免的函数开销。没有办法摆脱调用$(). 如果你不打那个电话,你就可以节省时间。
2021-03-24 06:02:55
@gddc 我认为 jQuery“优于”(在基准测试框之外读取)纯 JS 的最佳示例是减少开发时间(这是一个巨大的商业价值)并简化实验
2021-03-29 06:02:55
一个写得不好的解决方案总是一个写得不好的解决方案,这不是语言的错。它不会改变库将产生开销的事实,如果经过深思熟虑,“本机”函数可以避免这种开销。
2021-04-05 06:02:55
您所写的所有内容都是真实的,但是您忽略了@Ben 上面提到的内容。jQuery 使开发人员更快、更健壮。请参阅我多年前编写并大量使用的KillClass() 实现你知道吗?在某些边缘情况下被破坏了。糟糕的代码就是糟糕的代码,错误的代码就是错误的代码,但是使用jQuery往往能让开发者写出更好更正确的代码。大多数时候,计算机足够快;需要帮助的是开发人员。
2021-04-10 06:02:55

有一个框架叫做...哦,你猜怎么着?Vanilla JS. 希望你jQuery能理解这个笑话... :D 它为了性能而牺牲了代码的易读性...与下面的比较,你可以看到检索DOM元素的速度ID几乎35倍。:)

所以如果你想要性能,你最好尝试 Vanilla JS 并得出你自己的结论。也许您不会遇到 JavaScript 挂起浏览器的 GUI/在像for循环内部这样的密集代码期间锁定 UI 线程的情况

Vanilla JS 是一个快速、轻量级、跨平台的框架,用于构建令人难以置信的强大 JavaScript 应用程序。

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

在此处输入图片说明

@Leniel Macaferi 哦,伙计,我喜欢这个答案!我没有意识到 vanilla 和其他框架之间的性能会产生如此大的不同!无论如何,这个答案的名人堂!!PS:你也是做网站的吗?
2021-04-04 06:02:55

已经有一个可以接受的答案,但我相信这里直接输入的答案在其本机 javascript 方法/属性列表中是全面的,这些方法/属性实际上保证了跨浏览器支持。为此,我可以将您重定向到 quirksmode:

http://www.quirksmode.org/compatibility.html

它可能是最全面的列表,列出了在任何地方的浏览器上哪些有效,哪些无效。请特别注意 DOM 部分。阅读很多,但重点不是全部阅读,而是将其用作参考。

当我开始认真地编写 Web 应用程序时,我打印了所有的 DOM 表并将它们挂在墙上,以便我一眼就知道什么是安全的,什么是需要破解的。这些天我只是quirksmode parentNode compatibility在有疑问的时候用谷歌搜索

像其他任何事情一样,判断主要是经验问题。我真的不建议您阅读整个网站并记住所有问题来弄清楚何时使用 jQuery 以及何时使用纯 JS。请注意列表。搜索起来很容易。随着时间的推移,你会产生一种直觉,即什么时候使用纯 JS 是可取的。


PS:PPK(该网站的作者)也有一本非常好的书,我推荐阅读

什么时候:

  1. 你知道你正在做的事情有坚定的跨浏览器支持,并且
  2. 输入的代码并不多,并且
  3. 它的可读性并没有明显降低,并且
  4. 您有理由相信 jQuery 不会根据浏览器选择不同的实现来获得更好的性能,然后:

使用 JavaScript。否则使用 jQuery(如果可以的话)。

编辑:这个答案适用于选择整体使用 jQuery 还是不使用它,以及选择是否在 jQuery 中使用 vanilla JS。attr('id').id倾向于 JS 之间进行选择,而在removeClass('foo').className = .className.replace( new Regexp("(?:^|\\s+)"+foo+"(?:\\s+|$)",'g'), '' )倾向于 jQuery之间进行选择

我认为 OP 打算使用 jQuery,但想知道在他的 jQuery 方法中何时何地使用原生 JavaScript。
2021-03-15 06:02:55
@Tyilo classList.remove 是未在 IE9 中实现的 HTML5 ClassList API 的一部分,例如caniuse.com/#feat=classlist
2021-04-01 06:02:55
.classList.remove('foo') 在较新的浏览器中似乎可以正常工作
2021-04-07 06:02:55