为了账号安全,请及时绑定邮箱和手机立即绑定

Array vs If 在索引 for 循环中的性能?

Array vs If 在索引 for 循环中的性能?

浮云间 2022-10-13 14:29:53
哪个性能更好?如果语句更具可读性,但是如果我在数组(数据库式)中创建值并让我的 for 循环根据当前索引调用函数,这使得进一步编辑变得更容易。var msg = [  "You are now viewing Tab number one",  "You are now viewing Tab number two",  "You are now viewing Tab number three",  "You are now viewing Tab number four"]var button = document.getElementsByTagName("button")for (var i = 0, len = button.length; i < len; ++i) {  (function(index) {    button[i].addEventListener("click",      function() {        document.getElementById("msg").innerHTML = msg[index];      });  })(i);}<button>Tab1</button><button>Tab2</button><button>Tab3</button><button>Tab4</button><br><p id="msg">Message here</p>var button = document.getElementsByTagName("button")for (var i = 0, len = button.length; i < len; ++i) {  (function(index) {    button[i].addEventListener("click",      function() {      if (index==0){        document.getElementById("msg").innerHTML = "You are now viewing Tab number one";      }      if (index==1) {        document.getElementById("msg").innerHTML = "You are now viewing Tab number two";      }      if (index==2) {        document.getElementById("msg").innerHTML = "You are now viewing Tab number three";      }      if (index==3) {        document.getElementById("msg").innerHTML = "You are now viewing Tab number four";      }      });  })(i);}<button>Tab1</button><button>Tab2</button><button>Tab3</button><button>Tab4</button><br><p id="msg">Message here</p>
查看完整描述

3 回答

?
喵喵时光机

TA贡献1846条经验 获得超7个赞

这就像问我的简单数字时钟应该使用哪种高端显卡?性能差异可以忽略不计。使用生活而不是let已经比您的实际问题产生更大的性能影响,而是数组索引与多个 ifs。


它仍然无关紧要。


关于选项,我发现它们都很难阅读,尤其是在按钮数量变大的情况下。


这个怎么样?


document.querySelector(".buttons").addEventListener("click", function(event) {

  const button = event.target.closest("button[data-msg]");

  if (button) {

    document.querySelector("#msg").innerText = button.dataset.msg;

  }

})

<div class="buttons">

  <button type="button" data-msg="You are now viewing Tab number one">Tab1</button>

  <button type="button" data-msg="You are now viewing Tab number two">Tab2</button>

  <button type="button" data-msg="You are now viewing Tab number three">Tab3</button>

  <button type="button" data-msg="You are now viewing Tab number four">Tab4</button>

</div>

<p id="msg">Message here</p>

海事组织 漂亮和声明性。并且易于扩展。

除了这些按钮之外,该条件if(button)还涉及您可能添加其他div.buttons可以单击的内容的可能性。

.closest("button[data-msg]")某些情况下,您可能会在可能触发事件的按钮内添加更多标记。我们想要<button data-msg="...">


查看完整回答
反对 回复 2022-10-13
?
MYYA

TA贡献1868条经验 获得超4个赞

对于 4 项,甚至 40 项,性能无关紧要:计算机速度非常快,而且列表非常短。更重要的是阅读和维护的难度。

表现

但值得研究一些潜在的性能原则,特别是在列表方面,因为小列表有变大的恼人趋势。

类似的数组查找button[i]常数时间或 O(1)。这意味着无论button获取多大的查找都将始终花费相同的时间。

而连续的 if 语句或 aswitch必须尝试每一个,直到找到匹配的一个。最好的情况i总是 0 并且必须比较 1 次。最坏的情况i总是 3,它必须比较 4 次。如果i分布均匀,则平均需要 2 次。这称为线性时间或 O(n),查找时间随着大小的增加而button增加。如果button变大两倍,则时间变长两倍。

随着数组查找button变大,性能将保持不变。随着 if 语句button变大,性能会变差。

可读性

现在,刚开始,你会发现线性代码更容易阅读。您会更喜欢按照执行顺序在页面上呈现所有内容。但是随着代码变得越来越复杂,这很快就会变得不堪重负,并且会导致大量的剪切和粘贴代码违反DRY 原则:不要重复自己。

有经验的程序员发现最好将尽可能多的细节推到其他地方,这样人们就可以清楚地看到重要的部分。重要的部分是它为每个添加消息的按钮生成单击处理程序msg。不重要的是该信息究竟是什么。

通过从循环中提取函数,您可以使代码更简单,并可能节省一些内存。

var addMsgListener = function(element, message) {

  element.addEventListener("click",

    function() {

      document.getElementById("msg").innerHTML = message;

    }

  )

};


var buttonMessages = [

  "You are now viewing Tab number one",

  "You are now viewing Tab number two",

  "You are now viewing Tab number three",

  "You are now viewing Tab number four"

]


var button = document.getElementsByTagName("button")


for (var i = 0, len = button.length; i < len; ++i) {

  addMsgListener(button[i], buttonMessages[i]);

}

请原谅我可能很糟糕的 Javascript。

现在很清楚该循环的作用,它为每个按钮添加了一个消息侦听器。如果我关心消息监听器是什么,我可以选择查看addMessageListener. 或者我可以跳过它。这使得代码“可略读”;人们可以阅读代码以了解它的作用,并且只在必要时深入了解细节。这不是线性阅读,但这是你会习惯并喜欢的东西。

请注意,addMsgListener不再指msg代也不button。这些是由使用它的循环选择的。它现在是通用的,可用于其他元素和消息。

更多的可重用性现在将展现出来;事件和 id 是否需要硬编码?这种在不改变代码的情况下改变代码的过程称为重构

维护

每次要更改消息时,都必须更改代码。如果要添加消息,则必须添加代码并重新编号。如果要删除消息,则必须删除代码并重新编号。如果要对消息重新排序,则必须重新编号。这需要开发人员进行 UI 更改。而且这个过程很容易出错,如果您删除了一条消息而忘记更改索引怎么办?

通过将消息放入数组中,您只需更改msg. 如果要添加消息,请在 中添加一行msg。如果要删除消息,请从 中删除一行msg。如果要对消息重新排序,请重新排序msg

msg不必存在于代码中,它可以进入配置文件,使非编码人员更容易更改。

远距离行动

这导致了我们的最后一个问题:msg需要与按钮的长度和顺序相同。每次更改 HTML 时,都msg可能需要更改,反之亦然。但是按钮及其消息位于不同的位置。这被称为远距离操作:更改代码的一部分会受到代码完全不同部分中的某些内容的影响。

为避免这种情况,您可以给每个按钮一个classorid并以此为它们的消息编制索引。这至少意味着按钮和消息不依赖于它们的确切顺序。如果您不确定哪些按钮将出现在 HTML 中,但希望为所有可能的按钮提供消息,这将很有用。

var msg = {

  car: "🏎",

  truck: "🚚",

  train: "🚆",

  plane: "✈"

}

你可以走另一条路;在 Javascript 中生成按钮及其消息。它仍然将有关每个按钮的所有信息保存在一起。如果按钮是动态的并且可以更改,这将很有用。

您可以按照 Thomas 的建议进行操作,并将消息附加到按钮本身。然后所有关于按钮的数据都在一起。如果您添加、删除或重新排序按钮,消息仍然有效。这允许人们只在 HTML 上工作。



查看完整回答
反对 回复 2022-10-13
?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

在这种情况下,使用tabindex或data-index属性可能是一个好主意。示例代码段不涉及循环并使用data-index.


var msg = [

  "You are now viewing Tab number one",

  "You are now viewing Tab number two",

  "You are now viewing Tab number three",

  "You are now viewing Tab number four"

]


document.body.addEventListener('click', (e) => {

  e.preventDefault();

  e.stopPropagation();

  if (e.target.tagName == 'BUTTON') {

    document.getElementById('msg').innerHTML = msg[e.target.dataset['index']];

  }

});

<button data-index="0">Tab1</button>

<button data-index="1">Tab2</button>

<button data-index="2">Tab3</button>

<button data-index="3">Tab4</button>

<br>

<p id="msg">Message here</p>

编辑


tabindex如果您将拥有大量选项卡,请尽量避免使用。以下部分摘自MDN


避免使用大于 0 的 tabindex 值。这样做会使依赖辅助技术的人难以导航和操作页面内容。相反,应按逻辑顺序编写包含元素的文档。


此外tabindex,最大值为 32767。


查看完整回答
反对 回复 2022-10-13
  • 3 回答
  • 0 关注
  • 110 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信