4

我们有一些 js 代码拆分在许多文件中。我们有一个核心文件,它定义了许多其他 js 文件使用的代码。

目前我们有这样的事情:

核心.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")
}

应用程序.js:

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

请注意,没有核心方法被声明为 window.core 对象的成员。相反,它们通过发布功能附加到核心对象。

这有一些优点:

  • 核心代码可以引用任何核心函数,无需编写“window.core”。
  • 我们避免在每个公共函数声明中写“var myfunction = window.mycore.myfunction = function() ...”
  • 可以看到暴露的方法是集中的。

但是,在发布函数中使用 eval 给我们在使用代码分析工具时带来了问题,因为它们往往不理解 eval 声明。

所以,这是我的问题。哪个是改进此代码的更好方法,因此我们可以保留提到的优点但消除 eval 声明。我知道将一些名称/值对发送到发布函数的解决方案,例如 publish({'myfunction1': myfunction1}, ... ),但我也想避免函数名称重复。考虑到我不是在寻找根本性的变化,因为已经编写了很多代码。

谢谢!

4

3 回答 3

2

我不确定我是否完全理解您使用“发布”方法的原因,但是您是否有任何理由不只是从构造函数返回具有正确函数的对象?

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
   };
})();

或者

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

或者,以另一种方式结束同一个对象:) ...一如既往有不同的方法可以到达那里

(function(){

    var o = {};

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

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

    window.mycore = o;

})();
于 2012-05-10T14:43:34.340 回答
0

因此,从根本上讲,我认为将这些名称空间编写为对象会对您有所帮助。但这完全是一个完全不同的主题。(并且基于您不想进行大量重构的事实而取消资格)。

话虽如此,我的第一个想法是,您可能可以通过.call()使用or.apply()方法来回避对 eval 的需求。他们允许你做的是将函数调用从你的函数名中链接出来。但这不适用于您提供发布功能的“字符串”。

所以在谷歌搜索之后,这就是你从字符串执行函数的方式:

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

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

于 2012-05-10T14:43:47.773 回答
0

我个人更喜欢@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);
}
于 2012-05-10T14:57:44.050 回答