我想检查函数是否已定义(我不在乎,我的意思是它是可调用的)
示例代码:
var functions = {
'alert':'alert',
'undefinedFunction':'undefinedFunction',
'ff.showAlert':'ff.showAlert'
};
var ff = {
showAlert: function() {
alert('the function works');
}
};
for (i in functions) {
console.log(i+' : '+typeof window[functions [i]]);
}
返回:
alert : function
undefinedFunction : undefined
ff.showAlert : undefined
console.log(typeof window.ff.showAlert); return function
Live demo
有没有办法以编程方式检查函数是否存在?
答案 0 :(得分:6)
代码:
window[functions [i]]
正在检查window['ff.showAlert']
,但您真正想要检查的是:
window['ff']['showAlert']
或
window.ff.showAlert
为此,您需要遍历命名空间(window
- > ff
- > ...):
function methodIsDefined(fn, obj) {
var ns = fn.split('.');
fn = ns.pop();
do {
if (!ns[0]) {
return typeof obj[fn] === 'function';
}
} while(obj = obj[ns.shift()]);
return false;
}
E.g。
methodIsDefined('ff.showAlert', window); // => true
methodIsDefined('ff.foo', window); // => false
答案 1 :(得分:2)
您的问题在于命名空间。字符串"ff.showAlert"
不引用函数window['ff']['showAlert']
,而是引用window['ff.showAlert']
,这是一个重要的区别。您声明的函数实际上由window['ff']['showAlert']
引用。所以你要检查它存在的地方是错误的。
如果要检查此类命名空间函数是否存在,首先必须拆分字符串,然后遍历DOM以查找正确的属性。代码将类似于以下内容(未经测试!):
function checkFunction( name ) {
var path = "ff.showAlert".split( '.' ),
runner = window;
for( var i=0; i<path.length; i++ ) {
if( path[i] in runner ) {
runner = runner[ path[i] ];
} else {
return false;
}
}
return runner;
}
修改强>
正如@VirtualBlackFox在评论中所指出的:上述解决方案仅在函数声明在window
范围之下时才有效。如果它在另一个函数的范围内,则必须将该范围作为附加参数传递并在那里搜索。
即使在这种情况下,也无法检查是否存在某些闭包构造中定义的函数。
答案 2 :(得分:0)
您需要拆分多部分功能名称,例如'ff.showAlert'
。另外,因为您将ff
指定为var,所以它不会是window
的成员,除非它在任何函数范围之外。你的代码示例是否存在并不是很清楚。
无论如何,下面的函数允许你传入一个基础对象,以防你需要指定window
以外的一个,并且它会拆分多部分函数名称:
function isFnDefined(fnName, baseObj) {
try {
var parts = fnName.split('.'),
ii;
// If no baseObj was provided, default to 'window'.
baseObj = baseObj || window;
for (ii in parts) {
baseObj = base[parts[ii]];
}
return typeof baseObj === 'function';
}
catch (e) {
return false;
}
}
isFnDefined('alert'); // returns true
isFnDefined('undefinedFunc'); // returns false
isFnDefined('ff.showAlert'); // returns true, if ff is a member of window
isFnDefined('showAlert', ff); // returns true
答案 3 :(得分:-1)
您需要使用eval():http://www.w3schools.com/jsref/jsref_eval.asp
答案 4 :(得分:-2)
你有一个字符串代表当前范围内的东西,你想知道它是什么,解决方案是评估字符串。
var f = undefined;
try
{
f = eval(functions[i]);
}
catch(ReferenceError) {}
console.log(typeof f);
但是你为什么要在输入对象中存储字符串而不是函数?
此外,如果您可以强制每个字符串作为相对于窗口的引用(当前范围中没有'var'或来自另一个范围的闭包的内容),那么@Sirko解决方案可能是最好的。< / p>