ChatGPT解决这个技术问题 Extra ChatGPT

如何在 Javascript 中调用动态命名的方法?

我正在动态创建一些将在构建网页时插入到网页中的 JavaScript。

JavaScript 将用于根据另一个 listbox 中的选择填充 listbox。当一个 listbox 的选择发生更改时,它将根据 listbox 的选定值调用方法名称。

例如:

Listbox1 包含:

颜色

形状

如果选择了 Colours,那么它将调用填充另一个 listboxpopulate_Colours 方法。

澄清我的问题:如何在 JavaScript 中进行 populate_Colours 调用?

我不建议这样做,而是在单一的“填充”方法中建立本地分支机构。这将使它更可测试并且看起来不那么“hacky”
在这里查看我的答案。 call by name in javascript

M
Mike

假设 populate_Colours 方法位于全局命名空间中,您可以使用以下代码,该代码利用了所有对象属性都可以像访问关联数组一样被访问,并且所有全局对象实际上都是 {2 } 主机对象。

var method_name = "Colours";
var method_prefix = "populate_";

// Call function:
window[method_prefix + method_name](arg1, arg2);

感谢您的回复。 '窗口'位真的让我震惊,直到我用谷歌搜索它并发现全局对象是窗口对象的一部分。现在它是有道理的!谢谢你。仅供参考,我在这里找到了一个很好的页面devlicio.us/blogs/sergio_pereira/archive/2009/02/09/…
我做了类似的事情,除了我的目标函数在 jQuery“fn”命名空间中。例如,$.fn[method_prefix + method_name](arg1, arg2);
好的。也许值得添加一个 try/catch 块。
这对某些人来说可能很明显,但对于那些无法使其工作的人:将函数扔到 $(function () {window.load 代码之外:)
@peter因为方括号在这种情况下不是属性访问器,而是表示一个数组。数组不是函数,所以你不能调用它们。
D
David Spillett

正如 Triptych 所指出的,您可以通过在宿主对象的内容中找到它来调用任何全局范围函数。

一种对全局命名空间污染更少的更简洁的方法是直接将函数显式放入数组中,如下所示:

var dyn_functions = [];
dyn_functions['populate_Colours'] = function (arg1, arg2) { 
                // function body
           };
dyn_functions['populate_Shapes'] = function (arg1, arg2) { 
                // function body
           };
// calling one of the functions
var result = dyn_functions['populate_Shapes'](1, 2);
// this works as well due to the similarity between arrays and objects
var result2 = dyn_functions.populate_Shapes(1, 2);

这个数组也可以是全局宿主对象以外的某个对象的属性,这意味着您可以像 jQuery 等许多 JS 库一样有效地创建自己的命名空间。如果/当您在同一页面中包含多个单独的实用程序库时,这对于减少冲突很有用,并且(您的设计的其他部分允许)可以更容易地在其他页面中重用代码。

您也可以使用这样的对象,您可能会发现它更干净:

var dyn_functions = {};
dyn_functions.populate_Colours = function (arg1, arg2) { 
                // function body
           };
dyn_functions['populate_Shapes'] = function (arg1, arg2) { 
                // function body
           };
// calling one of the functions
var result = dyn_functions.populate_Shapes(1, 2);
// this works as well due to the similarity between arrays and objects
var result2 = dyn_functions['populate_Shapes'](1, 2);

请注意,对于数组或对象,您可以使用任何一种设置或访问函数的方法,当然也可以在其中存储其他对象。您可以通过使用 JS 文字表示法进一步减少这两种方法的语法,以减少不是那么动态的内容,如下所示:

var dyn_functions = {
           populate_Colours:function (arg1, arg2) { 
                // function body
           };
         , populate_Shapes:function (arg1, arg2) { 
                // function body
           };
};

编辑:当然,对于更大的功能块,您可以将上述扩展为非常常见的“模块模式”,这是一种以有组织的方式封装代码功能的流行方式。


这是保持清洁的好方法。我将如何调用该方法? window[dyn_functions['populate_Colours'](arg1, arg2) 会工作吗?
回答我自己的问题 - 我刚刚测试了 window[dyn_functions['populate_Colours'](arg1,arg2)];它确实有效。
正如 epascarello 指出的那样,您通常不需要“窗口”-“dyn_functions['populate_Colours'](arg1,arg2);”将工作。事实上,如果您编写的例程可能曾经在 Web 浏览器以外的 JS 环境中使用,那么不包括全局对象的名称将使代码更具可移植性。但是有一个例外:如果您在函数中有一个名为 dyn_functions 的局部变量,那么您需要更具体地指代您所指的内容,但无论如何最好避免这种情况(通过合理的命名约定)。
由于这篇文章来自 '09,您现在可能已经知道了,但是您正在创建一个数组,然后分配给数组的属性(而不是索引)。您不妨这样做 var dyn_functions = {}; 这样您就不会不必要地创建一个数组......但这不是一个大问题。
过于复杂的答案,但确实有效。我认为对于我有一系列模式化函数并且我需要一个决策树来选择执行的场景的资源负载,这种方法执行任务可能过于复杂。尽管如此,如果我正在连接我自己的类对象,这将是定义对象本身的首选方法。
G
GorvGoyl

为此,我建议使用 global / window / eval
相反,这样做:

将所有方法定义为 Handler 的属性:

var Handler={};

Handler.application_run = function (name) {
console.log(name)
}

现在这样称呼

var somefunc = "application_run";
Handler[somefunc]('jerry');

输出:杰瑞

从不同文件导入函数时的情况

import { func1, func2 } from "../utility";

const Handler= {
  func1,
  func2
};

Handler["func1"]("sic mundus");
Handler["func2"]("creatus est");

为什么不使用 global / window / eval
S
Simon

你可以这样做:

function MyClass() {
    this.abc = function() {
        alert("abc");
    }
}

var myObject = new MyClass();
myObject["abc"]();

O
OXiGEN

ServiceWorkerWorker 中,将 window 替换为 self

self[method_prefix + method_name](arg1, arg2);

工作人员无权访问 DOM,因此 window 是无效引用。用于此目的的等效全局范围标识符是 self


T
Tim

我不建议像其他一些答案所建议的那样使用窗口。使用 this 和相应的范围。

this['yourDynamicFcnName'](arguments);

另一个巧妙的技巧是在不同的范围内调用并将其用于继承。假设您已经嵌套了该函数并希望访问全局窗口对象。你可以这样做:

this['yourDynamicFcnName'].call(window, arguments);

我该怎么做打字稿?我在类中有一个方法,它将迭代具有函数名和函数参数的对象数组。被调用的函数存在于同一个类中。但是我收到错误,因为 this[functionName](funcArgument) 不是函数
你能分享一个codepen的例子吗?对于类,请务必考虑词法范围。
当窗口不存在时,您会添加一个示例吗?
窗口不一定存在,我只是举个例子。您可以使用任何对象,根据我的记忆,我认为 node 确实有一个全局 this 范围为他们自己的对象,所以第一个选项应该在 node 或浏览器中完美运行。
d
dılo sürücü

去做就对了

class User

  getName() 
  {   

    return "dilo";
   }

}

let user =new User();
let dynamicMethod='getName';
console.log(user[dynamicMethod]()); //dilo

 

这次真是万分感谢!简单的基本答案,适用于所有类型的 js,可能缺少 { following class User ?
m
mathi

你好试试这个

 var callback_function = new Function(functionName);
 callback_function();

它将自己处理参数。


未捕获的引用错误 - 未定义 functionName
@brianlmerritt,您必须定义 functionName 的值...回答者假设您已经定义了该值。
似乎 new Function() 不能像这样用于此目的。
E
El Amrani Chakir

一个使用参数动态调用函数的简单函数:

this.callFunction = this.call_function = function(name) {
    var args = Array.prototype.slice.call(arguments, 1);
    return window[name].call(this, ...args);
};

function sayHello(name, age) {
    console.log('hello ' + name + ', your\'e age is ' + age);
    return some;
}

console.log(call_function('sayHello', 'john', 30)); // hello john, your'e age is 30


p
proseosoc

试试这些

使用动态名称调用函数,如下所示:

let dynamic_func_name = 'alert';
(new Function(dynamic_func_name+'()'))()

带参数:

let dynamic_func_name = 'alert';
let para_1 = 'HAHAHA';
let para_2 = 'ABCD';
(new Function(`${dynamic_func_name}('${para_1}','${para_2}')`))()

运行动态代码:

let some_code = "alert('hahaha');";
(new Function(some_code))()

A
Aylian Craspa

这是一个有效且简单的解决方案,用于检查函数的存在并通过另一个函数动态地对该函数进行分类;

触发功能

function runDynmicFunction(functionname){ 

    if (typeof window[functionname] == "function"  ) { //check availability

        window[functionname]("this is from the function it "); //run function and pass a parameter to it
    }
}

你现在可以像这样使用php动态生成函数

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

现在您可以使用动态生成的事件调用该函数

<?php

$name_frm_somware ="runThis_func";

echo "<input type='button' value='Button' onclick='runDynmicFunction(\"".$name_frm_somware."\");'>";

?>

您需要的确切 HTML 代码是

<input type="button" value="Button" onclick="runDynmicFunction('runThis_func');">

G
Gilberto

试试这个:

var fn_name = "Colours",
fn = eval("populate_"+fn_name);
fn(args1,argsN);

使用这种模式有什么影响?我读到 eval 函数有一些与其使用相关的奇怪副作用。我通常会尽量远离它,除非是万不得已。
评估动态内容使黑客很容易将自己的代码注入并执行到您的代码中