首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >缓存与.querySelector

缓存与.querySelector
EN

Stack Overflow用户
提问于 2016-02-25 01:58:03
回答 1查看 1.5K关注 0票数 0

我们很早就学会了缓存选择器。他们都说,只要查一次就行了。

我想知道这个想法是如何与.querySelector一起工作的。

假设我想在我刚才点击的元素下面找到一个元素。js应该是这样的:

this.querySelector('.toggle-this-content').classList.toggle('open')

所以我点击一个按钮,它会切换下面的内容来打开。这是昂贵的选择吗?我可能应该适当地进行授权,这样我就可以说:

toggleThisContent.classList.toggle('open')

在我使用的函数中,但是我想知道.querySelector的使用是糟糕的实践还是A-Ok。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-25 02:59:44

你用“昂贵”这个词,你用“坏习惯”。然而,这两者并不是同义词。一些东西可能是昂贵的,但良好的做法;或便宜,但糟糕的做法。或者,您可以重新定义“昂贵”一词,意思不仅是某些东西需要大量的CPU周期,而且还需要大量的人工周期来编写、读取、调试、扩展和维护。

请考虑以下几点:

代码语言:javascript
复制
function foo(sel) { 
  if (document.querySelector(sel)) document.querySelector(sel).classList.add('bar');
}

正如您所建议的,大多数经验丰富的程序员可能更喜欢

代码语言:javascript
复制
function foo(sel) { 
  let elt = document.querySelector(sel);
  if (elt) elt.classList.toggle('bar');
}

但实际上,原因与性能无关,尽管这个版本的性能可能会稍微好一些(我的意思是,更快几十微秒,很可能)。这是可取的,因为它不是重复的。程序员意图“检索sel选择的元素”的一个方面在一个querySelector调用中精确地表示了一次。代码更短,而且不太容易打字。看上去更可读性。

让我们以另一种情况为例,在代码的不同部分执行特定的querySelector,如下

代码语言:javascript
复制
function x1() {
  document.querySelector('.c1').classList.toggle('x1');
}

function x2() {
  document.querySelector('.c1').classList.toggle('x2');
}

在这种情况下,安排只执行一个querySelector('.c1')需要计算并将元素保存在两个调用中任何一个都可用的位置--就像一个简单的例子:

代码语言:javascript
复制
let x = function() {
  let elt = document.querySelector('.c1');
  return { 
    x1: function() { elt.classList.toggle('x1'); },
    x2: function() { elt.classList.toggle('x2'); }
  };
}();

x.x1();

您已经成功地将对querySelector的调用减少到一个,这将节省几十微秒,但代价是代码要复杂一些。

因此,在这种情况下,如果其他一切都是平等的,如果是查看原始代码(两个单独的函数调用),并询问将其重构为第二个片段(IIFE)有多重要,答案将是“几乎一点都不重要”。

这并不是说,在更高的层次上重构这一点并不是一个好主意。您使用的反模式是将DOM操作代码绑定到特定类(或者在其他常见情况下是ID)。在这种模式中,程序员使用it和类作为引用DOM元素的一种变量名,在任何需要获取实际元素的地方,都可以使用getElementByIdgetElementsByClassNamequerySelector从巨大的全局DOM命名空间中一次又一次地检索它。最好使用存储在变量中的DOM元素来引用DOM元素,并将这些变量通过ID或类映射到代码的一个部分中尽可能小的表面积。这不是性能问题,而是良好的代码结构问题。例如,通过这种方式,您可以在HTML中重命名类c1,并且代码中只有一个需要更改的位置。当然,这需要安排您的代码,以便在需要时可以使用变量。但是这和安排代码不使用全局变量并没有什么不同--因为querySelector('.c1')是一种全局变量--无论如何,这都是你应该做的事情。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35616837

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档