问题:全局只读属性
首先,请注意,这个问题存在于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历史=
…;
仍然没有,它会抛出一个错误严格模式,并在松散模式下静默失败。这在历史上导致了兼容性问题哪个是为什么?这不是一个可靠的选项,尤其是在使用无功功率,无功功率
这又是另一个有力的反对理由无功功率,无功功率
.
再赋值较老的属性,例如文件
,将失败脚本,在某些环境中,但每个变量名都将在模块,这就是为什么这是首选选项。