JSLint错误:意外的“in”。与undefined进行比较,或使用hasOwnProperty。

20

我有一个以下的 JavaScript 函数,不符合 jslint 检查:

  function hasActiveX() {
    return ('ActiveXObject' in window);
  }

jslint错误

Unexpected 'in'. Compare with undefined, or use the hasOwnProperty method instead.

我应该忍受jslint错误吗?还是有更好的方法确定ActiveXObject?我找不到跳过此检查的jslint标志。

2个回答

21
忽略错误。 "in"运算符在ECMA 262-5.1 / June 2011 sec-11.8.7中定义明确。 'someProperty' in anObject只有三种结果: truefalse或抛出 TypeError 异常。当评估结果为true时,肯定存在'someProperty' in anObject。当评估结果为false时,肯定不存在'someProperty' in anObject。当抛出 TypeError 时,肯定不存在'someProperty' in anObject,因为anObject要么为空,要么根本不是对象。这一切对我来说似乎非常清楚。当我想知道一个对象是否具有属性,并且我不关心该属性是对象自己的属性还是被继承的属性,也不关心属性的值是什么时,我只需查找'someProperty' in anObject即可。

警告

注意:有些人会让你检查anObject.someProperty !== undefined,但这并不是真正检查对象是否具有该属性。它所做的是检查对象是否具有该属性该属性的值不是undefined。有些人会让你检查anObject.hasOwnProperty('someProperty');,但这只会告诉你对象是否具有该属性没有以某种方式继承它。不相信我?试试下面的内容:
console.log(document.body.tagName);
// BODY

console.log(document.body.hasOwnProperty('tagName'));
// false, it's inherited

console.log('tagName' in document.body);
// true, it does have the property

document.body.wobbles = undefined;
// new property added to document.body

console.log('wobbles' in document.body);
// true, it does have the property

console.log(document.body.wobbles !== undefined);
// false, the value really IS undefined

我写了一篇关于“in”运算符的文章,更详细的内容可以参考这里: http://matthewkastor.blogspot.com/2012/09/Unexpected--in---Compare-with-undefined--or-use-the-hasOwnProperty-method-instead.html 底线是,如果对象可能为null或不是对象,则应忽略此错误并在try catch块中封装它们。

function hasProperty(prop, obj) {
    try {
        return prop in obj;
    } catch(e) {
        return e;
    }
}

这是一个关于为什么应该使用 in 的很好的讨论。但是,你有没有想过为什么 JSLint 认为你不应该使用它?如果你不知道 JSLint 为什么建议不要使用它,那么你就不知道是否在解决它的问题。 - algal
4
是的,我知道为什么JSLint会发出警告并且这个警告不能被忽略。上面的帖子解释了“in”的用法以及为什么可以安全地忽略它。简单来说,警告是出于性能方面的考虑。如果你期望属性直接分配给特定的对象,那么搜索整个原型链就没有意义了。使用“in”而不带“hasOwnProperty”保护并不是真正的错误,也没有任何有害的副作用。 - Kastor

17

我认为JSLint建议您尝试:

function hasActiveX() {
    return window.hasOwnProperty('ActiveXObject');
}

或者另一个建议是将其与 "undefined" 进行比较:

return (typeof(window.ActiveXObject) != "undefined");

在阅读评论后,看起来如果JSLint不再抱怨它,in实际上是有用的,否则我会尝试上面的第二个选项。


6
IE <= 8 中,调用 window.hasOwnProperty 将失败,因为全局对象不继承 Object.prototype(例如 Object.prototype.isPrototypeOf(window); // false)。您需要间接调用它,例如 Object.prototype.hasOwnPrototype.call(window, 'ActiveXObject');。但是,就像 @missingno 所说的那样,不能保证该方法是一个自有属性,它可能在全局对象的原型链上声明(这完全取决于实现),通常对于测试主机属性,使用 in 运算符是有用的... 来吧,JSLint,别伤害我们的代码 :P - Christian C. Salvadó
3
typeof !== undef 是没有意义的,只需检查属性是否为 undefined:return window.ActiveXObject !== undefined; - Matt Esch
1
@MattEsch typeof !== undefined并不是无用的,因为在ES5严格模式之外,undefined可以很容易地被重新赋值,而var x !== undefined检查可能会失败,这就是typeof的原因 :) - ArtoAle
1
@ArtoAle 我猜从技术上讲它不是无用的,但实际上它是。如果有人重新定义了未定义的内容,那么你会遇到更严重的问题。这不仅仅是在严格模式下undefined是只读的要求,如果你想确保undefined,你总是可以使用void 0 - Matt Esch
1
@MattEsch,当然……但是(不考虑void 0通常被认为是不好的做法,因为它可能会令人困惑),这是实现相同结果的另一种技术,我不明白为什么要将其标记为“无用”。 - ArtoAle
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接