Доступ к глобальному объекту при использовании requirejs

149
11

Я знаю, что не рекомендуется использовать глобальный объект, и вся идея использования 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, что может быть ответом на мой вопрос, но я не смог найти документацию, в которой упоминается контекст, который выполняется переданная функция. Может быть, он работает в контексте глобальной переменной?

спросил(а) 2021-01-19T15:53:08+03:00 8 месяцев назад
1
Решение
170

Я предлагаю вам создать модуль, который возвращает объект window. Это особенно полезно для модульного тестирования (издевательские зависимости).


window.js


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

app.js


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

ответил(а) 2021-01-19T15:53:08+03:00 8 месяцев назад
111

Вариант ответа @TJCrowder, который также работает в строгом режиме:


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

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

});
})(this);


Вызвав сразу вызываемую функцию с аргументом 'this' (который вне функции является глобальной областью), то чем бы ни была глобальная область, она передается в IIF как аргумент global.


Это также позволяет избежать жесткого кодирования объекта "window", что является преимуществом, поскольку оно не применяется в нерабочих средах.

ответил(а) 2021-01-19T15:53:08+03:00 8 месяцев назад
111

Если вы не находитесь в строгом режиме, вы можете сделать это:


(function() {
var global = this;

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

Внешняя анонимная функция, которую мы немедленно вызываем, вызывается без особого специального значения this, и поэтому (поскольку это не в строгом режиме), глобальный объект получает this. (В строгом режиме вместо этого он получит undefined.) Таким образом, мы захватываем this в переменную (global) внутри анонимной функции и используем ее из функции, которую вы передаете в define (которая закрывается над ней).

ответил(а) 2021-01-19T15:53:08+03:00 8 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема