2013-04-09 54 views
1

有没有办法在不使用eval()的情况下执行以下操作?检查对象是否定义在对象名字符串中

以下函数接受字符串数组,其中的字符串是对象名称。我遍历它们以确保它们都不是未定义的。我希望能够做到这一点,而无需使用eval()

function hasMissingDependencies(dependencies) { 
    var missingDependencies = []; 

    for (var i = 0; i < dependencies.length; i++) { 
     if (eval('typeof ' + dependencies[i]) === 'undefined') { 
      missingDependencies.push(dependencies[i]); 
     } 
    } 

    if (missingDependencies.length > 0) { 
     return true; 
    } 

    return false; 
} 

有了这个,我能够通过类似下面的,并得到了我想要的:

alert(hasMissingDependencies(['App.FooObject', 'App.BarObject'])); 

我宁愿不使用eval(),但还没有找到另一种方法来检查对象名称作为字符串传递时是否未定义对象。

+0

为什么你需要将它们作为字符串传递? – 2013-04-09 19:04:08

+0

我不知道另一种方法来传递**可能未定义到另一个函数的对象名称。例如,调用'hasMissingDependencies(App.FooObject,App.BarObject)'如果其中任何一个对象没有被定义,就会在它进入函数之前抛出一个错误。我错过了什么吗? – Jared 2013-04-09 19:11:29

+0

你从哪里通过它?你可以看到我的答案是一个可能的解决方案,但是在你传递它们之前检查它们是否存在,然后传递null或者其他一些值,如果不存在,会更简单。 – 2013-04-09 19:13:24

回答

5

假设这些都是全局变量(即不是一个内部函数范围内定义),你可以在句点上分割并使用括号表示法。

function isDefined(name, obj){ 
    if(!obj){ 
     obj = window; 
    } 
    var pathArr = name.split("."); 
    obj = obj[pathArr.splice(0,1)]; 
    if(typeof obj !== undefined){ 

    return pathArr.length ? isDefined(pathArr.join("."),obj): true; 
    } 

    return false; 


} 

需要注意的是,除非你想写一个requireJS更换,这是几乎总是一个坏主意,但。检查值是否存在于你调用该函数的上下文中,如果它们存在,则传入值,否则传入null/undefined /一些默认值。如果您不控制传递的上下文,请询问对象,然后检查它们是否已定义。

+0

已注意。谢谢您的帮助。我打算将这个答案标记为可接受的,因为它是最容易遵循的,但我鼓励任何人使用此线程查看@dystroy的答案,以获得更简洁的版本。 – Jared 2013-04-09 19:33:30

2

您似乎想要检查名称在您的数组中的全局变量是否已定义。

您可以构建一个简单的函数来获取这些变量:

function getVar(name) { 
    var v = window, path=name.split('.'); 
    while (path.length>0 && v) v = v[path.shift()]; 
    return v; 
} 

这样可以让您测试

if (typeof getVar(dependencies[i]) === 'undefined') 
+1

这也是我的想法。尽管如此,这对他的命名空间不起作用。即使App.FooObject存在,window ['App.FooObject']也会返回undefined – 2013-04-09 19:06:48

+1

@ ben336我还没有理解这个需求。我认为现在更好, – 2013-04-09 19:12:59

+2

是的,比我的版本更清洁。 Upvoted。虽然可能值得一提的答案是,这通常不是一个好主意:) – 2013-04-09 19:17:06

相关问题