Как объявить глобальные переменные при использовании строгого режима прагма
Считалось, что хорошая практика заключается в использовании функции самозапускания для привязки строгого режима к коду, часто называемого прагмой строгого режима:
(function(){
"use strict";
// Strict code here
}());
Мой вопрос в том, как объявить глобальные переменные в этом случае? Три альтернативы, которые я знаю сегодня:
Альтернатива 1:
var GLOB = {};
(function(){
"use strict";
}());
Альтернатива 2:
(function(){
"use strict";
window.GLOB = {};
}());
Альтернатива 3:
(function(win){
"use strict";
win.GLOB = {};
}(window));
Любые предпочтения и мотивации? Другие варианты?
Ответы
Ответ 1
Альтернатива IMO 3 лучше. Но предполагается, что window
представляет глобальную область действия, что верно для браузера, но не для других сред JS (командная строка, Node.js и т.д.).
Следующее будет работать по всем направлениям:
(function(globals){
"use strict";
globals.GLOB = {};
}(this));
Ответ 2
Я знаю, что это старый вопрос, но там не упоминается способ получения глобального контекста:
(function(globals){
"use strict";
globals.GLOB = {};
}( (1,eval)('this') ));
(1,eval)('this')
будет оценивать this
из глобального контекста, поэтому вы можете вставлять его везде, где хотите, и вы всегда будете получать глобальный контекст
Ответ 3
Метод 1 будет терпеть неудачу, если он вставлен в другую функцию.
Используя метод 3, проще экспортировать свои методы в другое пространство имен. Просто заменить window
на, скажем, frames[0]
или document
достаточно, чтобы прикрепить все методы к пользовательскому пространству имен.
Я рекомендую метод 3 по последней причине.
Ответ 4
Преимущество alt 2 и 3 заключается в том, что они сохраняют весь код внутри "контейнерной функции". При чтении кода легко пропустить одну строку кода вне функции.
также:
- "GLOB" должно быть именем приложения. - Вы хотите разрешить использование более одного приложения в файле html/js без конфликтов имен.
Ответ 5
У Андреа Джаммархи есть хорошая техника для этого, которая работает в браузерах. Определите функцию в вашей самозапускаемой функции globalEval следующим образом:
(function () {
"use strict";
function globalEval(data) {
data = data.replace(/^\s*|\s*$/g, "");
if (data) {
var head = document.getElementsByTagName("head")[0] || document.documentElement,
script = document.createElement("script");
script.type = "text/javascript";
script.text = data;
head.appendChild(script);
head.removeChild(script);
}
}
// use globalEval to stick variables into the global scope
globalEval("var myGlobal = 1;");
// myGlobal === 1
)();
// myGlobal === 1
Или определите функцию globalEval вне кода самозапускания, если вы хотите использовать его в других областях.