CoffeeScript中使用'in'检测Service Worker支持失效问题咨询
CoffeeScript
in 运算符的用法误区及问题解析 问题根源
你碰到的问题核心在于:CoffeeScript 的 in 和 JavaScript 原生 in 完全不是一回事。
- JS 原生的
'serviceWorker' in navigator是用来检测对象(包括原型链)是否包含指定属性; - 但 CoffeeScript 里写
'X' in Y,会被转译成[].indexOf.call(Y, 'X') >= 0——这是专门用来检测数组里有没有某个元素的逻辑。
navigator 是普通对象不是数组,indexOf.call(navigator, 'serviceWorker') 会把它当成类数组对象,去遍历数字索引对应的“元素”,自然找不到字符串 'serviceWorker',所以条件永远不成立,才会输出错误提示。
CoffeeScript in 的正确使用场景
in 在 CoffeeScript 里只能用来检测数组(或类数组对象)的元素是否存在,比如:
fruits = ['apple', 'banana'] if 'apple' in fruits console.log '苹果在列表里'
这种场景下转译后的代码逻辑是对的,没问题。
检测对象属性的正确姿势
要判断对象有没有某个属性,CoffeeScript 里应该这么写:
- 直接判断属性是否存在(适合属性值不会是
null/undefined的情况,比如你这个 Service Worker 的场景):if navigator.serviceWorker # 注册 Service Worker 的逻辑 - 用
hasOwnProperty检测对象自身的属性(排除原型链上的属性):if navigator.hasOwnProperty 'serviceWorker' # 注册逻辑 - 用可选链处理可能的空值(CoffeeScript 支持可选链语法):
if navigator?.serviceWorker # 注册逻辑
关于 in 的安全性
in 本身是安全的,但你必须搞清楚它的适用场景——只用来检测数组/类数组的元素。要是误用在普通对象上,转译后的代码逻辑就会和你的预期完全不符,就像你这次遇到的情况一样。
内容的提问来源于stack exchange,提问作者John Deighan
相关产品推荐
相关产品推荐

