理解javascript作用域和作用域链

简介: <h1>    <span style="font-size:18px">    </span><span style="font-family:KaiTi_GB2312; font-size:32px">作用域</span></h1> <p><span style="font-family:KaiTi_GB2312"><span style="font-size:24px">   <

        作用域

   作用域就是变量和函数的可访问范围,控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域。

    全局和局部作用域下面用一张图来解释:

    

   单纯的JavaScript作用域还是很好理解的。

   


   作用域链

  全局执行环境是最外层的一个执行环境,在web浏览器中全局执行环境是window对象,因此所有全局变量和函数都是作为window对象的属性和放大创建的。每个函数都有自己的执行环境,当执行流进入一个函数的时候,函数的环境会被推入一个函数栈中,而在函数执行完毕后执行环境出栈并被销毁,保存在其中的所有变量和函数定义随之销毁,控制权返回到之前的执行环境中,全局的执行环境在应用程序退出(浏览器关闭)才会被销毁。

  当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)来保证对执行环境有权访问的变量和函数的有序访问。

    用一张图来解释作用域链的运行:由里向外执行。

    

    当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充,例如定义下面这样一个函数:       

function add(num1,num2) {
    var sum = num1 + num2;
    return sum;
}
在函数add创建时,它的作用域链中会填入一个全局对象,该对象包含了所有全局变量,如下图所示:



函数add的作用域将会在执行时候用到,例如执行如下代码:

function a(sum1,sum2){
            var sum=num1+num2;
            return sum;
        }
        var tatal=a(5,10);
    执行此函数时会创建一个称为“运行期上下文(execution context)”的内部对象,运行期上下文定义了函数执行时的环境。每个运行期上下文都有自己的作用域链,用于标识符解析,当运行期上下文被创建时,而它的作用域链初始化为当前运行函数的[[Scope]]所包含的对象。    

    这些值按照它们出现在函数中的顺序被复制到运行期上下文的作用域链中。它们共同组成了一个新的对象,叫“活动对象(activation object)”,该对象包含了函数的所有局部变量、命名参数、参数集合以及this,然后此对象会被推入作用域链的前端,当运行期上下文被销毁,活动对象也随之销毁。新的作用域链如下图所示:

    

    在函数执行过程中,没遇到一个变量,都会经历一次标识符解析过程以决定从哪里获取和存储数据。该过程从作用域链头部,也就是从活动对象开始搜索,查找同名的标识符,如果找到了就使用这个标识符对应的变量,如果没找到继续搜索作用域链中的下一个对象,如果搜索完所有对象都未找到,则认为该标识符未定义。

   


    总结

  根据上述讲的作用域链的结构可以看出,定义的标识符的越深,那么读写的速度也就越慢,而全局变量总是处于作用域链的最末端,所以当变量解析的时候,查找全局变量是最慢的,所以在编写代码的时候要尽可能少的使用全局变量,尽可能使用局部变量。

相关文章
|
10月前
|
JavaScript 前端开发
js的作用域作用域链
【10月更文挑战第29天】理解JavaScript的作用域和作用域链对于正确理解变量的访问和生命周期、避免变量命名冲突以及编写高质量的JavaScript代码都具有重要意义。在实际开发中,需要合理地利用作用域和作用域链来组织代码结构,提高代码的可读性和可维护性。
|
JavaScript 前端开发
浅谈js作用域
浅谈js作用域
125 0
|
10月前
|
前端开发 JavaScript 数据处理
CSS 变量的作用域和 JavaScript 变量的作用域有什么不同?
【10月更文挑战第28天】CSS变量和JavaScript变量虽然都有各自的作用域概念,但由于它们所属的语言和应用场景不同,其作用域的定义、范围、覆盖规则以及与其他语言特性的交互方式等方面都存在明显的差异。理解这些差异有助于更好地在Web开发中分别运用它们来实现预期的页面效果和功能逻辑。
183 11
|
10月前
|
JavaScript 前端开发
javascript的作用域
【10月更文挑战第19天javascript的作用域
|
10月前
|
JavaScript 前端开发
如何在 JavaScript 中实现块级作用域?
【10月更文挑战第29天】通过使用 `let`、`const` 关键字、立即执行函数表达式以及模块模式等方法,可以在JavaScript中有效地实现块级作用域,更好地控制变量的生命周期和访问权限,提高代码的可维护性和可读性。
|
11月前
|
JavaScript 前端开发
JavaScript 作用域
JavaScript 作用域是指程序中可访问的变量、对象和函数的集合。它分为函数作用域和局部作用域。函数作用域内的变量仅在函数内部可见,而全局作用域的变量在整个网页中均可访问。局部变量在函数执行完毕后会被销毁,而全局变量则在整个脚本生命周期中都存在。未使用 `var` 关键字声明的变量默认为全局变量。
|
JavaScript 前端开发
JavaScript基础知识-作用域(action scope)
关于JavaScript基础知识中作用域的介绍。
146 1
JavaScript基础知识-作用域(action scope)
|
11月前
|
JavaScript 前端开发
js作用域
js作用域
77 1
|
JavaScript 前端开发
js 变量作用域与解构赋值| 22
js 变量作用域与解构赋值| 22
|
缓存 JavaScript 前端开发
了解js基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化
该文章详细讲解了JavaScript中的作用域、闭包概念及其应用场景,并简要分析了函数柯里化的使用。
了解js基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化