6

我刚刚开始在一家新公司工作,并注意到他们的许多 JS 对我来说看起来完全错误。我有点犹豫是否要在没有确认这是错误的情况下提出它,因为我还很初级,我不是 JS 专家,这只是我的第二天,我不想看起来很愚蠢。

所以,通常我希望模块模式看起来像:

MODULENAME = MODULENAME || {};

MODULENAME.SUBMODULENAME = (function() {
    var bla = {};

    bla.somefunction = function() {
        //do stuff
    };

    //add more stuff to bla
    return bla;
}());

他们在代码中的全部内容是:

MODULENAME = MODULENAME || {};

MODULENAME.SUBMODULENAME = (function() {
    var that = this;

    that.somefunction = function() {
        //do stuff
    };

    //add more stuff to that
    return that;
}());

现在当然是因为该函数没有被作为带有new关键字或方法的构造函数调用,this所以绑定到window并且它们定义thatthis. 所以他们基本上把所有东西都转储到了全局对象中,他们所有的子模块名称实际上都是window. 有人愿意这样做吗?或者这真的像我认为的那样错误吗?

编辑:

我在var子模块定义之前犯了一个错误,最初我写了一些稍微不同的东西,忘记删除var. 我也试图让这个例子更清楚一些,希望我现在的意思更明显。

编辑2:

此外,我查看了在 Firebug 中执行的脚本,它们肯定将所有内容添加到window,该对象完全是一团糟。

4

2 回答 2

3

是的,它看起来不对。

MODULENAME = MODULENAME || {}; // missing var

var MODULENAME.SUBMODULENAME = (function() { // probably the missing var from above...
    var that = this;
    //add some stuff to that
    return that; // that is the WINDOW- wrong.
}());

演示它可以造成的损害:

var x = function() {
    alert('out');
}
var MODULENAME = MODULENAME || {};

MODULENAME.SUBMODULENAME = (function() {
    var that = this;
    that.x = function() {
        alert('DAMAGE');
    }
}());

x();​ // alert DAMAGE and not "out" - messed up with the global object!
于 2012-05-09T01:18:30.763 回答
0

模块模式的使用不正确,这也是为什么不应使用函数表达式的原因之一,因为它们的使用对函数声明没有任何帮助。如果目的是创建全局函数(我怀疑它是),那么他们应该使用:

function somefuncion() {
  ...
}

如果他们的意图是向对象添加属性(在这种情况下为方法),这很可能是这种情况,那么:

MODULENAME.SUBMODULENAME.somemethod = function() { /* do stuff */ };

如果需要有条件地创建方法,例如基于特征检测,那么以下可能适合:

(function(global, undefined) {

  // In here global is the global object
  global.MODULENAME = global.MODULENAME || {};
  global.MODULENAME.SUBMODULENAME = global.MODULENAME.SUBMODULENAME || {};

  // and undefined is undefined, belt and braces approach
  undefined = void 0;

  // Direct assignment
  function somemethod() {
      //do stuff      
  };

  // Assign directly to the "namespace" object
  MODULENAME.SUBMODULENAME.somemethod = somemethod;

  // Conditional assignment
  if ( sometest ) {
    MODULENAME.SUBMODULENAME.anothermethod = function(){...};

  // Try another way...
  } else if (someOtherTest) {
    MODULENAME.SUBMODULENAME.anothermethod = function(){...};

  // Default
  } else {
    MODULENAME.SUBMODULENAME.anothermethod = function(){...};
  }

  // Clean up 
  global = null;

}(this)); 

上面的一个问题是,在外部函数内部声明的每个函数都有一个返回函数对象及其环境的闭包,因此有点浪费资源。保持简单并且只在真正需要的地方使用模块模式并在不需要的地方使用普通的函数声明和赋值会更有效。不那么时髦,但更实用。

于 2012-05-09T03:04:26.193 回答