Javascript 在事件侦听器中使用eval(myFunctionName)作为回调的替代方法是什么?

Javascript 在事件侦听器中使用eval(myFunctionName)作为回调的替代方法是什么?,javascript,eval,addeventlistener,event-listener,Javascript,Eval,Addeventlistener,Event Listener,我开始错误地问这个问题,所以我重新开始,从我正在努力解决的问题的细节开始,而不是 而不是问题的一般特征 我有一个对象,其中的值是字符串。它们非常需要是字符串,因为它们是从HTML5自定义数据-*属性中提取的,我真的不想开始在HTML属性中编写javascript,就像1999年那样 下面是一个自定义数据-*属性的示例: data-event="{«eventListener» : «transitionend», «eventAction» : «showText»}" 如您所见,它基本上是一

我开始错误地问这个问题,所以我重新开始,从我正在努力解决的问题的细节开始,而不是 而不是问题的一般特征

我有一个对象,其中的值是字符串。它们非常需要是字符串,因为它们是从HTML5自定义
数据-*
属性中提取的,我真的不想开始在HTML属性中编写javascript,就像1999年那样

下面是一个自定义
数据-*
属性的示例:

data-event="{«eventListener» : «transitionend», «eventAction» : «showText»}"
如您所见,它基本上是一个JSON字符串,稍加修改,因此可以采用HTML属性值的形式

我希望能够解析该自定义
数据-*
属性,并将其转换为以下javascript:

parentElement.addEventListener('transitionend', showText, false);
为此,我需要:

  • «
    »
    字符替换为
    字符
  • JSON.将结果值解析为对象
  • 如果不存在
    useCapture
    参数,则创建该参数(如本例所示)
  • 然后,创建
    addEventListener
    语句对我来说非常简单(几乎是)
  • 事实上——当然——我最后说:

    parentElement.addEventListener('transitionend', 'showText', false);
    
    这不起作用,因为我不能调用
    'showText'
    -它只是一个字符串,它不指向函数

    解决此问题的最简单方法是创建以下语句:

    parentElement.addEventListener('transitionend', eval('showText'), false);
    
    相当于:

    parentElement.addEventListener('transitionend', showText, false);
    
    唯一让我犹豫不决的是,我不确定是否真的不应该使用
    eval()
    ,或者是否应该尽量避免使用
    eval()
    ,而且,尽管有正常的警告,这种异常情况是部署
    eval()
    可以接受的情况


    问题:在Javascript中,获取一个恰好是函数名的字符串,并在字符串上使用
    eval()
    来访问和执行该函数,这是错误的还是不可取的

    如果这是不可取的,那么当我知道一个函数的名称并希望将其插入事件处理程序时,还有什么选择

    如果我最好避免这样做:

    parentElement.addEventListener('transitionend', eval('showText'), false);
    
    我应该用什么来代替


    或者……在某些情况下使用
    eval()
    是完全可以接受的吗?这就是其中之一?

    如果您的函数在全局范围内,则可以:

    myElement.addEventListener('click', window[myObject.function1], false);
    
    方括号只是
    的另一种语法,但它们允许变量属性名

    选中此项:

    constobj={a:'你好,我是obj.a'};
    常量键='a';
    控制台日志(obj.a);
    console.log(obj['a']);
    
    log(obj[key]);
    为了响应更新,最好将所有事件处理程序放置在一个对象中,而不是全局命名空间中,即:

    之前:

    function showText(event) {
       ...
    }
    
    function anotherHandler(event) {
       ...
    }
    
    之后:

    const myActions = {
       showText(event) {
          ...
       },
       anotherHandler(event) {
          ...
       }
    }
    
    然后,在解析
    数据
    属性并得到如下结果后:

    data = {"eventListener" : "transitionend", "eventAction" : "showText"}
    
    以这种方式绑定处理程序:

    parentElement.addEventListener(
         data.eventListener,
         myActions[data.eventAction],
         false)
    

    这不仅可以去除
    eval
    ,而且有助于以更干净的方式组织代码。

    这是一个经常重复的问题,不需要另一个答案,只需投票表决即可(如果相关)注释。谢谢。这是一个很好的选择。我没有想到
    窗口
    对象。我不能说100%的函数将始终在全局范围内,但是如果没有人提出任何更好的建议,那么您上面的建议将是首选解决方案。啊,不。遗憾的是,
    窗口[myObject.function1]
    不起作用。我认为这是因为
    myObject
    是使用
    let
    定义的,并且(正如我刚刚了解的)使用
    let
    定义的变量不会成为window的属性。为什么需要
    eval
    在这里。为什么不使用
    []
    动态属性访问如果字符串以前不知道,如果知道,则可以直接调用
    obj.property()
    查看链接问题的答案了解详细信息,但基本上:
    const myObjectOfffunctions={function1:myFunction,function2:yourFunction};myObjectOfffunctions.function1()
    或不重命名它们:
    const myObjectOfFunctions={myFunction,yourFunction};myObjectOfFunctions.myFunction();
    。如果需要动态名称:
    const name=“myFunction”;myObjectOfFunctions[name]()
    在上面的注释中,名称
    name
    将来自属性,例如。@Rounin答案仍然是一样的。将事件侦听器放在一个对象中,并按属性名称引用它们。是的,使用
    eval
    是不合适的。否。您需要一个对象,其中实际的
    showText
    函数是红色,如
    const myEventListeners={showText:…};
    。然后您可以通过JSON中的名称访问它:
    addEventListener(myObject.eventName,myEventListeners[myObject.eventAction]);
    这是一个经常重复的问题,不需要另一个答案,只需要一个接近票数的投票(如果相关的话)评论。@Rounin:我不明白你在说什么。如果你编辑这个问题并添加一个你想做的事情,这会有所帮助。是的,你是对的,@georg。我意识到我问的问题是错误的。我从最一般、最简单的层面开始(这通常是SO问题的好形式),但在这种情况下,我应该从更具体、更高的层次开始。谢谢你的耐心和毅力,@georg-我最终到达了那里。