【问题标题】:Using javascript objects as a "function store" and calling them dynamically?使用 javascript 对象作为“函数存储”并动态调用它们?
【发布时间】:2019-05-29 21:55:54
【问题描述】:

考虑这样的事情:

const keyAction = {
    a() {
        console.log("You've pressed 'a'");
    },
    b() {
        console.log("You've pressed 'b'");
    },
    c() {
        console.log("You've pressed 'c'");
    }
}

document.addEventListener('keydown', e => keyAction[e.key]());

这是一种不好的做法吗?有什么理由不这样做吗?

【问题讨论】:

  • 为什么要创建3个函数?创建 1 并在其中使用 e.key
  • @Justcode what if ,如果这些函数有不同的实现
  • @brk 喜欢吗?我们可以在其中调用另一个函数。是的,我也同意这个没有错
  • 这样做绝对没有错。请记住在调用之前检查keyAction[e.key] 是否未定义。

标签: javascript ecmascript-6


【解决方案1】:

实际上这是一种流行的做法,因为有些人倾向于使用对象来模拟来自其他语言的命名空间。我认为它没有什么不好,只要您了解这种方法可能设置的陷阱。例如,当您将这些函数作为参数传递时,您应该记住 this 会发生什么(请看下面的示例):

const store = {
    a() {
        this.b();
    },
    b() {
        console.log("It works!");
    }
}

store.a();  // Logs "It works"
setTimeout(store.a, 10) // Error: this.b is not a function

此外,正如@Nick Ovchinnikov 所指出的,在您的具体示例中,还有另一个陷阱。您应该确保,无论何时按下按钮,环境都不会尝试调用不存在的函数 - 否则您可能会遇到错误。所以最终你的处理程序绑定应该看起来像这样:

document.addEventListener('keydown', e => {
    if (typeof keyAction[e.key] === 'function') {
        keyAction[e.key]();
    }
});

【讨论】:

  • 感谢您的解释。 @Nick Ovchinnikov 的answer 也包含我的想法的一个重要陷阱。您能否将其包含在您的答案中,以便我接受?
  • 当然!已经注意到了。非常感谢!
【解决方案2】:

你有问题,当你按下一个你没有处理的键时,你会看到Error: keyAction[e.key] is not a function

if (typeof keyAction[e.key] === 'function') {
    return keyAction[e.key]()
}

console.log('You pressed a some button')

Javascript 是动态语言,当然在某些情况下它非常棒。但是不要滥用,因为你失去控制的速度可能比你想象的要快

【讨论】:

    【解决方案3】:

    使用对象作为函数存储并不是一个坏主意。它易于理解、易于维护和快速访问(因为 hashmap 系统)。与 if/else if/... 相比,它还使您能够对数据进行处理 - 例如,执行循环...等

    这取决于你想要做什么,这可能是一个很好的帮助。

    尽量避免每次调用函数时都重新创建对象。构建一次并重复使用。

    const keyAction = {
      a: () => {
        console.log("You've pressed 'a'");
      },
    
      b: () => {
        console.log("You've pressed 'b'");
      },
    };
    
    function clickFunc(key) {
      keyAction[key]();
    }
    .ex {
      background-color: #444444;
      color: white;
      height: 5em;
      width: 5em;
      margin: 1em;
      cursor: pointer;
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: center;
    }
    <div class="ex" onclick="clickFunc('a')">
      A
    </div>
    
    <div class="ex" onclick="clickFunc('b')">
      B
    </div>

    【讨论】:

      猜你喜欢
      • 2011-12-30
      • 1970-01-01
      • 1970-01-01
      • 2013-10-06
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多