发表于: 2017-07-15 23:08:03
0 798
小课堂:JS中作用域以及作用域链
一.背景介绍
作用域与作用域链是JS中非常重要的概念之一
学习作用域与作用域链对于深入了解JS的运行机制是一个很大的帮助。
二.知识剖析
首先,我们要知道执行环境和作用域是两个完全不同的概念
执行环境(EC)或执行上下文,是JS中极为重要的一个概念
EC的组成:变量对象(VO):变量对象即包含变量的对象,除了我们无法访问它外,和普通对象没什么区别。
[[scope]]属性:作用域即变量对象,作用域链是一个由变量对象组成的带头结点的单向链表,其主要作用就是用来进行变量查找。而[[Scope]]属性是一个指向这个链表头节点的指针。
this:指向一个环境对象,注意是一个对象,而且是一个普通对象,而不是一个执行环境。
当JavaScript代码执行的时候,会进入不同的执行上下文,这些执行上下文会构成了一个执行上下文栈
在web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。代码载入浏览器时,全局执行环境被创建(当我们关闭网页或者浏览器时全局执行环境才被销毁)。
每个函数都有自己的执行环境,因此局部执行环境为函数对象。当函数被调用时函数的局部环境被创建(函数内的代码执行完毕后,该环境被销毁,同时保存在其中的所有变量和函数定义也随之被销毁)。
代码在环境中执行,会创建变量对象的一个作用域链。
javascript函数的执行用到了作用域链,这个作用域链是函数定义的时候创建的,当定义一个函数时,它实际保存一个作用域链。当调用这个函数时,它创建一个新的对象来存储它的局部变量,并将这个对象添加至保存的作用域链。作用域链的前端始终都是当前执行的代码所在环境的变量对象。作用域链的末端始终都是全局执行环境的变量对象。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有权访问
三.常见问题
几种不同作用域
四.解决方案
函数作用域:
六.拓展思考
从作用域链的结构可以看出,在运行期上下文的作用域链中,标识符所在的位置越深,读写速度就会越慢。如上图所示,因为全局变量总是存在于运行期上下文作用域链的最末端,因此在标识符解析的时候,查找全局变量是最慢的。所以,在编写代码的时候应尽量少使用全局变量,尽可能使用局部变量。一个好的经验法则是:如果一个跨作用域的对象被引用了一次以上,则先把它存储到局部变量里再使用。
栗子
评论