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

     2023-02-23     135

关键词:

【中文标题】了解 javascript 全局命名空间和闭包【英文标题】:understanding the javascript global namespace and closures 【发布时间】:2012-04-04 03:53:44 【问题描述】:

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

    是否有一个“GOD”(即父级)对象,所有对象(因为除了基元之外的所有事物都是对象)都可以回答,如果有,该对象是否会是“窗口”?

    李>

    为什么在全局级别拥有变量/函数是个坏主意?

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

    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】:

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

    Yes. 从技术上讲,它是所有这些原语的成员的全局对象;只是碰巧在浏览器中,window 对象全局对象。

    > window.String === String;
    true
    

    为什么在全局级别拥有变量/函数是个坏主意?

    因为如果您要添加大量第 3 方库/脚本,它们都共享同一个全局对象,因此存在名称冲突的可能性。这是所有使用$ 作为别名的库(jQuery、Prototype 等)的现实问题。

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

    x 不应被视为全球性的。它是通过在parent() 函数内声明子函数而形成的闭包的一部分。您的 sn-p 的 问题 部分是 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

【讨论】:

因为它对子函数是全局的,但对全局对象不是,这意味着所有子函数都可以访问它而不会作为参数过去 @codewombat:但您通常只会在另一个函数中声明一个函数因为您需要它来访问该范围内的变量。 既然你有一个自执行的父函数,如果任何代码进行 dom 操作,应该在 body 节点的底部调用它吗? 那么我如何从例如按钮点击中调用 child3?【参考方案2】:

    是的,在浏览器环境中,“上帝对象”是窗口。它通常被称为 global object,而不是 god object ;) 在非浏览器环境(例如 nodejs)中,全局对象可能使用除 window 之外的其他名称。

    如果将所有内容都作为全局变量,则可能会遇到名称冲突。还有encapsulation 的问题 - 换句话说,通过将变量只放入需要它的范围内,您的代码通常会更好。

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

【讨论】:

如果 IIFE 中存在修改 dom 的代码或者在 body 节点的底部调用你的 js 更好(以确保所有 html加载)? 全局对象这个名字很好,但是“上帝对象”听起来很酷:D 是的,如果 IIFE 中的代码在准备好之前尝试访问 DOM,则 IIFE 可能会导致错误。通过将 IIFE 放在页面底部或使用 jQuery 的 $( document ).ready(function() ... );【参考方案3】:

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

    拥有大量全局变量是个坏主意,因为可能存在名称冲突,因此很难检测到错误。一般来说,设计一些命名空间更安全(参见 $ 来自 jQuery 等)并模块化代码。

    小心,parent 是一个潜在存在的窗口字段。这被认为是对象,因此与 2) 中的观察相同。

【讨论】:

那么有没有办法“防错”父函数,因为它是唯一的全局对象? 模块模式例如:adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth【参考方案4】:

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

例如而不是:

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

【讨论】:

JavaScript 作用域和闭包

】JavaScript作用域和闭包【英文标题】:JavaScriptscopeandclosure【发布时间】:2010-10-1211:37:42【问题描述】:我正试图绕过闭包(那里有一个笑话),我遇到了这个:(function()/*docoolstuff*/)();这是如何工作的?将函数放在括号中的目的... 查看详情

函数(命名空间和作用域)

...字,存储在内置命名空间内,启动解释器时加载到内存;全局命名空间:在程序从上到下被执行的工程中依次加载到内存,放置我们设置的所有变量名和函数名;局部内存空间:就是函数内部定义的名字。当调用函数时会产生这... 查看详情

函数的闭包和装饰器

...三种命名空间从大范围到小范围的顺序:内置命名空间、全局命名空间、局部命名空间作用域(包括函数的作用域链):小范围的可以用大范围的但是大范围的不能用小范围的范围从大到小(图)在小范围内,如果要用一个变量... 查看详情

第四节:命名空间

...同时,也有助于组织代码,有更强的可维护性和可读性。JavaScript不提供原生的命名空间支持,但我们可以利用JavaScript的一些语言特性,实现类似的效果。1.闭包简单的说,闭包就是,一个函数可以使用函数之外定义的变量,那... 查看详情

闭包函数

...,我们直接就可以调用的,就叫做内置名称空间 什么是全局变量:除了函数内部定义的内容外,自己写的代码就叫做全局变量 什么是局部变量:在函数内部定义的内容,就叫做局部名称空间12345678910a=1     &... 查看详情

函数/命名空间/闭包(代码片段)

...nbsp;*args>默认值参数>**kwargs命名空间(存储变量)分类1.全局命名空间 →直接在py文件中,函数外声明的变量都属于全局命名空间2.局部命名空间 → 在函数中声明的变量会放在局部命名空间3.内置命名空间 → ... 查看详情

javascript闭包

闭包闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。概念首先了解一个JavaScript变量的作用域,无非就是两种:全局变量和局部变量。Javascript语言的特殊之处,就在于函数内部可以直接... 查看详情

JavaScript:命名空间与作用域

】JavaScript:命名空间与作用域【英文标题】:JavaScript:NamespacevsScope【发布时间】:2018-10-1012:53:45【问题描述】:我对JavaScript中作用域和闭包的概念有相当好的把握。此外,以下网站提供了如何实现JavaScript命名空间的示例:Everyt... 查看详情

函数进阶:闭包装饰器

...在的那一层的)名称空间|,包括局部变量和形参globals:全局变量builtins:内置模块的名字空间 不同变量的作用域不同就是由这个变量所在的命名空间决定的 作用域即 查看详情

js命名空间

命名冲突全局变量会绑定到window上,不同的javascript文件如果使用了相同的全局变量,或者定义了相同名字就的顶层函数,都会造成命名冲突,并且很难被发现。减少冲突的一个办法,把自己的所有变量和函数全部绑定到一个全... 查看详情

命名空间和模块

...命名空间是位于全局命名空间下的一个普通的带有名字的JavaScript对象。这令命名空间十分容易使用。它们可以在多文件中同时使用,并通过--outFile结合在一起。命名空间是帮你组织Web应用不错的方式,你可以把所有依赖都放在HT... 查看详情

预编译作用域链和闭包理解

在理解预编译之前,首先了解一下JS的解析过程:JS引擎在解析脚本的过程分为两个阶段,预编译和执行,首先预编译然后再从上之下一行一行的执行代码。其次,要了解作用域,作用域是一个变量或者函数能够使用的空间,分... 查看详情

day12函数的命名空间,作用域,闭包等

...#print(c)二、函数的命名空间命名空间一共分为三种:  全局命名空间  局部命名空间  内置命名空间*内置命名空间中存放了python解释器为我们提供的名 查看详情

javascript闭包

...作用域的变量的函数 只要存在调用内部函数的可能,JavaScript就需要保留被引用的函数。而且JavaScript运行时需要跟踪引用这个内部函数的所有变量,直到最后一个变量废弃,JavaScript的垃圾收集器才能释放相应的内存空间 ... 查看详情

如何快速的理解javascript闭包?

先看问题1、在js中的作用域是什么?  作用域就是作用范围,作用空间。作用域分为全局作用域和局部作用域。(这个东西大家都明白)  如果把局部作用域比作一个国家,那么全局作用域就是地球,地球上除了那个国家之... 查看详情

作用域(代码片段)

...lobals、locals在提到变量的作用域时,经常提到局部变量和全局变量,之所有称之为局部、全局,就是因为他们的自作用的区域不同,这就是作用域。 3. LEGB规则Python使用LEGB的顺序来查找一个符号对应的对象:locals->enclos... 查看详情

第四节:命名空间

...,也有助于组织代码,有更强的可维护性和可读性。 JavaScript不提供原生的命名空间支持,但我们可以利用JavaScript的一些语言特性,实现类似的效果。 1.闭包  查看详情

javascript从作用域到闭包

...通常来讲这块是全局变量与局部变量的区分。参考引文:JavaScript开发进阶:理解JavaScript作用域和作用域链全局作用域:最外层函数和在最外层函数外面定义的变量拥有全局作用域。  1)最外层函数和在最外层函数外面定义的... 查看详情