简体   繁体   English

如何像使用成员函数而不使用eval一样使用字符串引用闭包?

[英]How can I reference a closure using a string the same way I do it with a member function without using eval?

We have some js code splitted in many files. 我们有一些js代码分割成许多文件。 We have a core file that defines code used by many other js files. 我们有一个核心文件,该文件定义了许多其他js文件使用的代码。

Currently we have something like this: 目前,我们有这样的事情:

core.js: core.js:

window.mycore = function() {

    var myfunction1 = function() {
    };
    var myfunction2 = function() {
    };
    var myfunction3 = function() {
        //..
        var a =  myfunction1(b);
        //..        
    };
    //...
    // many "myfunction"
    //...
    var myfunctionN = function() {
    };
    var publish = function() {
        for(var i = 0; i < arguments.length; i++) {
            try {
                window.mycore[arguments[i]] = eval('(' + arguments[i] + ')');
            }
            catch(e) {
                Log.err(600, arguments[i], e);
            }
        }
    };
    publish("myfunction1", "myfunction7", "myfunction8",/*...*/"myfunctionM")
}

app.js: app.js:

// ...
// ...
var result = window.core.myfunction1("myparam");
// ...
// ...

Note that none core methods are declared as members of the window.core object. 请注意,没有任何核心方法被声明为window.core对象的成员。 Instead they are attached to the core object with the publish function. 而是使用发布功能将它们附加到核心对象。

This has some pros: 这有一些优点:

  • The core code can reference any core function without the need of writing "window.core." 核心代码可以引用任何核心功能,而无需编写“ window.core”。
  • We avoid writing "var myfunction = window.mycore.myfunction = function() ..." in every public function declaration 我们避免在每个公共函数声明中都写“ var myfunction = window.mycore.myfunction = function()...”
  • The exposed methods can be seen centraliced. 可以看到暴露的方法是集中的。

But, the use of eval in the publish function is bringing us problems when using code analysis tools since they don't tend to understand eval declarations. 但是,在发布功能中使用eval会给我们带来使用代码分析工具时遇到的问题,因为它们不倾向于理解eval声明。

So, here is my question. 所以,这是我的问题。 Which is the better way to improve this code, so we can keep the advantages mentioned but eradicating the eval declaration. 这是改进此代码的更好方法,因此我们可以保留上面提到的优点,但可以消除eval声明。 I am aware of the solution of sending to the publish function some name/value pairs like publish({'myfunction1': myfunction1}, ... ), but I also want to avoid function name repetitions. 我知道将一些名称/值对发送给publish函数的解决方案,例如publish({'myfunction1':myfunction1},...),但是我也想避免函数名重复。 Consider that I am not looking for radical changes since there is a lot of code written already. 考虑到我没有在寻找根本的改变,因为已经编写了很多代码。

Thanks! 谢谢!

I'm not sure I understand completely your reasons for using the "publish" method, but is there any reason your not just returning an object with the correct functions from your constructor? 我不确定我是否完全理解您使用“发布”方法的原因,但是有什么原因使您不只是从构造函数中返回具有正确函数的对象吗?

ie: 即:

window.mycore = (function() {
   var myFunc1 = function(a) {
      alert(a);
   };

   var myFunc2 = function(b) {
      // call to other function in the same scope
      myFunc1(b);
   }

   ...

   // at the end just expose the public members you want
   return {
      myFunc1: myFunc1,
      myFunc2: myFunc2
   };
})();

or 要么

window.mycore = (function() {
   return {
      myFunc1: function(a) {
         alert(a);
      },
      myFunc2: function(b) {
         this.myFunc1(b);
      }
   };
})();

or, yet another way to end up with the same object :) ... as always there are different ways to get there 或者,以相同的对象结束的另一种方法:) ...一如既往,有不同的方法可以到达那里

(function(){

    var o = {};

    o.func1 = function(a) {
        alert(a);
    }

    o.func2 = function(b) {
        this.func1(b);
    }

    window.mycore = o;

})();

So, at a fundamental level, I think it would have benefitted you to have written those name spaces as objects. 因此,从根本上来说,我认为将那些名称空间作为对象编写将使您受益。 But thats a whole different subject entirely. 但这完全是一个完全不同的主题。 (and it disqualifies based on the fact that you dont want to do a lot of refactoring). (它基于您不想进行大量重构的事实而被取消资格)。

With that said, my first idea was that you could probably sidestep the need for eval by using the .call() or .apply() method. 随着中说,我的第一个想法是,你很可能通过回避对EVAL需要.call().apply()方法。 What they allow you to do is to chain a function call out of your function name. 它们允许您执行的操作是将函数调用链接到函数名称之外。 but that doesn't apply to a "string" which is what you're giving your publish function. 但这不适用于您要提供的发布功能的“字符串”。

so after googling, this is how you execute a function from a string: 因此,在谷歌搜索之后,这就是从字符串执行函数的方式:

var fn = window[settings.functionName];
if(typeof fn === 'function') {
    fn(t.parentNode.id);
}

https://stackoverflow.com/a/912642/680578 https://stackoverflow.com/a/912642/680578

Personally I prefer the @Jaime approach, but maybe you may do something like 我个人更喜欢@Jaime方法,但也许您可以做类似的事情

window.mycore = function() {

    function myfunction1() {
    };
    function myfunction2() {
    };
    function myfunction3() {
       //..
       var a =  myfunction1(b);
       //..        
    };
    //...
    // many "myfunction"
    //...
    function myfunctionN() {
    };
    var publish = function() {
       for(var i = 0; i < arguments.length; i++) {
          try {
             window.mycore[arguments[i].name] = arguments[i];
          }
          catch(e) {
             Log.err(600, arguments[i].name, e);
          }
       }
    };
    publish(myfunction1, myfunction7, myfunction8,/*...*/myfunctionM);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不使用Eval的情况下调用匿名函数? - How can I call anonymous function without using Eval? 如何在不使用eval的情况下调用不存在的(非成员,非全局)方法? - How do I make a nonexistent (non-member, non-global) method invocable without using eval? 关于javascript中的eval()的问题...为什么它是邪恶的,如何在不使用它的情况下完成同样的事情? - A question about eval() in javascript… why is it evil and how can I accomplish the same thing without using it? 如何使用闭包概念获得相同的输出 - How do I get the same output using the closure concept 如何在不使用eval()的情况下使用回调更新包装函数的条件? - How can I update the condition in a function-wrapped while with callback without using eval()? 如何在不使用eval的情况下动态访问JSON节点? - How can i reach a JSON node dynamically without using eval? 如何在不使用eval()的情况下在Backbone.js中创建不同的链接? - How can I have links which do different things in Backbone.js without using eval()? 有没有其他方法可以使该计算器在没有eval函数的情况下工作? - Is there an alternative way i can make this calculator work without the eval function? 如何在不使用eval()的情况下将完整功能字符串转换为javascript函数 - how to convert a full function string to a javascript function without using eval() 如何在不使用 javascript 中的替换函数的情况下替换字符串? - How do I replace a string without using the replace function in javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM