Javascript 如何通过与名称匹配的字符串调用函数并执行它?

Javascript 如何通过与名称匹配的字符串调用函数并执行它?,javascript,Javascript,我从无序列表中单击的列表项中获取innerHTML。我把这个字符串保存到一个变量中,我想调用一个与这个变量同名的函数 我做了一些研究,发现了一些不同的文章,但没有一篇有效。eval被认为是一种随意的方式,但我无法让它发挥作用。另外一个用户正在使用Window,但代码对我不起作用 如何将该变量作为函数调用。i、 e.单击名称 现在调用clickedName会出现错误 Uncaught TypeError: clickedName is not a function at HTMLUList

我从无序列表中单击的列表项中获取innerHTML。我把这个字符串保存到一个变量中,我想调用一个与这个变量同名的函数

我做了一些研究,发现了一些不同的文章,但没有一篇有效。eval被认为是一种随意的方式,但我无法让它发挥作用。另外一个用户正在使用Window,但代码对我不起作用

如何将该变量作为函数调用。i、 e.单击名称

现在调用clickedName会出现错误

Uncaught TypeError: clickedName is not a function
    at HTMLUListElement.<anonymous> 
以下是我正在使用的代码:

index.html

<div id="myDiv">test</div>

    <ul id="parent-list">
        <li>Cats</li>
        <li>Dogs</li>
    </ul>
script.js

document.getElementById("parent-list").addEventListener("click", function(e) {
    if (e.target && e.target.nodeName == "LI") {
        // console.log(e.target.innerHTML + " was clicked");
        // call function respective to element clicked
        let clickedName = e.target.innerHTML;
        console.log(clickedName);

    }
 });


function cat() {
    const myElem = document.createElement("div");
    let myString = `<div>Meow, Meow, Meow</div>`;

    myElem.innerHTML = myString;

    // put on page
    document.getElementById("myDiv").append(myElem);
} // catClick


如果函数在当前范围内声明,则此[clickedName]应该可以工作。这是因为函数是This对象上的一个方法,因此应该可以通过它进行访问。但是,如果该函数是另一个对象的一部分,比如说一个对象,则只需执行一个对象[clickedName]

如果该函数是在当前范围内声明的,则该[clickedName]应该可以工作。这是因为函数是This对象上的一个方法,因此应该可以通过它进行访问。但是,如果函数是另一个对象的一部分,比如说一个对象,您可以只做一个对象[clickedName]

我不推荐的一种方法是知道函数通常声明为中,函数fName{}在全局范围内是window对象的一部分,因此doFunction与window.doFunction相同。因此,您可以这样做:

window[clickedName]();
但这意味着用户可以输入全局范围内任何函数的名称来运行它,这并不好。相反,我建议将您希望能够以这种方式运行的函数封装到只包含这些方法的特定对象中;然后你可以从那里打电话:

const allowedFunctions = {
    firstAllowed: function() { /* ... */ },
    someOtherFunction: function() { /* ... */ }
};
// ...then later, to call it...
if (allowedFunctions[clickedName]) { allowedFunctions[clickedName](); }
我不建议使用的一种方法是,知道通常声明为in的函数以及全局范围中的函数fName{}都是window对象的一部分,因此doFunction与window.doFunction相同。因此,您可以这样做:

window[clickedName]();
但这意味着用户可以输入全局范围内任何函数的名称来运行它,这并不好。相反,我建议将您希望能够以这种方式运行的函数封装到只包含这些方法的特定对象中;然后你可以从那里打电话:

const allowedFunctions = {
    firstAllowed: function() { /* ... */ },
    someOtherFunction: function() { /* ... */ }
};
// ...then later, to call it...
if (allowedFunctions[clickedName]) { allowedFunctions[clickedName](); }

和以前一样的问题,同样的错误。两种方法都试过了。我们能在你的代码上获得更多的上下文吗?如果我不知道函数的定义位置或定义方式,我无法告诉您如何调用函数。在更正了上面另一个答案中的错误后,我尝试了这样做[clickedName]。这不起作用,但做窗口对象会起作用,所以我相信你也是对的。谢谢。和以前一样的问题,同样的错误。两种方法都试过了。我们能在你的代码上获得更多的上下文吗?如果我不知道函数的定义位置或定义方式,我无法告诉您如何调用函数。在更正了上面另一个答案中的错误后,我尝试了这样做[clickedName]。这不起作用,但做窗口对象会起作用,所以我相信你也是对的。谢谢你,我也试过了,但没用。不会抛出错误,但不会发生任何事情。尝试在chrome开发工具的script.js文件中设置一个断点,但它并没有在断点处暂停,以便让我一步一步地查看它到达该行时发生了什么。它只是执行而已。我还尝试了用window[clickedName]做这件事的不太好的方法;这是行不通的。引发与原始帖子中相同的错误。是否确定单击的目标元素的innerHTML是其中一个函数的名称?如果你退出console.log,你会看到什么?clickedName?天哪,你说得对。我的函数名是cat,而li文本是cats。非常感谢你。你能解释一下你的代码是怎么回事,为什么使用第二个更好吗。我不完全明白。此外,也许这是一个愚蠢的方式,这样做在第一位。我可以把带有点击事件的按钮作为列表项,并构建一个菜单栏,这样就可以用javascript制作一个单页类型的应用程序。这就是我正在做的。不过我想不用扣子。把所有事情都放在一个页面上是不是一个愚蠢的想法?把它放在一个页面上或者没有按钮都没有错。问题是直接使用元素的innerHTML作为函数名;如果HTML不在您的控制之下,任何用户都可以运行任意函数。如果HTML可以从用户生成的内容中编辑,那么这一问题尤其严重,因为这样它将在其他用户的计算机上运行。至少通过封装它们,可以限制哪些函数可以以这种方式运行。但请记住,点击事件不一定要出现在按钮上,它们可以出现在任何东西上:我也尝试过这样做,但它不起作用。不会抛出错误,但不会发生任何事情。尝试在chrome开发工具的script.js文件中设置一个断点,但它不会在断点处暂停,让我一步一步来看看发生了什么
当它击中那条线时,它会发出声音。它只是执行而已。我还尝试了用window[clickedName]做这件事的不太好的方法;这是行不通的。引发与原始帖子中相同的错误。是否确定单击的目标元素的innerHTML是其中一个函数的名称?如果你退出console.log,你会看到什么?clickedName?天哪,你说得对。我的函数名是cat,而li文本是cats。非常感谢你。你能解释一下你的代码是怎么回事,为什么使用第二个更好吗。我不完全明白。此外,也许这是一个愚蠢的方式,这样做在第一位。我可以把带有点击事件的按钮作为列表项,并构建一个菜单栏,这样就可以用javascript制作一个单页类型的应用程序。这就是我正在做的。不过我想不用扣子。把所有事情都放在一个页面上是不是一个愚蠢的想法?把它放在一个页面上或者没有按钮都没有错。问题是直接使用元素的innerHTML作为函数名;如果HTML不在您的控制之下,任何用户都可以运行任意函数。如果HTML可以从用户生成的内容中编辑,那么这一问题尤其严重,因为这样它将在其他用户的计算机上运行。至少通过封装它们,可以限制哪些函数可以以这种方式运行。但请记住,点击事件不一定要出现在按钮上,它们可以出现在任何东西上: