Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > зачем использовать window


Автор: YahоО 9.1.2020, 00:41
Разбираю найденный код, и появился такой вопрос: 
Почему (зачем) в скрипте внутри функции объявляется переменная, и дальше используется window. чтобы она была видна вне анонимной функции :
Код

;(function(window){
 var Fakt =... //много разного кода, много переменных, которые не нужны в глобальной области видимости
 window.fakt = new Fakt();     //переменная становится свойством глобального объекта - и зачем это нужно?
})(this);
fakt.init();
...


вместо того чтобы сразу, т.е. еще до выполнения анонимной функции объявить нужную (эту же) переменную и не использовать window для присвоения ей значения?
Код

var fakt;
;(function(){
 var Fakt=... //много разного кода, много переменных, которые не нужны в глобальной области видимости
 fakt = new Fakt();
})();
fakt.init();
...

Так понимаю что сам на этот вопрос ответа не найду :(
Может мне просто так удобнее как во втором варианте?


Автор: ksnk 9.1.2020, 12:57
Так, на вскидку - переменая `Fakt` имеет глобальную область видимости. Так и должно быть, или это просто опечатка?

По сути - код разбит на 2 части - описание и инициализация. Обычно, обе части располагаются в разных местах страницы сайта. К примеру инициализация счетчика яндекса и скрипт, в котором он описан. Это объясняется особенностями броузерного кэширования. Инициализация вставляется в том месте, которое будет удобнее редактировать, например в тег script выдаваемой html. Так что разделить 2 части на 3 это не очень хорошая идея, в перспективе smile 
Если в данном случае отдельной инициализации не требуется и отдельной видимой снаружи переменой возможно и не нужно - кто мешает инициировать все это добро прямо в описании ?
Код

;(function(window, args){
...
 fakt = new Fakt();
 fakt.init.apply(window, args)
})(this, [arg1,arg2...]);



Автор: YahоО 9.1.2020, 17:32
ksnk, спасибо за отклик! Еще вчера понял что не все там правильно записал в своем вопросе-примере, не то чтобы опечатка, а даже ошибка там была, но тем не менее Вы все верно прочитали. 
Подредактировал свой пример.
Код разбит на 2 части - описание и инициализация, это понятно, можно даже в анонимной функции инициализировать:
Код

var fakt;

(function(){
 var Fakt=... //много разного кода, много переменных, которые не нужны в глобальной области видимости
 fakt = new Fakt();
 fakt.init();
})();
...

но мой вопрос о другом, попробую его еще раз как то переписать по другому, может и сам его пойму:

зачем нам 
  window.fakt 
если можно иметь 
  var fakt; 
это разве одно и тоже? И если есть разница, то чем она заключается?

Автор: YahоО 9.1.2020, 18:11
В javascript скорость выполнения функций как то не особо зависит от того объявлена ли переменная, или ее используют без объявления сразу присваивая ей значение (замеров не делал, но и не было необходимости такой),
но все четко заметно в excel vba, где разница во времени просто ощутима, примерно как одна секунда и много много секунд для одних и тех же действий с одними и теми же данными.
Понятно что в этом вопросе javascript более шустрый, но непонятно в чем смысл и какая то разница все же должна быть, если мы объявим переменную var то как это отражается на window, и если просто использовать window.fakt

Автор: ksnk 9.1.2020, 18:36
Использовать глобально видимую во всем приложении переменную можно, когда обработчики событий вставляются прямо в верстке. Например где-то в шаблоне сайта забито что-то вроде <div ... onclick="return fact.dosomething();'...;
если таких вставок в шаблонах или использование еще в каких местах не предполагается, то использовать глобальную область видимости не нужно и даже вредно. На скорость выполнения область видимости не влияет, практически, но если какой-то скрипт тоже захочет использовать глобальную переменную с таким же именем - будет много интересной отладки на вполне, вроде бы, работающем коде... Замыкание тут используется для того, чтобы такого геморроя на ровном месте было поменьше.

Разница var fakt и window.fakt в том, что не обязательно глобальная область видимости может называться window. Для броузерных скриптов - да, обычно это так, но если скрипт подтягивается аяксом или вставлен в какой-нибудь обрамляющее замыкание, как делают минимизаторы, то возможны разные варианты. imho, лучше window.fakt

Автор: YahоО 9.1.2020, 22:24
"Использовать глобально видимую во всем приложении переменную можно, когда обработчики событий вставляются прямо в верстке. Например где-то в шаблоне сайта забито что-то вроде <div ... onclick="return fact.dosomething();'...;
если таких вставок в шаблонах или использование еще в каких местах не предполагается, то использовать глобальную область видимости не нужно и даже вредно. "

Но ведь fakt и есть в данном случае глобально видимая во всем приложении переменная. По любому. То ли как var fakt , то ли как window.fakt .
Использовать глобальную область видимости не нужно и даже вредно - да как же это????? куда же девать этот самый   fakt ? он уже в этой видимости, глобальной. Чтобы убрать его оттуда придется вообще весь код упрятать анонимку?!

В "учебнике" читаю: 
  Все переменные, объявленные вне функций, попадают в глобальную область видимости.
  Переменная, инициализированная без ключевого слова var, также имеет в глобальную область видимости.
Другими словами все варианты использования в приведенном примере переменной fakt обязательно попадают в глобальную область видимости.

Если скрипт подтягивается аяксом / fetch и / или вставлен через new Function / eval то и здесь те же "правила", потому что новые имена переменных появляются внутри new Function / eval и являются локальными, а чтобы они не были локальными их надо объявлять отдельно, в корне а не во вставке.

Не обязательно глобальная область видимости может называться window - нууу есть глобальная локальная и блочная область видимости, о других не слышал, но как бы глобальная всегда window ?

Это я так понимаю, а как на самом деле кто знает, может и так всё.

Лучше так, или так, думал что как лучше где то должно быть написано, оказывается если специально не написали в мануалах об этом, то наверно совсем не интересный мой вопрос, а значит и не нужный,
а хотелось что б уж совсем совсем совсем "правильно" smile


Автор: ksnk 9.1.2020, 23:10
Цитата(YahоО @  9.1.2020,  22:24 Найти цитируемый пост)
Но ведь fakt и есть в данном случае глобально видимая во всем приложении переменная.

Глобальные переменные лучше не использовать. Просто потому что их можно в любом месте грязными руками поменять и получить неожиданный и плохо уловимый глюк. С большой вероятностью - ты сам через пару месяцев, когда этот код уже забудется и нужно будет вставить подобную штуку на этот же сайт. Привычка к названиям переменных остается smile Если можно без особо страшного геморроя выкинуть глобальность этой переменной - то так и нужно сделать. Если в коде уж очень серьезные закладки на глобальность - на уровне вставок в шаблоне или других скриптах, то да, не получится так просто, энергетически выгоднее наплевать и оставить глобальной...

Цитата(YahоО @  9.1.2020,  22:24 Найти цитируемый пост)
Не обязательно глобальная область видимости может называться window

В node.js , например, объекта window нет. Есть объект global. Так как язык один и тот же, иногда появляется желание получить код работающий в обоих местах. 


Автор: YahоО 9.1.2020, 23:55
Объект global он же тоже где то находится? В глобальной видимости, т.е. в  window? хотя возможно к window там обращений как таковых может и нет.

ksnk, еще раз благодарю за разъяснения, простите если отнял понапрасну Ваше время и внимание, поскольку вопрос мой не оказался полезным для практического его использования.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)