10

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

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

它可以工作,但是对全局对象进行硬编码window看起来不是很好,我很想知道是否可以删除它。不使用时define(),代码如下所示:

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

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

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

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

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

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

4

3 回答 3

15

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

窗口.js

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

应用程序.js

define(['window'], function(win) {
  // Manipulate window properties
  win.foo = 1;  
  console.log(win.foo);      
});
于 2014-09-16T09:23:08.253 回答
5

如果你不是在严格模式下,你可以这样做:

(function() {
  var global = this;

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

我们立即调用的外部匿名函数没有特定的特殊this值,因此(因为这不是在严格模式下)接收全局对象为this. (在严格模式下,它会接收undefined。)所以我们在匿名函数中抓取this一个变量(global),并从你传入的函数中使用它define(关闭它)。

于 2013-03-16T10:40:54.133 回答
5

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

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

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

    });
})(this);

通过使用参数“this”(函数外部是全局范围)调用立即调用的函数,然后无论全局范围是什么,它都会作为参数“global”传递到 IIF。

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

于 2015-05-06T05:58:01.803 回答