Это плохая практика, объявляющая глобальные переменные в файле a.js?

У меня есть файл .js, где я инициализирую два параметра, которые используются в отдельной функции:

var submyvar1;
var submyvar2;

function init(myvar1 , myvar2){
    submyvar1= myvar1;
    submyvar2= myvar2;
}

function (){
    //subvar1 & subvar 2 used here
}

Является ли объявление глобальных переменных подобным образом плохой практикой?

Если да, в чем альтернатива, оберните весь .js-файл в объект?

3
nl ja de
добавлено автор Eliran Malka, источник

4 ответы

По крайней мере, это не хорошая практика, вы можете использовать выражение , вызванное вызываемой функцией :

(function() {
    var x;
    var y;

    window.init = function(xValue, yValue) {
        x = xValue;
        y = yValue;
    }

    window.doWhateverYouWant = function() {
        console.log(x + y);
    }
}());

You could use this pattern unless you need access your global variable outside this .js file, when an cross-accessing between .js files or <script> elements are required, global variable is a simple solution (although you could use AMD or sth else instead).

3
добавлено
@otakustay Как инициализировать эту функцию из внешнего файла? Нужно ли мне назначать функцию var, а затем называть ее каким-то образом?
добавлено автор blue-sky, источник
@otakustay Мне нужно иметь доступ к методам функций вне файла .js.
добавлено автор blue-sky, источник
Вы правы, разработчики экспортируют все, что захотят, с помощью шаблона window.foo = ... .
добавлено автор otakustay, источник
@ user470184 Что означает initialize ? поместите мой код в a.js , затем загрузите его в свой HTML, например <script src = "a.js"> </script> , затем вы можете позвонить < code> init , например <script> init (1, 2); </script> .
добавлено автор otakustay, источник
@ user470184 Конечно, вы можете, все, что было определено с помощью шаблона window.foo = ... , можно было получить в любом месте, внутри или вне вашего .js-файла
добавлено автор otakustay, источник
Теперь x и y не отображаются в глобальном масштабе, но (и я могу ошибаться) init и doWhateverYouWant ,
добавлено автор Kristof Claes, источник

I decided to use a revealing module pattern as described at : Nice article here on a possible implementation using the 'Revealing Module Pattern' : http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/

Его очень похоже на принятый ответ.

Вот пример шаблона, описанный выше, над машиной:

We looked at the Self-Executing Anonymous Function earlier as a pattern you could use to keep all your code private. As it turns out, you can actually modify the pattern somewhat so that you can achieve the same benefits of the Revealing Module Pattern. Not only can we achieve public and private properties and methods, but we can also provide an easy way to extend the namespace while keeping the content protected from the global namespace. In addition, the following pattern can protect the $ from conflicting with other JavaScript libraries and also protect undefined from being redefined.

Take a look at the following example, and we will walk through the code explaining the key changes to the pattern.


//Self-Executing Anonymous Func: Part 2 (Public & Private)
(function( skillet, $, undefined ) {
    //Private Property
    var isHot = true;

    //Public Property
    skillet.ingredient = "Bacon Strips";

    //Public Method
    skillet.fry = function() {
        var oliveOil;

        addItem( "\t\n Butter \n\t" );
        addItem( oliveOil );
        console.log( "Frying " + skillet.ingredient );
    };

    //Private Method
    function addItem( item ) {
        if ( item !== undefined ) {
            console.log( "Adding " + $.trim(item) );
        }
    }    
}( window.skillet = window.skillet || {}, jQuery ));

//Public Properties
console.log( skillet.ingredient ); //Bacon Strips

//Public Methods
skillet.fry(); //Adding Butter & Fraying Bacon Strips

//Adding a Public Property
skillet.quantity = "12";
console.log( skillet.quantity ); //12

//Adding New Functionality to the Skillet
(function( skillet, $, undefined ) {
    //Private Property
    var amountOfGrease = "1 Cup";

    //Public Method
    skillet.toString = function() {
        console.log( skillet.quantity + " " + 
                     skillet.ingredient + " & " + 
                     amountOfGrease + " of Grease" );
        console.log( isHot ? "Hot" : "Cold" );
    };    
}( window.skillet = window.skillet || {}, jQuery ));

try {
    //12 Bacon Strips & 1 Cup of Grease
    skillet.toString(); //Throws Exception
} catch( e ) {
    console.log( e.message ); //isHot is not defined
}
You can execute and modify the above code from jsFiddle.

First, since we have a Self-Executing Anonymous Function, we can actually provide some parameters to pass to it when it executes. In this case we are passing 2 arguments to the anonymous function.

The first argument looks quite strange. What is window.skillet = window.skillet || {} doing? The code checks to see if skillet exists in the global namespace (window). If it does not exist, then window.skillet is assigned an empty object literal. Using this approach we can build a library across JavaScript files. If another script uses the same technique, then it will pass in the existing instance and append logic to it. Inside the Anonymous Function, if we want something to be public, then we append it to the skillet object. Any other properties or methods will be considered private.

The second argument passed in jQuery. The benefit of this is that the named parameter is referenced as $, which allows us to refer to jQuery as $ within the Anonymous Function without having to worry that it will conflict with the $ declared in other JavaScript libraries. This is a common practice that you will most likely run across when looking at well written jQuery code.

You might notice a 3rd parameter to the Anonymous Function called undefined. Why did we add that parameter and why didn’t we pass an argument to it? In JavaScript, you can unfortunately redefine what undefined means. Imagine that some code somewhere deep in one of your 3rd party libraries redefines undefined to something strange like true. If anywhere in your code you test against undefined, then you code will most likely not behave like you intended. In JavaScript, if you have a parameter that doesn’t have a matching argument, then it’s value is set as undefined. By using this trick, it can save us from the bad code someone wrote to redefine undefined.

Pros

Gives you the ability to have public and private properties and methods
The code inside doesn’t use the Object Literal notation
Keeps undefined’s value as undefined in case someone overrode the value
Allows you to use $ inside your code without worrying about clashing with other libraries
Allows your library to grow across files using the “window.namespace = window.namespace || {}” technique
A common pattern that you will see in many libraries, widgets, and plugins
Cons

Slightly more complicated pattern, but not overly difficult to understand
If you are interested in digging deeper into some of the patterns I mentioned above then I encourage you to check out Klaus Komenda’s post entitled JavaScript Programming Patterns. The article provides an insightful view of how JavaScript patterns have changed over the years. 
1
добавлено

Вы должны избегать этого, где это возможно, чтобы предотвратить загромождение глобального пространства имен. Вероятно, будут биты вашего кода, которые вы хотите разоблачить, так что в этом случае все в порядке. Например, jQuery, очевидно, должен сделать переменные jQuery и $ глобальными (он делает это, создавая им свойства окна ).

Чтобы этого избежать, вы можете включить свой код в функцию с последующими скобками:

var mySingleGlobalVar = (function() {
    var submyvar1;
    var submyvar2;

    function init(myvar1 , myvar2){
        submyvar1= myvar1;
        submyvar2= myvar2;
    }

    function (){
        //subvar1 & subvar 2 used here
    }

    return init;
}());

Это функция, которая выполняется немедленно. В этом примере я выделил возвращаемое значение (функция init) для глобального var, и это единственный глобальный var, который создаст ваш скрипт (если вы все правильно объявите их с помощью var ).

1
добавлено
«загромождать глобальное пространство имен», это означает, что если кто-то другой использует одно и то же имя var в отдельном файле .js, объявленном так же, как исходный вопрос (глобально), движок JS будет использовать любую переменную, с которой он сталкивается в первую очередь?
добавлено автор blue-sky, источник
для доступа к методам функций вне файла .js я использую что-то вроде mySingleGlobalVar.myFucntion (param1) ....?
добавлено автор blue-sky, источник
Да, за исключением того, что он будет использовать то, что он встретит последним! Кроме того, если они используют ключевое слово var в строгом режиме, когда переменная уже объявлена, она выдает ошибку.
добавлено автор Nathan MacInnes, источник
Нет, просто mySingleGlobalVar (param1, param2) . mySingleGlobalVar - это переменная, которая указывает на функцию.
добавлено автор Nathan MacInnes, источник

В JavaScript: хорошие части (также подведено здесь ) предлагается:

Глобальные переменные ослабляют отказоустойчивость программ и должны быть   избегать. Одним из способов минимизации использования глобальных переменных является создание единого   глобальная переменная для вашего приложения:

  var MYAPP = {};
 
     

Эта переменная становится контейнером для вашего приложения:

  MYAPP.stooge = {
    «имя»: «Джо»,
    «фамилия»: «Говард»};
 
     

Уменьшая глобальный охват до одного имени, вы значительно   уменьшить вероятность плохого взаимодействия с другими приложениями,   виджеты или библиотеки. Ваша программа также становится легче читать   потому что очевидно, что MYAPP.stooge относится к высокоуровневому   структура.

1
добавлено
JavaScript Jobs — чат
JavaScript Jobs — чат
8 336 участник(ов)

JavaScript Jobs — чат для поиска работы и людей Правила оформления: https://teletype.in/@telegram-ru/r1WQe5F1m См. также: @mobile_jobs, @devops_jobs, @nodejs_jobs, @react_js, @angular_ru, @js_ru

JavaScript.ru
JavaScript.ru
7 932 участник(ов)

Сообщество сайта JavaScript.ru в Slack.

pro.js
pro.js
4 675 участник(ов)

Про JavaScript и NodeJS Invite: https://t.me/joinchat/Be4rsT5Rsgq30DHutjxXgA Правила: http://telegra.ph/ru-chat-rules-06-19 Вакансии только с ЗП, не чаще раза в неделю.

Верстка сайтов HTML/CSS/JS/PHP
Верстка сайтов HTML/CSS/JS/PHP
3 439 участник(ов)

Правила группы: напишите !rules в чате. Группа Вк: vk.com/web_structure Freelancer: @web_fl Веб Дизайн: @dev_design Маркетолог: @topmarkening Автор: @M_Boroda

JavaScript — русскоговорящее сообщество
JavaScript — русскоговорящее сообщество
3 269 участник(ов)

Рекомендуем сразу отключить уведомления Правила: https://rudevs.network/ByaMH6un7 См. также: @js_noobs_ru, @nodejs_ru, @typescript_ru, @react_js, @electron_ru Вакансии и поиск работы: @javascript_jobs

JavaScript Noobs — сообщество новичков
JavaScript Noobs — сообщество новичков
2 484 участник(ов)

Чат для новичков

javascript_ru
javascript_ru
915 участник(ов)

Сообщество любителей самого популярного языка программирования в мире. Чат основан в 2009 году. Логи: https://goo.gl/9EOeM7 Поддержка бота: @chat_linker (ссылка на репу внутри) Вам будут интересны @frontend_ru и @css_ru

jsChat
jsChat
603 участник(ов)

Чат посвященный программированию на языке javaScript Перед отправкой ссылки на Ваш контент посоветуйтесь с админом Все ссылки удаляются ботом автоматически

JavaScript for Zombies Chat
JavaScript for Zombies Chat
492 участник(ов)

Чат про JavaScript для настоящих zombie! Вход строго по приглашениям! Ссылка для строгих приглашений: https://t.me/joinchat/AAMBHz3Uyr0tuZ7VaB029g

All That JS
All That JS
417 участник(ов)

JS на русском