从 JS 中的 id 自动创建变量?

IT技术 javascript
2021-01-17 10:58:15

就在今天,经过几年的 javascript 编程,我遇到了一些让我震惊的事情。浏览器为每个具有 id 的元素创建对象。对象的名称将与 id 匹配。

所以如果你有:

<div id ="box"></div>

你可以做:

alert(box); //[object HTMLDivElement]

无需先为该变量分配任何内容。请参阅演示

这出于某种原因似乎在标准中,即使它在某些情况下可能会破坏代码有一个开放的错误可以结束这种行为,但我现在更想摆脱它。

你们知道是否有办法禁用此功能(可能是严格模式)?我是否过于重视这一点?因为这显然是个坏主意。(是IE引入的,给大家一个提示)。

更新:似乎 FF 仅在怪癖模式下执行此操作。其他浏览器(如 IE6+ 和 Chrome)可以立即执行此操作。

6个回答

ECMAScript 5 strict 应该对此有所帮助,因为您不能使用未声明的变量我不确定当前哪些浏览器支持严格模式,但我知道 Firefox 4 支持。

您链接的 HTML 规范提到了通过将此行为限制为 quirks-only 来减少全局范围污染的建议

我不知道这个特性是否在原始规范中,但我确实希望它在 ECMAScript 的后续版本中被删除、禁止或以其他方式无效。ES6 将严格基于 ES5。

JavaScript 有许多特性可以让初学者和新手更容易使用,我怀疑这就是这样的特性之一。如果您是专业人士,并且希望使用高质量的代码"use strict";并始终使用JSLint您的代码。如果您使用这些指南,则此功能永远不会打扰您。

这是YUI Theatre 提供的有关 ES5 的有用视频(虽然它已经 2 岁了,但目前仍然相关,因为还没有 ES6)。

5年后它仍然存在
2021-03-15 10:58:15
8年后,它仍然存在!
2021-03-15 10:58:15
6年后,它仍然存在!
2021-03-18 10:58:15
严格模式与此没有区别。
2021-04-02 10:58:15
7年后,它仍然存在!
2021-04-07 10:58:15

我不认为这有什么大不了的。特别是对于我们这些考虑全局命名空间污染和冲突的人来说,这似乎很混乱,但实际上它并没有真正引起问题。

如果您声明自己的全局变量,它只会覆盖浏览器为您创建的任何内容,因此实际上没有任何冲突。我能看到它可能导致问题的唯一地方是,如果您正在测试是否存在全局声明和基于对象 ID 的“自动”全局,这妨碍了它并使您感到困惑。

在实践中,我从未认为这是一个问题。但是,我同意这似乎是他们应该摆脱或允许您关闭的东西。

是的,大多数浏览器都会这样做,但又像你说的那样,有些浏览器不会(firefox),所以不要指望它。在 js 中覆盖这些变量也很容易,我可以想象某些东西container可能会被使用该变量的人直接覆盖,而无需先声明它。

没有办法在 chrome afaik 中解决这个问题,但即便如此,解决这个问题并为所有浏览器修复它也可能很麻烦。

不要太重视它,但要小心。这就是为什么要逃避变量的全局范围的原因之一。

为了完成起见,这些浏览器默认是这样做的:Chrome, IE9 & compat, Opera

更新:ECMAScript 的未来版本可能包含某种选项,因为讨论正在进行中,但这不会解决旧浏览器中的“问题”。

四年后,但就其value而言,现代 Firefox确实做到了这一点。我很惊讶(也很害怕)发现我们网站中有相当大的代码块,在几个页面上使用,依赖于它,但我们没有任何关于它的错误报告。因此,它似乎是可靠的——无论如何,就目前而言。当然,在我的团队中,我并不是唯一一个对这一发现感到恐惧的人,我们肯定会在下一次机会中重构它,因为我们也不相信它,但它的value是什么。
2021-03-16 10:58:15

我认为没有办法禁用它,但您不需要太重视它。如果你害怕不可预知的错误,你可以通过使用避免它们JSHintJSLint的他们将帮助您避免错误。例如,如果您使用未声明的变量,他们会警告您。

这里的问题是浏览器在运行时定义了全局作用域中的对象,您希望防止这些定义干扰您的代码。我不知道关闭这种行为的方法,但我有两种解决方法供您使用:

1)正如您链接到的文章中所建议的,您可以通过确保在使用之前定义每个变量来解决此问题。我将通过通过JSLint运行我的代码来实现这一点,它会警告这类事情(除了一堆其他常见错误)。

2) 但是,由于可能会忘记通过 JSLint 运行您的代码,因此您可能更喜欢工具链中无法忘记的步骤。在这种情况下,请查看CoffeeScript - 它是一种与 javascript 非常相似的语言,您在使用前将其编译为 javascript,它会var为您插入正确的定义。事实上,我怀疑您无法编写依赖于使用 CoffeeScript 自动创建元素变量的代码。

我已经向我的 SVN 服务器添加了一个提交后钩子,它将.js使用 JSLint验证所有文件。很有用。
2021-04-03 10:58:15