什么时候使用香草JavaScript和jQuery?

我注意到,在监控/尝试回答常见的jQuery问题时,有一些使用javascript的实践,而不是jQuery,这实际上使您能够少写多做…同样的量。而且还可能带来性能上的好处。

具体例子

$(this) vs this

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

jQuery

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

Javascript

this.id;

还有其他类似的常见做法吗?某些Javascript操作可以更容易地完成,而不需要使用jQuery。或者这是一种罕见的情况?(jQuery的“快捷方式”实际上需要更多的代码)

编辑:虽然我很欣赏关于jQuery和普通javascript性能的答案,但我实际上正在寻找更多量化的答案。使用jQuery时,在这些实例中,使用纯javascript而不是使用$()会更好(可读性/紧凑性)。除了我在最初的问题中给出的例子。

77096 次浏览

当:

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

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

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

我发现JS和JQ之间确实有重叠。您所展示的代码就是一个很好的例子。坦率地说,使用JQ而不是JS的最佳理由仅仅是浏览器兼容性。我总是倾向于JQ,即使我能用JS完成一些事情。

正确的答案是,当你使用jQuery而不是“普通的旧”原生JavaScript时,你将总是采取性能惩罚。这是因为jQuery是一个JavaScript库。它不是什么花哨的JavaScript新版本。

jQuery强大的原因在于,它使一些在跨浏览器情况下过于繁琐的事情变得简单(AJAX就是最好的例子之一),并平滑了无数可用浏览器之间的不一致性,并提供了一致的API。它还很容易促进链接、隐含迭代等概念,以简化一起处理元素组的工作。

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

-编辑以包含评论-

正如评论中很快指出的那样(我100%同意),上面的语句是指基准测试代码。一个“原生”JavaScript解决方案(假设它写得很好)将比一个jQuery解决方案在几乎所有情况下都能完成相同的事情(我很想看到一个例子)。jQuery确实加快了开发时间,这是一个显著的好处,我并不想忽视它。它使代码易于阅读和遵循,这是一些开发人员自己无法创建的。

在我看来,答案取决于你想要达到的目标。如果,正如我根据你对性能好处的参考所推测的那样,你追求的是应用程序的最佳速度,那么每次调用$()时使用jQuery都会带来开销。如果你追求可读性、一致性、跨浏览器兼容性等等,那么肯定有理由支持jQuery而不是“原生”JavaScript。

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

但实际上,它可能比手工编写的JS执行得更好,因为手工编写的代码可能不如jQuery有效。

总之,对于较小的东西,我倾向于使用普通的JS,对于JS密集的项目,我喜欢使用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();

其他人的回答集中在“jQuery vs.纯JS”这个宽泛的问题上。从你的OP来看,我认为你只是想知道如果你已经选择使用jQuery,什么时候使用普通JS更好。你的例子是一个完美的例子,当你应该使用香草JS:

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

既慢,(在我看来)可读性较差:

this.id

它更慢,因为你必须旋转一个新的JS对象,只是为了用jQuery的方式检索属性。现在,如果你要使用$(this)来执行其他操作,那么无论如何,都要将jQuery对象存储在一个变量中并对其进行操作。然而,我遇到过许多情况,我只需要元素的属性(如idsrc)。

还有其他的惯例吗 像这样的吗?某些Javascript 可以完成操作 更简单,无需引入jQuery 混合。或者这是一种罕见的情况?( jQuery的“快捷方式”实际需要 更多的代码)< / p >

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

编辑: 在这里是一篇文章,解释了在attr()情况下使用jQuery的为什么比较慢。坦白:从标签维基上偷来的,但我认为这个问题值得一提。

编辑:考虑到直接访问属性的可读性/性能影响,我想说一个好的经验法则可能是尽可能使用this.<attributename>。在某些情况下,由于浏览器不一致,这种方法可能不起作用,但如果它不起作用,最好先尝试这种方法,然后再求助于jQuery。

  • this.id(如你所知)
  • this.value(在大多数输入类型上。我知道的唯一问题是IE,当一个<select>没有在它的<option>元素上设置value属性,或Safari中的无线电输入。)
  • 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 谢谢@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');

: < / s >

上面的措辞很糟糕。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(spans[0]),看起来我与外部while进行了一个无限循环,但因为我们处理的是“活动列表”,所以当我们执行parent.removeChild(span[0]);时,它会被更新。这是我们在使用数组(或类数组对象)时忽略的一个非常漂亮的特性。

已经有了一个公认的答案,但我相信这里直接输入的答案不能在本机javascript方法/属性列表中全面地保证跨浏览器支持。为此,请允许我把你引向quirkmode

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

它可能是关于在任何地方的任何浏览器上什么可以工作,什么不能工作的最全面的列表。请特别注意DOM部分。要读的东西很多,但重点不是全部读完,而是作为参考。

当我开始认真编写web应用程序时,我打印出了所有的DOM表,并把它们挂在墙上,这样我就能一眼知道哪些是安全的,哪些需要hack。这些天来,当我有疑问的时候,我就会谷歌一些类似quirksmode parentNode compatibility的东西。

和其他事情一样,判断主要是一种经验。我不建议你阅读整个网站,记住所有的问题来弄清楚什么时候使用jQuery,什么时候使用纯JS。只是要注意这个列表。搜索起来很容易。随着时间的推移,你会发现什么时候纯JS更可取。


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

$(this)不同于this:

通过使用$(this),你可以确保jQuery原型被传递到对象上。

第一个答案的活动属性列表this作为一个DOM元素是相当完整的。

你可能会觉得认识其他人也很有趣。

当这是文件时:

  • this.forms获取当前文档表单的HTMLCollection
  • this.anchors来获取所有设置了nameHTMLAnchorElementsHTMLCollection
  • this.links来获取设置了href的所有__abc2的HTMLCollection
  • this.images来获取所有__abc2的HTMLCollection
  • 与已弃用的小程序this.applets相同

当你使用document.forms时,document.forms[formNameOrId]会得到这样命名或标识的形式。

当这是一个表单时:

  • this[inputNameOrId]来获取如此命名或标识的字段

当这是表单字段时:

  • this.type来获取字段类型

在学习jQuery选择器时,我们经常跳过学习已经存在的HTML元素属性,因为它们访问起来非常快。

有一个框架叫做。你猜怎么着?Vanilla JS。希望你能听懂这个笑话……为了性能,它牺牲了代码的可读性。将它与下面的jQuery进行比较,你可以看到通过ID检索DOM元素几乎快了35 x。:)

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

Vanilla JS是一个快速、轻量级、跨平台的框架

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

enter image description here

和往常一样,这次聚会我要迟到了。

并不是额外的功能让我决定使用jQuery,尽管它很有吸引力。毕竟,没有什么能阻止您编写自己的函数。

事实上,在修改DOM以避免内存泄漏时,有很多技巧需要学习(我说的是你的IE)。有一个中心资源来为我处理所有这些问题,由比我优秀得多的JS程序员编写,不断地审查,修改和测试,这是上帝的恩赐。

我想这应该属于跨浏览器支持/抽象的观点。

当然,jQuery并不排除在需要时直接使用JS。我总觉得这两者似乎天衣无缝地配合在一起。

当然,如果您的浏览器不支持jQuery,或者您支持低端环境(旧手机?),那么一个大的.js文件可能是一个问题。还记得jQuery曾经很小的时候吗?

但通常情况下,性能差异并不是一个值得关注的问题。只要够快就行。由于每秒钟都要浪费千兆赫的CPU周期,我更关心编码员的性能,这是唯一不会每18个月功率翻一番的开发资源。

也就是说,我目前正在寻找可访问性问题,显然. innerhtml是一个有点不不。jQuery当然依赖于. innerhtml,所以现在我正在寻找一个框架,它将依赖于允许的一些乏味的方法。我可以想象这样的框架会比jQuery运行得慢,但只要它的性能足够好,我就会很高兴。

这里有一个非技术的答案——许多工作可能不允许某些库,比如jQuery。

事实上,谷歌不允许在他们的任何代码中使用jQuery (React也不允许,因为它属于Facebook),直到面试官说“对不起,你不能使用jQuery,它不在XYZ公司的批准名单上”,你才可能知道这一点。Vanilla JavaScript绝对可以在任何地方、任何时候工作,并且永远不会给你这个问题。如果你依赖于一个库,是的,你得到了速度和轻松,但你失去了通用性。

另外,说到面试,另一个缺点是,如果你在代码测试中说你需要使用一个库来解决一个JavaScript问题,它给人的印象是你实际上并没有理解这个问题,这看起来有点糟糕。然而,如果你用原始的JavaScript来解决它,这表明你实际上理解并可以解决任何摆在你面前的问题。