最近在开发中遇到一个 ESLint 规则问题:
obj.hasOwnProperty('key')
ESLint 给出错误提示:
Do not access Object.prototype method 'hasOwnProperty' from target object. eslint(no-prototype-builtins)
当时没想明白这个规则的设计点在哪里。根据其文字提示“不要从目标对象访问 Object 原型方法”,想到一种解决方案——直接找到这个方法,用 call 改变指向调用:
Object.prototype.hasOwnProperty.call(obj, 'key')
今天在想到原型链的时候突然意识到为何 ESLint 不允许从目标对象调用 Object 原型方法。
在 JS 中,往往通过改变原型链实现继承。一旦原型链发生改变,原先可以访问到的原型属性、方法便可能无法访问。考虑最极端的情况,若 obj 原先原型链的最顶端是 Object,此时可以通过原型链访问 Object.hasOwnProperty 方法;而若改变后,顶端不再是 Object,那么访问 obj.hasOwnProperty 访问就会得到 undefined。因此,直接从对象访问原型方法,很可能会带来隐藏的 BUG。
我采用的解决方法也是合理的,即直接在 Object 对象上调用其方法,利用 call 改变其 this 指向到我们的目标对象上,即可安全使用 hasOwnProperty 方法了。
虽然改变 this 指向的操作并不优雅,但目前我也没有更好解决方案了。