使用requirejs时访问全局对象

时间:2013-03-16 10:38:02

标签: javascript requirejs amd

我知道不建议使用全局对象,使用AMD背后的整个想法是避免使用全局对象。但是对于一些遗留代码,我必须在全局对象中定义一些东西。目前代码如下所示:

//example2.js
define(function(){
  var globalObject = window;
  globalObject.x = ...
  globalObject.y = ...
});

它有效,但硬编码全局对象window看起来不太好,我很想知道是否可以删除它。如果未使用define(),则代码如下所示:

//example1.js
x = ...
y = ...

我知道,我知道你讨厌这段代码,但让我们谈谈:如何在requirejs中的define()函数内以结构化的方式访问全局变量?我希望函数的隐藏的最后一个参数传递给define(),如下所示:

//example3.js
define(function(globalObject){
  globalObject.x = ...
  globalObject.y = ...
});

甚至更简单:this变量将指向该函数内的全局对象。例如:

//example4.js
define(function(){
  this.x = ...
  this.y = ...
});

注意:我不确定最后一个。调查传递给this的函数内的require()变量说它等于window这可以解答我的问题,但我找不到任何提到传递函数正在运行的上下文的文档。也许它毕竟在全局变量的上下文中运行?

3 个答案:

答案 0 :(得分:15)

我建议你创建一个返回window对象的模块。这对于单元测试目的特别有用(模拟依赖性)。

window.js

define(function(){
   return window;
});

<强> app.js

define(['window'], function(win) {
  // Manipulate window properties
  win.foo = 1;  
  console.log(win.foo);      
});

答案 1 :(得分:5)

如果您没有处于严格模式,可以执行以下操作:

(function() {
  var global = this;

  define(function(){
    global.x = ...
    global.y = ...
  });
})();

我们立即调用的外部匿名函数在没有特定的this值的情况下被调用,因此(因为这不是严格模式),接收全局对象为this。 (在严格模式下,它会收到undefined。)因此我们将this抓取到匿名函数中的变量(global)中,并从您传入的函数中使用它define 1}}(关闭它)。

答案 2 :(得分:5)

@ TJCrowder答案的变体,它也适用于严格模式:

(function(global) {
    define(function() {

        global.a="this";
        global.b="that";

    });
})(this);

通过使用参数&#39;这个&#39;来调用立即调用的函数。 (在函数之外是全局范围),然后无论全局范围如何,它都会作为参数传递到IIF中。&#39; global&#39;。

这也避免了对“窗口”的硬编码。对象,这是一个优点,因为它不适用于非浏览器环境。