编程语言
首页 > 编程语言> > javascript – 如何避免意外隐式引用全局对象上的属性?

javascript – 如何避免意外隐式引用全局对象上的属性?

作者:互联网

是否可以在没有默认情况下所有脚本似乎具有的隐式with(全局)上下文的情况下执行代码块?例如,在浏览器中,是否有任何方法可以设置脚本,例如

const foo = location;

Uncaught ReferenceError: location is not defined

而不是访问window.location,当尚未首先声明位置?缺乏这种方法,这种隐式引用是否有可能导致某种警告?在编写代码时它可能是错误的来源(见下文),因此有办法防范它可能是有用的.

(当然,由于普通的作用域规则,可以使用const或let或在内部块中声明另一个具有相同名称的变量,以确保使用该变量名称引用新变量而不是全局属性,但这是不一样的.)

这可能类似于询问是否可以从实际的with语句中停止引用属性:

const obj = { prop: 'prop' };
with (obj) {
  // how to make referencing "prop" from somewhere within this block throw a ReferenceError
}

众所周知,不应该首先使用它,但遗憾的是,当涉及到(全局)时,似乎我们别无选择,它偶尔会节省一些字符,而不会出现频繁出现的混乱错误:1 2 3 4 5 6.例如:

var status = false;
if (status) {
  console.log('status is actually truthy!');
}

(这里的问题:window.status是一个保留属性 – 当分配给它时,它将指定的表达式强制转换为字符串)

这些类型的错误与劝阻或禁止明确使用with的原因相同,但隐含的(全局)继续引起问题,即使在严格模式下也是如此,因此找出解决方法将是有用的.

解决方法:

在尝试回答这个问题之前,您需要考虑一些事项.

例如,使用Object构造函数.这是“Standard built-in object”.

window.statusWindow interface的一部分.

显然,您不希望status引用window.status,但是您是否希望Object引用window.Object?

您无法重新定义问题的解决方案是使用IIFE或模块,这应该是您正在做的事情.

(() => {
  var status = false;
  if (!status) {
    console.log('status is now false.');
  }
})();

为了防止意外使用全局变量,我只想设置你的linter来警告它.使用像(fake_global)这样的解决方案强制它不仅会在运行时出现错误,这可能会被捕获,但也会变慢.

特别是对于ESLint,我似乎找不到“好”的解决方案.启用浏览器全局变量允许隐式读取.

我建议no-implicit-globals(因为你不应该污染全局范围,它会阻止var状态没有定义任何问题),也不会启用所有浏览器全局,例如,窗口,文档,控制台,setInterval等就像你在评论中说的那样.

查看ESLint environments以查看您要启用的功能.默认情况下,Object和Array之类的东西都在全局范围内,但是上面列出的那些和atob不是.

要查看全局变量的确切列表,它们由this file in ESLintthe globals NPM package定义.我会选择(es6),“worker”或“shared-node-browser”(的组合).

eslintrc文件将具有:

{
    "rules": {
        "no-implicit-globals": "error"
    },
    "globals": {
        "window": "readonly",
        "document": "readonly"
    },
    "env": {
        "browser": false,
        "es6": [true/false],
        "worker": [true/false],
        "shared-node-browser": [true/false]
    }
}

标签:with-statement,javascript,scope
来源: https://codeday.me/bug/20190926/1818707.html