JavaScript-做用域、块级做用域、上下文、执行上下文、做用域链

1、做用域

在 JavaScript 中, 做用域(scope,或译有效范围)就是变量和函数的 可访问范围,即做用域控制着变量和函数的 可见性生命周期

2、全局/局部做用域

2.1 全局做用域(Global Scope)

(1)不在任何函数内定义的变量就具备全局做用域。javascript

(2)实际上,JavaScript默认有一个全局对象window,全局做用域的变量实际上被绑定到window的一个属性java

全局做用域

(3)window对象的内置属性都拥有全局做用域,例如 window.name、window.location、window.top 等。web

2.2 局部做用域(Local Scope)

(1)JavaScript的做用域是经过函数来定义的,在一个函数中定义的变量只对这个函数内部可见,称为函数(局部)做用域segmentfault

3、全局/局部变量

变量可以被定义在局部或者全局做用域,这致使运行时 变量的访问来自不一样的做用域

3.1 全局变量

(1)在函数定义外声明的变量是全局变量。 浏览器

(2)全局变量有 全局做用域,它的值可在整个程序中访问和修改函数

(3)若是变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量。this

3.2 局部变量

(1)在函数定义内声明的变量是局部变量。spa

(2)由于局部变量只做用于函数内,因此不一样的函数可使用相同名称的变量code

(3)每当执行函数时,都会建立销毁该变量,且没法经过函数以外的任何代码访问该变量。对象

(4)函数外没法访问函数内的变量,函数内却能够访问函数外的变量。

4、全局变量

一、在 函数定义外声明的变量是全局变量;全局变量有全局做用域,它的 值可在整个程序中访问和修改

全局变量

二、若是 变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量。

全局变量

5、局部变量

一、由于局部变量只做用于函数内,因此 不一样的函数可使用相同名称的变量

局部变量

二、每当执行函数时,都会 建立销毁该变量,且没法经过函数以外的任何代码访问该变量。

局部变量

三、 函数外没法访问函数内的变量,函数内却能够访问函数外的变量。

局部变量

6、块级做用域

6.1 概念

块级做用域指在If语句,switch语句,循环语句等语句块中定义变量,这意味着变量 不能在语句块以外被访问

6.2 var 不支持块级做用域

(1)在If等语句块中,定义的变量从属于该块所在的做用域,和函数不一样,他们不会建立新的做用域。

var

6.3 let和const

(1)为了解决块级做用域,ES6引入了 letconst 关键字,能够声明一个块级做用域的变量

let和const

(2)全局做用域的生存周期与上述应用相同。局部做用域只在该函数调用执行期间存在。

7、上下文 vs 做用域

(1)首先须要说明的是上下文和做用域是不一样的概念

(2)每一个函数调用都有与之相关的做用域和上下文。从根本上说,做用域是基于函数,而上下文是基于对象

(3)做用域是和每次函数调用时变量的访问有关,而且每次调用都是独立的。上下文老是关键字 this 的值,是调用当前可执行代码的对象的引用。

8、“this” 上下文

(1)上下文一般是取决于一个函数如何被调用。当函数做为对象的方法被调用时,this 指向调用方法的对象

上下文

(2)当调用一个函数时,经过 new 操做符建立一个对象的实例,当以这种方式调用时,this 指向新建立的实例

上下文

(3)当调用一个未绑定函数,this 默认指向全局上下文或者浏览器中的window对象。然而若是函数在严格模式下被执行(“use strict”),this 默认指向 undefined

9、执行上下文

(1)当函数执行时,会建立一个称为执行上下文的内部对象(可理解为做用域,不是前面讨论的上下文)。一个执行上下文定义了一个函数执行时的环境

(2)函数每次执行时对应的执行上下文都是独一无二的,因此屡次调用一个函数会致使建立多个执行上下文。

(3)当javascript代码文件被浏览器载入后,默认最早进入的是一个全局的执行上下文。当在全局上下文中调用执行一个函数时,程序流就进入该被调用函数内,此时引擎就会为该函数建立一个新的执行上下文,而且将其压入到执行栈顶部(做用域链)。浏览器老是执行位于执行栈顶部的当前执行上下文,一旦执行完毕,该执行上下文就会从执行栈顶部弹出,而且控制权将进入其下的执行上下文。这样,执行栈中的执行上下文就会被依次执行而且弹出,直到回到全局的执行上下文。

10、做用域链

(1)在JavaScript中,函数也是对象,对象中有些属性咱们能够访问,但有些不能够(访问),这些属性仅供JavaScript引擎存取,[[scope]]就是其中一个。

(2)[[scope]]指的就是咱们所说的做用域,其中存储了执行上下文的集合。

(3)[[scope]]中所存储的执行上下文对象的集合,这个集合呈链式连接,咱们把这种链式连接叫作做用域链。

10.1 示例

执行期上下文

(1)运行示例代码将会致使嵌套的函数被从上倒下执行,一直到 fourth 函数,此时做用域链从上到下为: fourth, third, second, first, global。

(2)fourth 函数可以访问全局变量和任何定义在first,second和third函数中的变量(和访问本身的变量同样)。

(3)一旦fourth函数执行完成,其就会从做用域链顶部移除,而且执行权会返回到third函数。这个过程一直持续到全部代码完成执行。

10.2 攀爬做用域链

(1)当不一样执行上下文之间存在 变量命名冲突,能够经过攀爬做用域链解决(从顶部到底部)。这也就是说
在最内层函数(执行栈顶部的执行上下文)中,具备相同变量名称的变量将具备较高优先级。

(2)简单的说,每次试图访问函数执行上下文中的变量时,查找进程老是从本身的变量对象开始。若是在本身的变量对象中没发现要查找的变量,继续搜索做用域链。他将攀爬做用域链检查每个执行上下文的变量对象,去寻找和变量名称匹配的值

阅读更多

个人博客即将搬运同步至腾讯云+社区,邀请你们一同入驻:https://cloud.tencent.com/dev...

相关文章
相关标签/搜索