【问题标题】:Can I Use an ID as a Variable Name?我可以使用 ID 作为变量名吗?
【发布时间】:2011-10-14 17:41:51
【问题描述】:

我觉得设置一个与元素id同名的变量比较方便,例如:

randomDiv = document.getElementById("randomDiv");
  randomDiv.onclick = function(){ /* Whatever; */ }
  randomDiv.property = "value";

这适用于 Chrome 和 Firefox,但不适用于 IE8;给出错误对象不支持此属性或方法

创建一个名称与元素 ID 匹配的变量是错误的(或不好的做法)还是 Internet Explorer 的另一个实例在起作用?

【问题讨论】:

  • 如果你var randomDiv = document.getElementById("randomDiv);,它在IE中可以工作吗?
  • 我不明白为什么这行不通

标签: javascript variables syntax


【解决方案1】:

自动生成全局变量被认为是不好的做法,因为查看一些代码可能很难分辨,是故意还是忘记在某处声明变量。自动创建像 doesn’t work in ES5 strict mode 这样的全局变量,并且可以在未来的 ECMAScript 版本中逐步淘汰。

在浏览器中JavaScript的全局作用域实际上是window。当您引用document 时,您会得到window.document。在浏览器中创建全局变量的最佳实践是将其添加到window(Node.js 中的global)。这里是an example from jQuery

window.jQuery = window.$ = jQuery;

window 上的某些属性(因此一些全局变量)是只读的,您无法覆盖它们。 window.document 是其中之一(在 Chrome 中测试,这都是特定于浏览器的,可能会改变):

window.document; // → Document
window.document = 'foo'; // → "foo" // It worked!
window.document; // → Document // Hmm, no it didn’t

事实证明大多数浏览器在 window 上为文档中的每个 id 创建属性(因此是全局变量)。许多浏览器不会将它们设为只读,您可以用自己的方式覆盖它们,但 Internet Explorer 会。

这是 JavaScript 中的全局变量可能很危险的另一个原因 - 您的一个 id 可能匹配只读的 window 属性(现在或将来的某些浏览器中)。

在顶层(不在函数内部),var 声明了全局变量。在顶层声明 var document = 'foo' 不会引发错误,但 document 仍将是 Document,而不是 "foo"

顺便说一句:新式浏览器(支持 ES5)允许您使用 Object.defineProperty 创建自己的只读全局变量:

Object.defineProperty(window, 'foo', { value: 'bar', writable: false });
foo = 'baz';
foo; // → "bar"

我为你准备了三个选项。

  1. 继续为您的元素使用全局变量,但如果它们已经存在则不要管它们(在window 上显式创建它们,这样代码在 ES5 中既清晰又酷):

    if ( ! window.randomDiv) {
        window.randomDiv = document.getElementById('randomDiv');
    }
    
  2. window 上创建一个对象,用作应用程序自己的命名空间,它不会干扰其他库或浏览器。这很常见,被认为是非常好的做法,尤其是在需要跨 JavaScript 文件访问时:

    // Early in your code…
    window.Fantabulum = {};
    // Later on…
    Fantabulum.randomDiv = document.getElementById("randomDiv");
    
  3. 避免制作全局变量。确保您的应用程序代码在函数内部(它应该已经存在,因此您的其他变量不是全局的并且没有相同的限制!),并为您的元素声明变量:

    (function(){
        var randomDiv = document.getElementById("randomDiv");
    })();
    

【讨论】:

  • 对建议 3 的一点评论:与您所拥有的代码完全相同的代码会在大多数浏览器中导致语法错误,因为它将是 parsed as a function statement,而不是作为函数 表达式,函数语句后面不能跟()。解决方法是将function(){ /* ... */ } 代码用括号括起来,以强制将其解析为函数表达式,即(function() { /* ... */ }())(function() { /* ... */ })()。或者将其分配给一个变量。
【解决方案2】:

创建与元素 ID 和名称同名的全局变量是 IE 的一个怪癖。您可以创建一个具有相同名称的全局变量,但有一些怪癖。

这是一个非常糟糕的主意。如果您不喜欢键入 document.getElementById,只需为其创建一个小的包装函数,例如:

funciton get(id) {
  return typeof id == 'string'? document.getElementById(id) : id;
}

【讨论】:

  • 我同意创建这样的全局变量是 JavaScript 的一个危险特性,但将元素存储在变量中而不是每次都调用 getElementById 是一种非常好的做法。
  • 这是一个非常漂亮的功能。我不介意打字,我只是认为使用变量名比尝试重新引用元素看起来更干净;特别是当我使用它的时候。我可以想到一些其他的例子,但我认为它们不值得一提。您是每次都使用 document.getWhatever 还是有更好的方法?
  • @Sidncious - 对存储引用非常满意,只是不喜欢为每个具有 id 的元素创建一个全局变量。
  • @Fantabulum - 大多数处理 UI 的脚本都是由元素启动的,因此您已经从事件中获得了对元素的引用。通过id直接访问元素在我写的app中并不常见,所以我用getElementById的不是很多,所以不需要包装。
【解决方案3】:

randomDiv 不是已定义/已知的“全局范围变量”。

Declaring global variable

【讨论】:

  • 好吧,也许称它为全局变量是用词不当,但问题是为什么不能 variableName === id?很好的信息,感谢您的输入。
  • 嗨 Fantabulum,您所指的 variableName 是 JavaScript 的一部分,而 id 是 DOM。它们是不同的东西。
  • Fantabulum,在上面的代码标题中,您尝试使用 DOM 来获取对 ID 为 randomDiv 的 HTML 表单对象的引用,但是 randomDiv 不是全局变量。如果您指的是为什么将 randomDiv 声明为全局变量不起作用,那不是 JavaScript 中声明全局变量的方法之一。
【解决方案4】:

似乎 id 自动成为变量!无需声明:

<button id="b1">press me</button>
<script>
    b1.onclick = function(){alert("Thanks!")}
</script>

如您所见,它可以工作(至少 firefox 68)并且不会抛出任何错误。

更多信息:

【讨论】:

    猜你喜欢
    • 2012-08-05
    • 1970-01-01
    • 2019-02-14
    • 2017-02-27
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 2023-03-24
    • 2021-06-20
    相关资源
    最近更新 更多