понимание глобального пространства имен javascript и замыканий - PullRequest
31 голосов
/ 19 марта 2012

Я пытаюсь улучшить мое понимание глобального пространства имен в javascript, и мне любопытно несколько вещей:

  1. существует ли объект «БОГ» (то есть родительский), на который все объекты (поскольку все вещи, кроме примитивов, являются объектами) отвечают, и если это так, будет ли этот объект «окном»?

  2. почему плохая идея иметь переменные / функции на глобальном уровне?

  3. если действительно плохая идея иметь переменные / функции в глобальной области видимости, тогда закрытие будет лучшим способом избежать этого? Пример:

    function parent(){
        var x = 'some value';//this var would be considered global to all children functions but not in the true global namespace
        function child1(){
            x.someMethod()
        } 
        function child2(){
            x*something;
        }
        function child3(){
            x+=something;
            child2()
            child1()
        }
        child3()
    }
    parent()
    

Ответы [ 4 ]

26 голосов
/ 19 марта 2012
  1. Есть ли бог (то есть родительский) объект?

    Да. С технической точки зрения этоглобальный объект, членами которого являются все эти примитивы;просто случается, что в браузере window объект является глобальным объектом.

    > window.String === String;
    true
    
  2. Почему плохая идея иметь переменные/ функционирует на глобальном уровне?

    Потому что, если вы добавляете много сторонних библиотек / скриптов, они все совместно используют один и тот же глобальный объект, есть вероятность конфликта имен.Это реальная проблема со всеми библиотеками, которые используют $ в качестве псевдонима (jQuery, Prototype и другие).

  3. Если это действительно плохая идея иметьТогда vars / functions в глобальной области видимости - лучший способ избежать этого?

    x не следует считать глобальным.Это часть замыкания, образованного объявлением дочерних функций внутри функции parent(). проблема в вашем фрагменте состоит в том, что parent() является глобальным;что произойдет, если какой-то другой код будет повторно объявлен parent()?Это было бы лучше:

    (function () {
    
    function parent(){
        var x = 'some value';
        function child1(){
            x.someMethod()
        } 
        function child2(){
            x*something;
        }
        function child3(){
            x+=something;
            child2()
            child1()
        }
        child3()
    }
    parent()
    
    }());
    

    Тот факт, что x доступен в дочерних функциях, неплох;Вы должны были написать эти функции самостоятельно, поэтому вы должны знать о существовании x.Имейте в виду, что если вы повторно объявите x в этих дочерних функциях с помощью var, это не повлияет на x в parent().

5 голосов
/ 19 марта 2012
  1. Да, в среде браузера «объект бога» - это окно. Обычно он называется глобальный объект , а не божественный объект ;);) В средах без браузера, таких как nodejs, глобальный объект может использовать другое имя, отличное от окна.

  2. Если вы поставите все как глобальные, вы рискуете столкнуться со встречными именами. Существует также вопрос инкапсуляции - другими словами, если поместить переменные только в ту область, где это необходимо, ваш код, как правило, лучше.

  3. Да, это довольно предпочтительный подход. Вы также можете использовать IIFE

3 голосов
/ 24 апреля 2016

Если вам НУЖНО поместить переменные в глобальное пространство имен, и вы, вероятно, в какой-то момент создадите одну переменную объекта и добавите к ней другие переменные в качестве свойств или методов. Дайте объекту имя, которое вряд ли будет использоваться кем-либо еще (по общему признанию, это - то, где проблемы столкновения возникают, но это может быть смягчено осторожным, стандартизированным наименованием).

например. Вместо:

var thing1 = 'table';
var anotherthing = 'chair';
var mypet = 'dog';
var count = 4;
var show_something: function( _txt ) { return _txt.trim(); };

Сделайте это:

var cmjaimet_obj = {
  thing1: 'table',
  anotherthing: 'chair',
  mypet: 'dog',
  count: 4,
  show_something: function( _txt ) { return _txt.trim(); }
};

Затем позже назовите их как свойства:

например. Вместо:

count += 2;
anotherthing = 'sofa';
console.log( show_something( 'Thing: ' + anotherthing ) );

Сделайте это:

cmjaimet_obj.count += 2;
cmjaimet_obj.anotherthing = 'sofa';
console.log( cmjaimet_obj.show_something( 'Thing: ' + cmjaimet_obj.anotherthing ) );
3 голосов
/ 19 марта 2012
  1. Насколько я знаю, я бы сказал, да, окно является родительским объектом.Однако внутри Iframe у вас есть собственный оконный объект, отличный от окружающего окна, доступ к которому вы можете получить через window.parent

  2. Плохо иметь много глобальных переменных из-за потенциальныхстолкновение имен и, следовательно, трудно обнаружить ошибки.В общем, безопаснее спроектировать некоторое пространство имен (см. $ из jQuery и т. Д.) И модульный код.

  3. Будьте осторожны, parent является потенциальным существующим полем окна.Эта взятая функция, функция является объектом, поэтому здесь применимо то же наблюдение, что и в пункте 2).

...