我正在重构别人编写的一些代码。有一个函数使用:
!!('ontouchstart' in window)
Run Code Online (Sandbox Code Playgroud)
我已经在其他项目中看到过它:https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js#L40 在 Stackoverflow 答案中: https: //stackoverflow.com/a /4819886/1127635
但它似乎可能比替代方案慢:http://jsperf.com/hasownproperty-vs-in-vs-undefined/12
那么为什么要使用这种可能较慢的替代方案呢?哪些浏览器不支持其他解决方案?
您的两个替代测试都在某种程度上存在缺陷:
window.ontouchstart !== null对非null听众进行测试。测试 的值ontouchstart是一种有风险的方法,因为库或其他代码可能会更改 的值ontouchstart。测试该值是一个不好的方法;最好测试该属性本身是否存在,这将我们带到您提出的下一个测试......
window.hasOwnProperty('ontouchstart')测试window对象是否有自己的ontouchstart属性。在某些浏览器中(我刚刚在 Chrome 37 和 IE9 上确认了这一点),window 没有自己的on-event 属性;相反,它们是 的属性window.__proto__。
我们不应该测试某个值(因为之前的代码可能在运行我们的代码之前更改了该值),并且我们无法测试window自己的属性,因为浏览器对 中事件侦听器属性存在位置的实现有所window不同原型链。因此,我们最一致的选择是测试该属性是否存在于window原型链中的任何位置(无论其值如何)。这正是我们对in运算符所做的事情。
当然,如果其他人的代码在我们的测试之前运行,他们可以ontouchstart在原来没有的地方添加一个属性。绝对严格地测试对事件的支持根本不可能,而且这是一件糟糕的事情。