理解javascript全局命名空间和闭包

zer*_*ero 31 javascript closures namespaces global-variables

我正在努力提高我对javascript中全局命名空间的理解,我对以下几点感到好奇:

  1. 有一个"GOD"(即父对象)对象,所有对象(因为除了基元之外的所有东西都是对象)要回答,如果是,那么该对象是"窗口"吗?

  2. 为什么在全球范围内拥有变量/函数是个坏主意?

  3. 如果在全局范围内拥有vars /函数真的是个坏主意那么闭包是避免这种情况的最佳方法吗?例:

    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()
    
    Run Code Online (Sandbox Code Playgroud)

Mat*_*att 26

  1. 是否有一个(即父)对象?

    是.从技术上讲,所有这些原语都是其成员的全球对象; 它恰好发生在浏览器中,该window对象全局对象.

    > window.String === String;
    true
    
    Run Code Online (Sandbox Code Playgroud)
  2. 为什么在全球范围内拥有变量/功能是不错的主意?

    因为如果你要添加许多第三方库/脚本,它们都共享相同的全局对象,那么就有可能发生名称冲突.这是一个真实的问题,所有库都$用作别名(jQuery,Prototype等).

  3. 如果在全局范围内拥有vars /函数真的是一个坏主意那么闭包是避免这种情况的最佳方法吗?

    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()
    
    }());
    
    Run Code Online (Sandbox Code Playgroud)

    事实x是儿童功能可以获得并不坏; 你应该自己编写这些函数,所以你应该知道它的存在x.请记住,如果您x在这些子函数中重新声明var,则不会影响xin parent().


Jan*_*nen 5

  1. 是的,在浏览器环境中,"上帝对象"是窗口.它通常被称为全局对象,而不是上帝对象 ;)在非浏览器环境(如nodejs)中,全局对象可能使用除窗口之外的其他名称.

  2. 如果将所有内容都设置为全局变量,则可能会遇到冲突的名称.还有封装的问题- 换句话说,通过将变量放入需要它的范围,你的代码通常会更好.

  3. 是的,这几乎是首选的方法.您还可以使用IIFE

  • 是的,IIFE _could_如果其中的代码在准备好之前尝试访问DOM,则会导致错误.通过将IIFE放在页面底部或使用jQuery的`$(document).ready(function(){...}); (2认同)