4

我知道这一定是非常基本的东西,但我不知道范围是如何工作的。我想要关闭变量在整个JavaScript文件中都是已知的。

我有类似的东西(在jQuery中):

var闭合=0;$(函数(){console.log(已关闭);});

但是关闭正在被记录为.我试过很多东西负载空载功能,但我失败了。

2
  • 关闭窗口.已关闭在全球范围内。不要全局定义变量。如果必须的话,把所有东西都包在IIFE里。 评论 2018年6月27日12:22
  • 它看起来像一个IIFE,您的外部变量在内部没有访问权限。 评论 2018年6月27日12:23

2个答案2

重置为默认值
5

问题:全局只读属性

首先,请注意,这个问题存在于Web环境中,即浏览器中。其他JS环境可能没有这个问题。

var闭合=0;在全局范围内,不会创建引用数字的绑定,而仍然是布尔值.

原因是关闭窗口已关闭在这种情况下;它总是一个布尔值,重新定义它会产生一个类似linter的警告“重新定义关闭.

这个只读属性指示引用的窗口是否已关闭。

在这些列表中可以找到这样的变量名:

过去在MDN上也有关于一个名为WindowOrWorkerGlobalScope,其属性将包含在此列表中;然而,这只是指两者都在窗口和中Worker全局范围.上下文的一小部分:MDN对他们的文档进行了重构,删除了所有这些“混合”,转而使用标准接口名称。你可以找到此列表的存档版本.

窗口Worker全局范围是两个接口全球This可以是Web环境中的的实例。

运行代码段以获取无法在全局范围内安全使用的变量名的完整列表:

const props=Object.entries(Object.getOwnPropertyDescriptors(globalThis)),不良={集合:(desc)=>desc,可配置:(desc)=>!描述,可写:(desc)=>!描述};数组.from(document.querySelectorAll(“[id]”)).forEach((span)=>span.innerHTML=道具.filter(([prop,{[span.id]:desc}])=>不需要的[span.id_](desc)).map(([prop])=>`<code>${prop}</code>`).join(“,”)
代码{背景:#eee;填充:1px 3px;}
<p>具有setter的属性,当设置值时,setter可能会更改类型或调用某些函数:</p><span id=“set”></span><小时/><p>不可配置的属性:</p><span id=“configurable”>(可配置)</span><小时/><p>只读属性:</p><span id=“可写”></span>

你会注意到,这是一个许多.它还有许多简短的通用变量名,如名称,长度 [1],[2],地位 [1],[2],自己,顶部,菜单栏、和起源.此外,关于在给setter赋值时调用某些函数,类似于var location=“Podunk,美国”;事实上重定向你去那个地方./Podunk,美国.

使用函数名有一个相关的问题,比如,选中的,自动完成,评价,或设置动画事件中属性,如onclick(单击):在那里,不仅仅是窗口属性包含在作用域链中,但也包含所有可确定范围的电流的整个原型链的特性HTML文档和当前特定的元素(例如,使用<a onclick=“”></a>提供从以下位置开始的所有访问权限HTMLAnchorElement.原型)也许还有更多,例如来自形式属性(表单元素的)(如果存在)。

所有这一切都在本文中解释对相关问题的回答.

依赖具有身份证件成为全球财产.

解决

有一些解决方案。我将按照从最好到最坏的主观顺序列出它们。

改用模块

将JavaScript代码运行为模块代替脚本不仅是一件很酷的事情,而且只是没有这个问题.

索引html:

<!DOCTYPE html><html lang=“en”><头部><元字符集=“UTF-8”><title>您的站点<script type=“module”src=“main.mjs”></script></头><body><!-- 内容。--></body></html>

main.mjs(主菜单):

const top={旋转:true},窗户={type:“透明”,框架:“木质”};let document={type:“LaTeX”,content:“\\documentclass[a4]{…}…”},闭合=0;var location=“Podunk,美国”;//所有这些都是上面定义的变量!console.log({top,window,document,closed,location});

模块还提供了一些其他有用的功能,如隐式延期关于DOM解析.

将所有内容包装在新范围内

在脚本的全局范围内,您将遇到此问题。在一个新的功能范围中,您没有这个问题:

(函数(){常闭=0;//或者`let`或`var`。$(函数(){console.log(已关闭);});})();

您还可以创建一个更有用的范围,例如jQuery的$(函数(){});等待加载DOM。这个顺便说一句,它可能是兼容性最高的选项,同时也是更好的选项之一。

因为我不使用jQuery,所以我更喜欢将所有内容包装在DOM内容已加载侦听器,我可以在其中确定所有需要的变量的范围,此外,还可以使用“使用严格”;:

addEventListener(“DOMContentLoaded”,()=>{“use strict”;//此处显示代码。});

这样可以避免全局属性和全局变量之间的冲突。

始终使用常数。如果你不能使用常数,使用。如果你不能使用,使用无功功率,无功功率.

……但你永远不需要无功功率,无功功率!1

使用常数在脚本中,作为安基特·阿加瓦尔的回答建议,缓解此问题:

常闭=0;console.log(已关闭);//0

然而,这只适用于变量名,但不是全部-常数闭合=123;让历史=“你好,世界!”;一切都有效,但常数窗口=123;,常量顶部=123;出租文件;不要。

1:虽然可能有单边外壳.显然,较旧的浏览器仍然需要无功功率,无功功率.

只需使用不同的变量名

听起来很明显,但这不是很稳健。

新的全局属性可能总是弹出,因此全局变量可能随时与它们冲突。因为这显然会破坏互联网上的几个脚本,所以现在添加的全局属性并不会产生太大问题。const history=“摄政时代”;工作正常历史可用作引用此字符串的变量。var历史=;仍然没有,它会抛出一个错误严格模式,并在松散模式下静默失败。这在历史上导致了兼容性问题哪个是为什么?这不是一个可靠的选项,尤其是在使用无功功率,无功功率这又是另一个有力的反对理由无功功率,无功功率.

再赋值较老的属性,例如文件,将失败脚本,在某些环境中,但每个变量名都将在模块,这就是为什么这是首选选项。

1
  • 我目前不明白为什么(至少)窗口,顶部文件常数在全局范围内使用。也许我或其他人可以解决这个问题,并完善这个答案中给出的解释。 评论 2020年4月6日19:10
0

使用而不是无功功率,无功功率作为关闭是JavaScript运行时使用的全局变量,以便使其在您可以使用的代码范围内成为局部变量而不是无功功率,无功功率它将变量设置为全局范围,并考虑全局关闭财产。

设闭合=0;$(函数(){console.log(已关闭);});
<script src=“https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js“></script>

  • 正是我需要的谢谢。
    – 用户9940465
    评论 2018年6月27日12:24
  • 1
    @MinirockAkeru这个答案没有解释为什么?你会得到尽管如此。并非所有变量都是这样。 评论 2018年6月27日12:34
  • 这在大多数情况下都不起作用。它适用于关闭,但不适合顶部,即使它们都是不可写的、可配置的、可枚举的、不可压缩的getter窗口. 评论 2020年4月6日18:41

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.