在zepto的源代码中,我发现在zepto.matches函数中,有一个回退执行,
zepto.matches = function(element, selector) { if (!element || element.nodeType !== 1) return false var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector || element.oMatchesSelector || element.matchesSelector if (matchesSelector) return matchesSelector.call(element, selector) // fall back to performing a selector: var match, parent = element.parentNode, temp = !parent if (temp) (parent = tempParent).appendChild(element) match = ~zepto.qsa(parent, selector).indexOf(element) temp && tempParent.removeChild(element) return match }
尽管匹配选择方式正常,但我对后备非常好奇,为什么在前面添加〜:
~zepto.qsa(parent, selector).indexOf(element)
document.getElementById("test"); $.zepto.matches(a,"#test") // -1
它返回-1,是对还是我错过了什么?
答案 0 :(得分:0)
这是Bitwise NOT operator。在这种情况下,它用于indexOf
的布尔返回值:indexOf
方法(数组,字符串),如果找不到匹配则返回-1,如果找到匹配则返回位置。当然,这个职位也可以是0。所以使用按位NOT运算符:
console.log(~-1); // 0
console.log(~0) // -1
console.log(~1) // -2
// and so on
因为在JS 0
中被视为“Falsy”值,而除了NaN
- 之外的任何其他数字都是“Truthy”值,~zepto.qsa(parent, selector).indexOf(element)
将返回{{ 1}}如果找不到该元素,因此可以在代码中线程有一个“Falsy”值:
0
但是,在这种情况下,我希望zepto方法返回一个真正的布尔值,因为它是一个API方法。在这种情况下,我更愿意使用:
var isFound = ~zepto.qsa(parent, selector).indexOf(element);
if (isFound) {
// do something
}
或者
match = zepto.qsa(parent, selector).indexOf(element) > -1;
它用于具有正确布尔表示的双match = !!~zepto.qsa(parent, selector).indexOf(element);
:如果!
返回indexOf
,-1
将其转换为~
,则第一个0
中的!
和true
中的第二个,即我们期望“未找到”的布尔值。
Bitwise NOT它也用于其他一些技巧,比如这个:
false
此代码返回var words = ["a", "b", "c", "b", "b"];
var frequency = words.reduce(function(freq, word) {
freq[word] = -~freq[word];
return freq;
}, {})
之类的对象;它基本上计算数组中相同字符串值的频率。这里的Bitwise NOT与Unary Negation operator一起用于增量计数器:所以如果{a:1, b:3, c:1}
是freq[word]
- 因为这个词还没有在“词典”中 - 那么{{1是} undefined
,而一元否定因为~undefined
。下次我们将-1
,因此1
,-~1
;然后- -2
将为2
,依此类推。
按位运算符非常有用,但也更容易被滥用。在某些情况下是必要的(例如,Zero-fill right shift它是目前JS中替换-~2
)的唯一方式,但它们不是,并且它们可能导致代码难以阅读。
但他们绝对值得被人知道。