【发布时间】:2020-03-05 05:26:20
【问题描述】:
如何将事件关联到我定义为字符串的函数名称?
我正在使用 Prototype.js,虽然这不是 Prototype 专用的。
$(inputId).observe('click', formData.fields[x].onclick);
这会导致 JavaScript 抱怨我的处理程序不是函数。我不希望我们使用eval()。
【问题讨论】:
标签: javascript
如何将事件关联到我定义为字符串的函数名称?
我正在使用 Prototype.js,虽然这不是 Prototype 专用的。
$(inputId).observe('click', formData.fields[x].onclick);
这会导致 JavaScript 抱怨我的处理程序不是函数。我不希望我们使用eval()。
【问题讨论】:
标签: javascript
Property accessors 可用于访问任何对象的属性或函数。
如果函数在全局范围内,可以使用window对象获取:
var myFunc = window[myFuncName];
这也适用于this 范围:
var myFunc = this[myFuncName];
【讨论】:
我已经解决了这个问题,因为我需要这样的功能。这是我的沙盒代码,未经彻底测试,但可以作为其他人的起点。 请注意,代码中有一个 eval() ,因为我不知道如何绕过该步骤,可能是 javascript 怪癖,无法以任何其他方式完成。让我知道是否有办法在这里摆脱 eval()!
executeFunctionByName = function(functionName)
{
var args = Array.prototype.slice.call(arguments).splice(1);
//debug
console.log('args:', args);
var namespaces = functionName.split(".");
//debug
console.log('namespaces:', namespaces);
var func = namespaces.pop();
//debug
console.log('func:', func);
ns = namespaces.join('.');
//debug
console.log('namespace:', ns);
if(ns == '')
{
ns = 'window';
}
ns = eval(ns);
//debug
console.log('evaled namespace:', ns);
return ns[func].apply(ns, args);
}
core = {
paragraph: {
titlebar: {
user: "ddd",
getUser: function(name)
{
this.user = name;
return this.user;
}
}
}
}
var testf = function()
{
alert('dkdkdkd');
}
var x = executeFunctionByName('core.paragraph.titlebar.getUser', 'Ikon');
executeFunctionByName('testf');
【讨论】:
var func = window; for(var i=0;i<namespaces.length;++i){ func = func[namespaces[i]]; }
... 或 this[myFuncName];
【讨论】:
也许?
setTimeout ( "myFunc()", 1 );
【讨论】:
只需eval 即可完成这项工作
var call = eval("method_name").call(args);
【讨论】:
var call = eval("mathod_name").call(args);
看起来formData.fields[x].onclick 包含一个全局函数的名称?如果是这样试试:
$(inputId).observe('click', window[formData.fields[x].onclick]);
【讨论】:
window.myFunction === window["myFunction"]
【讨论】:
你知道 onclick 属性包含什么或它是什么类型吗?我认为这是特定于原型的东西,因为 DOM 表单中不存在“字段”。
【讨论】:
如果您需要调用带参数的字符串函数,请执行以下操作:
window[stringFunctionName].apply( window, arrayOfArguments )
如果愿意,您可以使用scope 代替window
【讨论】:
更新:--- 使用 ES6 导出和导入
a.js
const fn = {
aaa: function() {
//code
},
bbb: function() {
//code
},
//codes ....
nnn: function() {
//code
}
}
export default fn
b.js
import someFn from './a'
//eg
const str1='aaa'
const str2 = 'bbb'
someFn[str1]()
eval('str')(过时功能https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features)
setTimeout('str')setInterval('str')
window['str'](但是……有时,全局对象不是窗口)
new Function('str')
上述这些方法总是不推荐使用,但它们使用起来确实很方便。 以下这些方法是安全的,但确实不方便使用。
switch...case(或 if...else)
switch(str){
case 'str1':
fn1()
break
case 'str2':
fn2
//and so on
}
将函数放入对象中
const fn={
str1:fn1,
str2:fn2
//and so on
}
fn[str1] //call function
【讨论】: