何时使用Vanilla JavaScript与jQuery?

jon*_*ohn 233 javascript performance jquery

我注意到在监控/尝试回答常见的jQuery问题时,有一些使用javascript而不是jQuery的实践,实际上可以让你写得更少,并做 ...相同的数量.并且还可以产生性能优势.

一个具体的例子

$(this) VS this

在单击事件中引用单击的对象id

jQuery的

$(this).attr("id");
Run Code Online (Sandbox Code Playgroud)

使用Javascript

this.id;
Run Code Online (Sandbox Code Playgroud)

还有其他类似的常见做法吗?可以更轻松地完成某些Javascript操作,而无需将jQuery添加到组合中.或者这是一个罕见的情况?(jQuery"快捷方式"实际上需要更多代码)

编辑:虽然我很欣赏有关jQuery与普通javascript性能的答案,但实际上我正在寻找更多的定量答案. 在使用jQuery时,实际上可以更好地使用普通javascript代替使用的实例(可读性/紧凑性)$().除了我在原始问题中给出的例子.

use*_*716 203

  • this.id (如你所知)
  • this.value(在大多数输入类型上.只有当我<select>没有value在其<option>元素上设置属性或Safari中的无线电输入时,我知道的问题是IE .)
  • this.className 获取或设置整个"类"属性
  • this.selectedIndex反对a <select>获取所选索引
  • this.options反对a <select>获取<option>元素列表
  • this.text反对<option>获取其文本内容
  • this.rows反对a <table>获取<tr>元素的集合
  • this.cells反对a <tr>得到它的细胞(td&th)
  • this.parentNode 得到一个直接的父母
  • this.checked获得一个感谢@Tim Down的检查状态checkbox
  • this.selected获得所选状态的option 感谢@Tim Down
  • this.disabled获得感谢@Tim Down的残疾状态input
  • this.readOnly获得一个感谢@Tim Down的readOnly状态input
  • this.href反对一个<a>元素得到它href
  • this.hostname反对一个<a>元素来获取它的域名href
  • this.pathname反对一个<a>元素来获取它的路径href
  • this.search对一个<a>元素来获取它的查询字符串href
  • this.src 对一个有效的元素 src

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

有时性能至关重要.就像你在循环中多次执行某些操作一样,你可能想抛弃jQuery.

一般来说,您可以替换:

$(el).attr('someName');
Run Code Online (Sandbox Code Playgroud)

有:

上面的措辞很差.getAttribute它不是替代品,但它确实检索从服务器发送的属性的值,并且它相应的setAttribute将设置它.在某些情况下是必要的.

下面的句子有点覆盖它.请参阅此答案以获得更好的治疗.

el.getAttribute('someName');
Run Code Online (Sandbox Code Playgroud)

...以便直接访问属性.请注意,属性与属性不同(尽管它们有时会互相镜像).当然也有setAttribute.

假设你遇到一个情况,你需要打开一个页面,你需要打开某个类型的所有标签.使用jQuery简单易行:

$('span').unwrap();  // unwrap all span elements
Run Code Online (Sandbox Code Playgroud)

但是如果有很多,你可能想做一些原生的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] );
}
Run Code Online (Sandbox Code Playgroud)

此代码非常简短,它的性能优于jQuery版本,并且可以轻松地在您的个人库中实现可重用的功能.

看起来我有一个无限循环与外部while因为while(spans[0]),但因为我们正在处理"实时列表"它会在我们这样做时更新parent.removeChild(span[0]);.这是一个非常漂亮的功能,我们在使用Array(或类似Array的对象)时错过了这个功能.

  • 这个答案应该是一个维基 (8认同)
  • 我准备写一个答案,但我会为你的建议添加建议.通常,`attr()`被大量过度使用.如果你只处理一个元素,那么你很少需要`attr()`.我最喜欢的两个是关于复选框的`checked`属性的混淆(围绕那个的各种神秘咒语:`$(this).attr("checked","checked")`,`$(this).is (":checked")`等)和类似`<option>`元素的`selected`属性. (3认同)
  • 很好...所以主要围绕这个关键字不成功地被包装到jQuery对象中. (2认同)

g.d*_*d.c 60

正确的答案是,在使用jQuery而不是"普通旧"本机JavaScript时,您总是会受到性能损失.那是因为jQuery是一个JavaScript库.它不是一些奇特的新版JavaScript.

jQuery功能强大的原因在于它在跨浏览器的情况下会产生一些过于繁琐的东西(AJAX是最好的例子之一),并且平滑了无数可用浏览器之间的不一致性并提供了一致的API.它还可以轻松地促进诸如链接,隐含迭代等概念,以简化对元素组的处理.

学习jQuery不能替代学习JavaScript.你应该在后者中有一个坚实的基础,这样你才能完全理解前者对你更容易的了解.

- 编辑包含评论 -

由于评论很快指出(我同意100%),上述陈述是指基准代码.一个"本机"JavaScript解决方案(假设编写得很好)将胜过jQuery解决方案,几乎在所有情况下都能完成同样的事情(我很乐意看到一个例子).jQuery确实加快了开发时间,这是一个重要的好处,我并不打算淡化.它易于阅读,易于遵循代码,这比一些开发人员能够自己创建的更多.

在我看来,答案取决于你想要实现的目标.如果,正如我根据您对性能优势的引用所假设的那样,您可以在应用程序之后获得最佳速度,那么每次调用时使用jQuery都会引入开销$().如果你要考虑可读性,一致性,跨浏览器兼容性等,那么肯定有理由支持jQuery优于"本机"JavaScript.

  • 写得不好的自制解决方案可能会慢一些.jQuery团队在包中执行了一些高效的JavaScript.请参阅@ Freelancer的回答. (15认同)
  • 你写的所有内容都是真的,但是你已经忘记了@Ben上面提到的内容.jQuery使_developer_更快,更健壮.请参阅我多年前写过并大量使用的[这个KillClass()实现](http://phrogz.net/JS/AddClassKillClass_js.txt).你知道吗?对于某些边缘情况,它是_broken_.糟糕的代码是糟糕的代码,错误的代码是错误的代码,但使用jQuery通常会使开发人员编写更好,更正确的代码.大多数时候,计算机足够快; 它是需要帮助的开发人员. (12认同)
  • @gddc我认为jQuery"优于"(在基准框之外阅读)纯JS的最好例子是减少开发时间(这是业务方面的巨大价值)并简化实验 (10认同)
  • 我很想看到一个jQuery可以胜过纯JS中的实现的情况的例子.无论你做什么,如果你正在使用jQuery(或任何其他库),你的功能开销是不可避免的.没有办法摆脱调用`$()`产生的(尽管)微小的开销.如果您不拨打电话,则可以节省时间. (8认同)
  • 写得不好的解决方案永远都是一个写得不好的解决方案,而这不是语言的错.它并没有改变这样一个事实,即如果经过深思熟虑,那么"本机"函数可以避免库的开销. (3认同)

Len*_*rri 38

有一个框架叫做......哦,猜怎么着?Vanilla JS.希望你得到这个笑话......:D它牺牲了代码的易读性......比较jQuery下面你可以看到检索一个DOM元素的速度快了ID35倍.:)

因此,如果你想要表现,你最好尝试Vanilla JS并得出你自己的结论.也许你不会遇到JavaScript挂起浏览器的GUI /在密集代码中锁定UI线程,比如for循环内部.

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

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

在此输入图像描述


sle*_*man 17

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

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

它可能是最全面的列表,其中包含哪些有效,哪些无效.特别注意DOM部分.要阅读的内容很多,但重点不在于阅读全部内容,而是将其作为参考.

当我开始认真编写Web应用程序时,我打印出所有DOM表并将它们挂在墙上,这样我就可以一眼就知道什么是安全的,什么需要黑客.这些天我只是像quirksmode parentNode compatibility我怀疑时那样谷歌.

像其他任何事情一样,判断主要是经验问题.我不会真的建议你阅读整个网站并记住所有问题,以确定何时使用jQuery以及何时使用普通JS.请注意清单.搜索很容易.随着时间的推移,你会发展出一种当普通JS更受欢迎的本能.


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


Phr*_*ogz 14

什么时候:

  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. (3认同)
  • @Tyilo classList.remove是HTML5 ClassList API的一部分,未在IE9中实现,例如http://caniuse.com/#feat=classlist (3认同)

And*_*ker 13

其他人的回答集中在"jQuery vs.普通JS"的广泛问题上.从您的OP来看,我认为您只是想知道如果您已经选择使用jQuery,最好使用vanilla JS.您的示例是何时应该使用vanilla JS的完美示例:

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

是慢还是(在我看来)可读性低于:

this.id.

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

还有其他类似的常见做法吗?可以更轻松地完成某些Javascript操作,而无需将jQuery添加到组合中.或者这是一个罕见的情况?(jQuery"快捷方式"实际上需要更多代码)

我认为最常见的情况是你在帖子中描述的情况; 人们$(this)不必要地包装在jQuery对象中.我经常看到这个idvalue(而不是使用$(this).val()).

编辑: 这里的解释文章,为什么使用jQuery的attr()情况下较慢.忏悔:从标签维基中偷走它,但我认为这个问题值得一提.

再次编辑:鉴于直接访问属性的可读性/性能影响,我想说一个好的经验法则可能是尽可能尝试使用this.<attributename>.可能有些情况下由于浏览器的不一致而无法正常工作,但是如果它不起作用,最好先尝试这个并回到jQuery上.


Ste*_*hen 10

如果你最关心的是表现,那么你的主要例子就会击中头部.不必要地或冗余地调用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();
Run Code Online (Sandbox Code Playgroud)

  • 另一方面,采取相同的例子.调用`$('.something')`两次意味着jQuery必须遍历DOM*两次*寻找具有该选择器的所有元素. (2认同)
  • 在第一个例子的情况下,缓存`$(this)`减少了对jQuery函数的调用.这将为您提供循环场景中的最大收益. (2认同)
  • @Alnitak注意`element`等于`$(this)`.那不包含多个元素. (2认同)

Dut*_*432 8

我发现JS和JQ之间肯定存在重叠.您展示的代码就是一个很好的例子.坦率地说,使用JQ而不是JS的最佳理由就是浏览器兼容性.我总是倾向于JQ,即使我可以在JS中完成某些事情.

  • 如果没有任何重叠将是一个奇迹,因为JQuery是JavaScript. (8认同)

Cod*_*oso 6

这是我个人的观点,但是无论如何jQuery都是JavaScript,我认为理论上它不能比vanilla JS表现更好.

但实际上它可能比手写JS更好,因为一个人的手写代码可能没有jQuery那么高效.

底线 - 对于较小的东西我倾向于使用vanilla JS,对于JS密集型项目我喜欢使用jQuery而不是重新发明轮子 - 它也更有效率.