如何在函数作用域内初始化变量并避免全局作用域?

时间:2020-06-02 21:23:34

标签: javascript

我在全局空间中设置了一个变量,如下所示:

let hoverMessageLock = 0;

这允许下面的功能操作我想要的。它的功能是在按钮悬停时添加一条消息,然后删除该消息,并在另一个悬停时将其替换为新消息。

我遇到的问题是我不想对变量使用全局空间,而是将其放在函数内部。但是,每个每次悬停事件都会一次又一次地调用函数本身,因此,如果我在函数范围内将hoverMessageLock = 0设置为一遍,它只会不断地被设置为0。因此,我的switch语句无法像在全局范围内那样正常工作。

我知道在使用类的其他编程语言中,您可以在类范围内设置变量,然后以与在函数内部全局范围相同的方式更改它们。在Javascript中也可以做到这一点吗?

let macroManager = {
    hoverMessage: function(message, style = "hovertext noTextSelect"){
        switch (hoverMessageLock){
            case 0:
                uiManager.messageDirector.addMessage(""+message+"", 0, 0, style);
                hoverMessageLock = 1;
                break;
            case 1:
                uiManager.messageDirector.removeMessage();
                uiManager.messageDirector.addMessage(""+message+"", 0, 0, style);
                break;
        }
    },
}

4 个答案:

答案 0 :(得分:1)

您已经有一个对象,并且效果很好,就像您在基于类的语言中描述的那样。类只是创建对象的一种方式,这里就是您所需要的所有对象。

只需将属性添加到您的对象中即可

B

请注意,根据您使用let macroManager = { hoverMessageLock: 0, hoverMessage: function(message, style = "hovertext noTextSelect"){ switch (this.hoverMessageLock){ case 0: uiManager.messageDirector.addMessage(""+message+"", 0, 0, style); this.hoverMessageLock = 1; break; case 1: uiManager.messageDirector.removeMessage(); uiManager.messageDirector.addMessage(""+message+"", 0, 0, style); break; } }, } 方法的方式,它的hoverMessageLock上下文可能会丢失(例如,如果将其用作事件处理程序),可以通过定义它来轻松解决而是箭头功能:this

我还建议,如果hoverMessage: (message, style = "hovertext noTextSelect") => { ... }变量/属性的唯一预期值是0和1,请改用布尔值false / true。

答案 1 :(得分:0)

您可以为此使用立即执行的函数表达式(IIFE)。

let macroManager = (function(hoverMessageLock) {
  return {
    hoverMessage: function(message, style = "hovertext noTextSelect") {
      switch (hoverMessageLock) {
        case 0:
          uiManager.messageDirector.addMessage("" + message + "", 0, 0, style);
          hoverMessageLock = 1;
          break;
        case 1:
          uiManager.messageDirector.removeMessage();
          uiManager.messageDirector.addMessage("" + message + "", 0, 0, style);
          break;
      }
    },
  };
})(0);

答案 2 :(得分:0)

class macroManger{
  constructor(){
     this.hoverMessageLock = 0;
  }
  hoverMessage(message, style = "hovertext noTextSelect"){
    switch (this.hoverMessageLock) {
        case 0:
          uiManager.messageDirector.addMessage("" + message + "", 0, 0, style);
          this.hoverMessageLock = 1;
          break;
        case 1:
          uiManager.messageDirector.removeMessage();
          uiManager.messageDirector.addMessage("" + message + "", 0, 0, style);
          break;
      }
  }
}

macroManger1 = new macroManger();
macroManger1.hoverMessage(...);

答案 3 :(得分:0)

您可以使用IIFE表达式创建本地范围:

6a1562f5c4901522ab6926a4caf9f278

因此,每次调用var macroManager = getMacroManager(); function getMacroManager() { return (function () { var hoverMessageLock = 0; return { hoverMessage: function (message, style = "hovertext noTextSelect") { switch (hoverMessageLock) { case 0: uiManager.messageDirector.addMessage("" + message + "", 0, 0, style); hoverMessageLock = 1; break; case 1: uiManager.messageDirector.removeMessage(); uiManager.messageDirector.addMessage("" + message + "", 0, 0, style); break; } }, }; })(); } 时,您将获得一个单独的实例,因此getMacroManager()将用作局部变量,这就是您期望发生的情况。

有关IIFE的更多信息: https://developer.mozilla.org/en-US/docs/Glossary/IIFE