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



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

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

下面是其中一个自定义data-*属性的示例:

data-event="{«eventListener» : «transitionend», «eventAction» : «showText»}"

如您所见,它基本上是一个 JSON 字符串,稍作修改,因此它可以采用 HTML 属性值的形式。

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

parentElement.addEventListener('transitionend', showText, false);

为此,我需要:

  1. «»字符替换为"字符
  2. 将结果值JSON.parse到对象中
  3. 如果useCapture参数不存在,请创建该参数(如本例所示(
  4. 然后对我来说,创建addEventListener语句很简单(几乎(

事实上 - 当然 - 我最终会得到这个声明:

parentElement.addEventListener('transitionend', 'showText', false);

这不起作用,因为我无法调用'showText'- 它只是一个字符串,它不指向函数。

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

parentElement.addEventListener('transitionend', eval('showText'), false);

相当于

parentElement.addEventListener('transitionend', showText, false);

唯一阻碍我的是我不确定是否真的不应该使用eval(),或者是否应该简单地避免它 - 而且,尽管有正常的警告,但这种不寻常的情况是可以接受的部署eval()


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

如果不可取,当我知道函数的名称并希望将其插入事件处理程序时,还有什么替代方法?

如果我最好避免这种情况:

parentElement.addEventListener('transitionend', eval('showText'), false);

我应该改用什么?

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

为了响应更新,最好将所有事件处理程序放在对象而不是全局命名空间中,即:

以前:

function showText(event) {
...
}
function anotherHandler(event) {
...
}

后:

const myActions = {
showText(event) {
...
},
anotherHandler(event) {
...
}
}

然后,在你解析了data属性并得到如下内容之后:

data = {"eventListener" : "transitionend", "eventAction" : "showText"}

以这种方式绑定处理程序:

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

这不仅摆脱了eval,而且还有助于以更简洁的方式组织代码。

如果您的函数在全局范围内,则可以执行此操作:

myElement.addEventListener('click', window[myObject.function1], false);

方括号只是.的替代语法 - 但它们允许变量属性名称。

检查这个:

const obj = { a: 'Hello this is obj.a' };
const key = 'a';
console.log(obj.a);
console.log(obj['a']);
console.log(obj[key]);

最新更新