什么是作用域、作用域链?

说完了闭包,再来聊聊作用域和作用域链吧。

什么是作用域?

简单来说,在一定的空间里可以对数据进行读写操作,这个空间就是数据的作用域。
JS中最常见的就是变量的作用域。
变量的作用域分为两种:全局变量和局部变量。
1、全局作用域: 最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的;
2、局部作用域: 局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部。

顺便提一下,JS是没有块级作用域的。

这意味着在块语句中定义的变量,实际是在函数中创建的,而不是语句中。
函数可以模仿块级作用域。

(function(){
//这里是块级作用域
})();

大致了解了什么是作用域,就继续来说什么是作用域链。

什么是是作用域链?

当代码在一个环境中执行时,会创建变量对象的一个作用域链。
由子级作用域返回父级作用域中寻找变量,就叫做作用域链。

作用域链中的下一个变量对象来自包含环境,也叫外部环境。而再下一个变量对象则来自下一个包含环境,一直延续到全局执行环境。全局执行环境的变量对象始终都是作用域链中的最后一个对象。
作用域链前端始终都是当前执行的代码所在环境的变量对象,如果环境是函数,则将其活动对象作为变量对象。

作用域链的用途是什么呢?

是保证执行环境有权访问的所有变量和函数的有序访问。

如何延长作用域链?

既然是个链,能不能延长呢?
答案当然是可以。
延长作用域链:
执行环境的类型只有两种,全局和局部(函数)。但是有些语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。
具体来说就是执行这两个语句时,作用域链都会得到加强。
1、try - catch 语句的catch块;会创建一个新的变量对象,包含的是被抛出的错误对象的声明。
2、with 语句。with 语句会将指定的对象添加到作用域链中。

你可能感兴趣的:(什么是作用域、作用域链?)