Javascript 在函数之外存储getElementById是个好主意吗?

Javascript 在函数之外存储getElementById是个好主意吗?,javascript,Javascript,我认为两个例子最能说明我的问题 (function(){ var myBtn = document.getElementById('myBtn'); function one() { console.log(myBtn.innerHtml); } function two() { myBtn.innerHtml = "apple"; } function three() { console.log(myBtn.value); }

我认为两个例子最能说明我的问题

(function(){
  var myBtn = document.getElementById('myBtn');

  function one() {
      console.log(myBtn.innerHtml);
  }
  function two() {
      myBtn.innerHtml = "apple";
  }
  function three() {
      console.log(myBtn.value);
  }
})();
vs

因此,第一个示例使用全局变量(或者当它被自调用函数锁定时,它不是全局变量?),第二个示例不使用。第一个示例比较枯燥,而第二个示例将所有内容都保留在函数中

哪一个更好用?两者的利弊是什么?项目规模重要吗


这也是一个理论上的例子,没有html,函数显然无法工作。谢谢。

第一个更好用。它提供了更干净、更快的代码

(function(){
  var myBtn = document.getElementById('myBtn');

  function one() {
      console.log(myBtn.innerHtml);
  }
  function two() {
      myBtn.innerHtml = "apple";
  }
  function three() {
      console.log(myBtn.value);
  }
})();

编辑:当结果只需在所有函数中存储和共享时,无需多次运行同一代码

第二种方法的缺点之一是在每个函数中都需要再次计算和存储变量。这将对性能产生影响。变量在所有函数中都是相同的,因此您可以在函数上方减去它,就像在函数1中一样。示例1中的变量不会成为全局变量(因为使用了iffy)。这也是积极的。需要尽可能保持全球环境清洁。就我个人而言,我认为选项1也更明显地反映了正在发生的事情

document.getElementById函数将返回对指定ID的第一个对象的引用。这意味着它将在后续调用中返回对同一对象的引用(在大多数情况下,如果使用得当的话),这将永远不会引用其他元素,也不会失效

您可以安全地坚持第一个示例的样式。这不是C++,你的对象不会消失。

< P>你的问题中有第三种方法:使用对象。 如果
myBtn
元素在页面生命周期内(即,直到用户刷新页面F5)不会从文档中删除,作为第一种方法,您应该存储对元素的引用,以避免多次查询文档:

(函数(){
//SomeObject不是全局的,而是IIFE范围的局部变量;)
var SomeObject=函数(){
this.myBtn=document.getElementById(“myBtn”);
};
SomeObject.prototype={
一:函数(){
log(this.myBtn.innerHTML);
},
二:功能(){
this.myBtn.innerHtml=“苹果”;
},
三:功能(){
log(this.myBtn.value);
}
};
//这是必需的,以确保某个对象将
//能够在构建期间检索“myBtn”元素,
//因为文档已经加载
document.addEventListener(“DOMContentLoaded”,function()){
var some=new SomeObject();
一些;
});
})();

我的按钮
建议您不要使用全局变量的原因是为了不污染全局名称空间。同样的论点也适用于大的闭包。你不想用太多的变量污染闭包

所以当类似于

(function(){
  var myBtn = document.getElementById('myBtn');

  function one() {
      console.log(myBtn.innerHtml);
  }
  function two() {
      myBtn.innerHtml = "apple";
  }
  function three() {
      console.log(myBtn.value);
  }
})();
不会污染全球范围,但会污染关闭,也就是说,想象一下,如果您有类似

(function(){
  var myBtn = document.getElementById('myBtn');

  // lots of code..

  function one() {
      console.log(myBtn.innerHtml);
  }

  // lots of code..

  function two() {
      myBtn.innerHtml = "apple";
  }

  // lots of code..

  function three() {
      console.log(myBtn.value);
  }
})();
因为您必须知道,当您在
three()
中时,myBtn存在于父作用域中,并且在
three
中创建一个局部变量会掩盖这一点

另一个反对使用外部作用域变量的案例

(function(){
  var myBtn = document.getElementById('myBtn');

  // lots of code..

  function one() {
      console.log(myBtn.innerHtml);
  }

  // lots of code..

  var myBtn1 = document.getElementById('myBtn1');

  function two() {
      myBtn1.innerHtml = "apple";
  }

  // lots of code..

  function three() {
      console.log(myBtn.value);
  }
})();
如果外部关闭时间足够长,您将被迫跟踪myBtn、myBtn1。。。。因此,虽然这比全局范围(必须跨文件跟踪变量)要好,但现在(只是?)必须跟踪闭包中的所有变量

这就引出了一个问题,对于大型闭包,什么样的方法更好呢。这里有一个选择

(function () {
    // lots of code..

    function one(myBtn) {
        console.log(myBtn.innerHtml);
    }

    // lots of code..

    function two(myBtn) {
        myBtn.innerHtml = "apple";
    }

    // lots of code..

    function three(myBtn) {
        console.log(myBtn.value);
    }


    var myBtn = document.getElementById('myBtn');

    one(myBtn);
    two(myBtn);
    three(myBtn);
})();
这使一切都很好地本地化。当然,如果您有一个大的闭包,这可能表明您在该闭包(模块)中做得太多了


当然,对于小闭包,您的第一个选项非常合适。

这不是全局变量。。。。它是闭包范围中的一个变量。myBtn是否始终存在?如果是这样的话,就用第一个。如果要添加和删除它,并且只在调用内部函数时才存在,请使用第二个。您应该绝对将
相似的
变量存储在某个位置,而不是在每个函数中反复选择它,因此示例#1更好。当然,只有当@JamesThorpe说,当应用程序运行时需要这个变量,而不仅仅是一次。在这种情况下,您的
var myBtn
在内存中变成了一个不必要的位置。这不适合,因为它需要基于意见的答案。而且浏览器通过ID选择元素的速度快得令人难以置信,所以基本上没有性能改进。@在这种情况下,系统发育不会有太大的区别。但这是一个最佳实践问题,可以应用于不同的要求更高的情况。由于ID在整个文档中必须是唯一的,浏览器实现者可以自由使用哈希表来处理元素查找。哈希查找非常快。如果在非常紧密的循环之前存储这样的元素,那么只会对性能产生影响。您进行的大多数其他DOM调用几乎肯定会使查找成本相形见绌。
(function () {
    // lots of code..

    function one(myBtn) {
        console.log(myBtn.innerHtml);
    }

    // lots of code..

    function two(myBtn) {
        myBtn.innerHtml = "apple";
    }

    // lots of code..

    function three(myBtn) {
        console.log(myBtn.value);
    }


    var myBtn = document.getElementById('myBtn');

    one(myBtn);
    two(myBtn);
    three(myBtn);
})();