我正在尝试使用惯用的C风格编写一个高效的函数,并且我对正确性性能有一些关注好奇心。
我有一个函数,它接受类字符串列表,它的作用是将DOM层次结构与节点字符串列表相匹配。仅当所有类字符串与元素的className
道具匹配时,检查才会通过。
所以......
function nearestParent(elem, clasz, stopat) {
// stopat can be used to stop the search short. For speed.
// make sure you do not use jquery elements
if (typeof clasz === 'string') { clasz = [clasz]; }
do {
elem = elem.parentNode;
for(var i=0,l=clasz.length,pass=true, cn=elem.className;i<l;++i) {
pass &= ~cn.indexOf(clasz[i]);
}
if(pass) return elem;
} while (elem && elem != stopat);
}
你在这里看到的for循环基本上是使用indexOf
检查字符串匹配。然而,我看到的缺陷是,如果indexOf返回的值是奇数,则pass被设置为错误的值:~3 & 1
= 0
。
所以看起来正确的实现方式是pass &= cn.indexOf(clasz[i]) != -1;
或者pass &= !!~cn.indexOf(clasz[i]);
......我想知道哪种方式最快?
答案 0 :(得分:2)
我在谷歌的Chrome团队工作。我没有直接使用JavaScript引擎,但我确实知道如何实现DOM。
我怀疑x &= y != -1
和x &= !!~y
之类的差异会显着影响此循环的效果。可能y != -1
更好。以下事情可能更重要:
pass
为false时,通过提前退出来执行较少的循环迭代。答案 1 :(得分:0)
&=
运算符是按位运算符。它会将两个操作数转换为32位整数,并对它们进行按位和操作。
您宁愿使用&&
运算符,它是逻辑运算符:
pass = pass && cn.indexOf(clasz[i]) != -1;
&&
执行短路评估,因此只要pass
变为假,它就会停止评估第二个操作数。
答案 2 :(得分:0)
您可以使用console.time或仅在几百次迭代中比较日期之前和之后的两个。
虽然你也应该把浪费时间的可能性考虑在内,以免失去可读性。