了解javascript全局名称空间和闭包



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

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

  2. 为什么在全局级别上拥有vars/函数是个坏主意?

  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()
    
  1. 是否存在(即父对象)对象?

    是的。更严格地说,所有这些基元都是全局对象的成员;恰好在浏览器中,window对象是全局对象

    > window.String === String;
    true
    
  2. 为什么在全局级别上拥有vars/函数是个坏主意?

    因为如果你添加了很多第三方库/脚本,它们都共享同一个全局对象,那么就有可能发生名称冲突。这是所有使用$作为别名的库(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()
    }());
    

    x在子函数中是可访问的,这一事实还不错;您应该自己编写这些函数,因此您应该意识到x的存在。请记住,如果使用var在这些子函数中重新声明x,则不会影响parent()中的x

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

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

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

  1. 据我所知,我会说是的,window是父对象。然而,在Iframe中,您有自己的窗口对象,与您可以通过window.parent 访问的周围窗口不同

  2. 有很多全局var是个坏主意,因为可能会发生名称冲突,因此很难检测到错误。通常,设计一些名称空间更安全(请参阅jQuery的$等)并模块化代码。

  3. 注意,parent是一个潜在的窗口领域。这取了一个物体,函数是物体,所以与2)中的观察结果相同。

如果需要将变量放入全局命名空间,并且您可能会在某个时候创建一个对象变量,并将其他变量作为属性或方法添加到其中。为对象指定一个其他人不太可能使用的名称(诚然,这是出现冲突问题的地方,但可以通过谨慎、标准化的命名来缓解)。

例如代替:

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 ) );

相关内容

  • 没有找到相关文章

最新更新