简体   繁体   中英

accessing global object when using requirejs

I know it's not recommended to use the global object and the whole idea behind using AMD is to avoid using the global object. But for some legacy code, I have to define some stuff in the global object. Currently the code looks like this:

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

It works but hard coding the global object window doesn't look very nice and I'm curious to see if it is possible to remove it. When define() was not used, the code looked like this:

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

I know, I know you hate this code, but let's be to the point: how can the global variable be accessed in a structured manner inside the define() function in requirejs? I wish there was something like a hidden last parameter to the function that is passed to the define() like this:

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

Or even simpler: the this variable would point to the global object inside that function. For example:

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

Note: I'm not sure about this last one. Investigating the this variable inside the function that is passed to require() says that it is equal to window which can be the answer to my question, but I haven't been able to find any documentation that mentions the context that the passed function is running. Maybe it is running in the context of the global variable after all?

I suggest you to create a module that returns the window object. This is specially useful for unit testing purposes (mocking dependencies).

window.js

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

app.js

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

If you're not in strict mode, you can do this:

(function() {
  var global = this;

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

The outer anonymous function that we immediately invoke is invoked with no particular special this value, and so (since this isn't in strict mode), receives the global object as this . (In strict mode, it would receive undefined instead.) So we grab this into a variable ( global ) within the anonymous function, and use it from the function you pass into define (which closes over it).

A variation on @TJCrowder's answer, which also works in strict mode:

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

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

    });
})(this);

By calling the immediately invoked function with the argument 'this' (which outside a function is the global scope), then whatever the global scope is it gets passed into the IIF as the argument 'global'.

This also avoids hard-coding to the 'window' object, an advantage since that doesn't apply in non-browser environments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM