简体   繁体   English

将getElementById存储在函数外部是个好主意吗?

[英]Is storing a getElementById outside of functions a good idea?

I think two examples will illustrate my question best. 我认为有两个例子可以最好地说明我的问题。

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

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

vs VS

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

So the first examples uses a global variable (or when it's locked withing a self-invoking function it's not a global variable?) the second does not. 因此,第一个示例使用全局变量(或者使用自调用功能将其锁定时,它不是全局变量吗?),第二个示例则没有。 The first example is more DRY while the second keeps everything within functions. 第一个示例是DRY,而第二个示例则将所有内容保留在函数中。

Which one is better to use? 哪个更好用? What are the pros and cons of both? 两者的优缺点是什么? Does project scale matter? 项目规模重要吗?

Again this is a theoretical example, the functions obviously don't work without html. 同样,这是一个理论示例,没有html的功能显然无法正常工作。 Thanks. 谢谢。

One of te disadvantages of the second is that within every function the variable needs to be calculated and stored again. 第二个缺点之一是在每个函数中都需要重新计算和存储变量。 This will have an impact on the performance. 这将对性能产生影响。 The variable will be the same in all functions so you could subtract it at place it above the function as in function 1. The variable in example 1 will not become a global variable (because of the use of an iffy). 该变量在所有函数中都将是相同的,因此您可以在函数上方将其减去(与函数1中相同)。示例1中的变量将不会成为全局变量(由于使用了iffy)。 This is also positive. 这也是积极的。 Need to keep the global environment as clean as possible. 需要保持全球环境尽可能清洁。 Personally I think option 1 is also more obvious what is going on. 就我个人而言,我认为备选案文1也更加明显。

First one is better to use. 第一个更好用。 it gives cleaner and faster code. 它提供了更干净,更快的代码。

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

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

Edit: There is no need to run the same code multiple times when the result would just be stored and shared across all you functions 编辑:当结果将被存储并在所有函数之间共享时,无需多次运行相同的代码

The document.getElementById function will return the reference to the first object with the ID specified. document.getElementById函数将返回对具有指定ID的第一个对象的引用。 This means it will return the reference to the same object during subsequent calls (in most cases, if used appropriately), which will never refer to other elements, or get invalidated. 这意味着它将在后续调用期间返回对同一对象的引用(在大多数情况下,如果使用得当),该引用将永远不会引用其他元素或变得无效。

You can safely stick to the style of the first example. 您可以放心地遵循第一个示例的样式。 This is not c++, and your object won't disappear. 这不是c ++,并且您的对象不会消失。

There's a third and missing approach in your question: using objects. 您的问题中还有第三种且缺失的方法:使用对象。

If myBtn element won't be dropped from the document within the life of the page (ie until user refreshes the page F5 ), as your first approach, you should store a reference to the element in order to avoid querying the document many times: 如果在myBtn内不会将myBtn元素从文档中删除(即直到用户刷新页面F5 ),作为第一种方法,应存储对该元素的引用,以避免多次查询文档:

 (function() { // SomeObject isn't global, but a local variable of IIFE's scope ;) var SomeObject = function() { this.myBtn = document.getElementById("myBtn"); }; SomeObject.prototype = { one: function() { console.log(this.myBtn.innerHTML); }, two: function() { this.myBtn.innerHtml = "apple"; }, three: function() { console.log(this.myBtn.value); } }; // This is required in order to be sure that SomeObject is going to // be able to retrieve "myBtn" element during its construction time, // because the document is already loaded document.addEventListener("DOMContentLoaded", function() { var some = new SomeObject(); some.one(); }); })(); 
 <button id="myBtn">My button</button> 

The reason its recommended that you don't use a global variables is so that you don't pollute the global namespace. 建议不要使用全局变量的原因是,这样就不会污染全局名称空间。 The same argument would hold for a large closure. 相同的论点适用于大的关闭。 You don't want to be polluting the closure with too many variables 您不想使用太多变量来污染闭包

So while something like 所以当类似

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

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

does not pollute the global scope, it does pollute the closure ie imagine how difficult maintenance would be if you had something like 不会污染全局范围,但会污染闭包,即想象一下如果您有类似的东西,维护将有多困难

(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);
  }
})();

because you have to know that when you are in three() that myBtn exists in the parent scope and creating a local variable within three would mask that 因为您必须知道,当您在three() ,myBtn存在于父范围中,并且在three范围内创建局部变量会掩盖该

Another case against using variable from an outer scope 另一种反对使用外部作用域变量的情况

(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);
  }
})();

with a long enough outer closure, you'd be forced to keep track of myBtn, myBtn1.... So while this is better than global scope (where you had to keep track of variable across files), now you (just?) have to keep track of all the variables within the closure. 使用足够长的外部闭包,您将不得不跟踪myBtn,myBtn1...。因此,这比全局作用域(必须跟踪文件中的变量)要好,而现在(只是?)必须跟踪闭包内的所有变量。

Which begets the question, what would be a better way for large closures . 这就引出了一个问题: 对于大型闭包 ,哪种方法更好? Here is one option 这是一个选择

(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);
})();

which keeps everything nicely localized. 使所有内容都很好地本地化。 Of course if you have a large closure it is probably an indication that you are doing too much in that closure (module). 当然,如果您的封包很大,则可能表明您在该封包(模块)中做得太多。

Of course for small closures, your first option is pretty ok. 当然,对于小型瓶盖,您的第一个选择还可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM