Доступ к глобальному объекту при использовании requirejs
Я знаю, что не рекомендуется использовать глобальный объект, и вся идея использования 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()
, говорит о том, что она равна window
, что может быть ответом на мой вопрос, но я не смог найти документацию, в которой упоминается контекст, который выполняется переданная функция. Может быть, он работает в контексте глобальной переменной?
Ответы
Ответ 1
Если вы не находитесь в строгом режиме, вы можете сделать это:
(function() {
var global = this;
define(function(){
global.x = ...
global.y = ...
});
})();
Внешняя анонимная функция, которую мы немедленно вызываем, вызывается без особого специального значения this
, и поэтому (поскольку это не в строгом режиме), глобальный объект получает this
. (В строгом режиме вместо этого он получит undefined
.) Таким образом, мы захватываем this
в переменную (global
) внутри анонимной функции и используем ее из функции, которую вы передаете в define
(которая закрывается над ней).
Ответ 2
Я предлагаю вам создать модуль, который возвращает объект window
. Это особенно полезно для модульного тестирования (издевательские зависимости).
window.js
define(function(){
return window;
});
app.js
define(['window'], function(win) {
// Manipulate window properties
win.foo = 1;
console.log(win.foo);
});
Ответ 3
Вариант ответа @TJCrowder, который также работает в строгом режиме:
(function(global) {
define(function() {
global.a="this";
global.b="that";
});
})(this);
Вызвав сразу вызываемую функцию с аргументом 'this' (который вне функции является глобальной областью), то чем бы ни была глобальная область, она передается в IIF как аргумент global.
Это также позволяет избежать жесткого кодирования объекта "window", что является преимуществом, поскольку оно не применяется в нерабочих средах.