& =运算符在javascript中减少布尔值

时间:2014-10-21 00:22:58

标签: javascript

我正在尝试使用惯用的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]); ......我想知道哪种方式最快?

3 个答案:

答案 0 :(得分:2)

我在谷歌的Chrome团队工作。我没有直接使用JavaScript引擎,但我确实知道如何实现DOM。

我怀疑x &= y != -1x &= !!~y之类的差异会显着影响此循环的效果。可能y != -1更好。以下事情可能更重要:

  • pass为false时,通过提前退出来执行较少的循环迭代。
  • 查看其他DOM API是否更有效。例如,使用Element.classList.contains而不是indexOf来测试元素是否具有特定的类名。或者,根据您要定位的浏览器,构建一个CSS选择器并使用Element.matches来测试每个元素是否与选择器匹配。
  • 使用分析器(Chrome has one built in)来衡量您的脚本并直接测量速度和速度。

答案 1 :(得分:0)

&=运算符是按位运算符。它会将两个操作数转换为32位整数,并对它们进行按位和操作。

您宁愿使用&&运算符,它是逻辑运算符:

pass = pass && cn.indexOf(clasz[i]) != -1;

&&执行短路评估,因此只要pass变为假,它就会停止评估第二个操作数。

答案 2 :(得分:0)

您可以使用console.time或仅在几百次迭代中比较日期之前和之后的两个。

虽然你也应该把浪费时间的可能性考虑在内,以免失去可读性。