while 条件中的赋值表达式是一种不好的做法?
Posted
技术标签:
【中文标题】while 条件中的赋值表达式是一种不好的做法?【英文标题】:Assignment expression in while condition is a bad practice? 【发布时间】:2016-04-10 14:54:42 【问题描述】:This article 解释了为什么我在使用这样的代码时会收到警告:
var htmlCollection = document.getElementsByClassName("class-name"),
i = htmlCollection.length,
htmlElement;
// Because htmlCollection is Live, we use a reverse iteration.
while (htmlElement = htmlCollection[--i]) // **Warning?! Why?!**
htmlElement.classList.remove("class-name");
但这没有解释«为什么在while条件下赋值表达式是一种不好的做法? »。
我还阅读了这个*** answers,指出这种做法同样好。所以...
while (element = element.parentNode)
语法有性能问题还是只是样式代码建议?
顺便说一句,似乎«--i » 运算符也是一种不好的做法。我read in this article:
众所周知,++(递增)和 --(递减)运算符会通过鼓励过多的技巧来导致不良代码。
这是什么玩笑?
【问题讨论】:
【参考方案1】:它应该没有性能问题(可以说,由于 CPU 管道的问题,使用前缀增量的索引可能比后缀增量稍慢;这是一个微优化,非常微不足道,几乎可以肯定它在上下文中毫无意义JS 引擎开销,即使在 C 语言中,编译器也可能会重新排序表达式,以确保它不会因等待增量而停滞)。
无论哪种方式,反对条件赋值的主要论点基本上是大多数当你这样做时,这是一个错误(你的意思是==
或在JS中,===
) .如果您将分配包装在额外的括号中,那么某些代码检查器(C# 要求将其作为语言功能以避免事故)会感到满意,例如“是的,我真的打算分配”(当您'重新将分配的结果与其他值进行比较;省略括号会改为比较,然后分配一个布尔值,这更可能是错误的)。
有些人讨厌用作较大表达式的一部分的递增/递减运算符,因为我猜很难记住操作的顺序,而且众所周知,C 程序员会写出可怕的东西,比如++*++var
之类的东西。我忽略了这些人;只是不要将它用于过于棘手的事情。
【讨论】:
这表明你有“可能”使用=
而不是==
出错。但是关于赋值性能(不是前缀/后缀增量性能),也没有性能问题?
@Haeresis:它可能存在的任何问题都可以忽略不计,或者通过编译器在任何合理的现代 JS 引擎上重新排序来消除。唯一可能帮助(配置文件!)的事情是显式测试while ((htmlElement = htmlCollection[--i]) !== undefined)
,这可能为 JS JIT-er 提供足够的信息以将表达式优化为简单的指针比较,但同样,在 JS 开销的情况下,这是一个不太重要的微优化。
谢谢,我没问题。【参考方案2】:
作为一种正交方法,并且可能“更清晰/更清晰”:
// var htmlCollection = document.getElementsByClassName("class-name");
var htmlCollection = document.querySelectorAll('.class-name');
for(let htmlElement of htmlCollection)
htmlElement.classList.remove("class-name");
作为一种遍历 DOM 元素的方法。
已更新以包含来自以下 ShadowRanger 的建议。
【讨论】:
这个方法不是反向迭代吗?所以我不能在这种特殊情况下使用它,因为如果我删除class-name
,该项目将从 Live htmlCollection 中删除,下一个项目不是 n+1 而是 n+2。也许of
避免这种情况,但我不这么认为。
@Haeresis:这并不能避免。另一方面,切换到document.querySelectorAll('.class-name')
会避免它,because the NodeList
returned by that function is a snapshot, not a live view。
是的。只是更慢(codepen.io/Haeresis/pen/epQLBG 和 codepen.io/Haeresis/pen/epQLve);p 谢谢!
而用这个 ES6 of
代替 in
,是不是需要用一些hasOwnProperty
检查?
@Haeresis:那个测试不是苹果对苹果;您的 querySelectorAll
正在执行基于后代的额外过滤;这会花费时间,而且您不会弥补,因为您从不使用结果(大概您必须手动执行子查询才能获得每个 .vanilla
的 .inner div
后代。querySelectorAll
几乎如果您要跟进 getElementsByClassName
对每个结果的子查询,肯定会赢得 getElementsByClassName
。以上是关于while 条件中的赋值表达式是一种不好的做法?的主要内容,如果未能解决你的问题,请参考以下文章