JavaScript中的作用域
在功能上,它规定了
-
js中变量和函数的作用范围,解决了标识符重名值被替换覆盖的问题
-
作用域--作用域的存在,使得内部函数能获取所有外部函数数据,外部函数则无法访问内部函数数据,唯一的方式是执行后return的结果
-
闭包--但是有时候又要求外部函数能够调用内部函数的方法或者数据,又不至于破坏原本内访外的规则,于是闭包(或者说return返回的内部函数)由此而生
可以说闭包本质上是在函数内部再构造一个传递数据的函数,通过return这个内部构造的函数(可以访问函数的方法和数据),用外部变量接收,从而即使函数调用后被销毁,因为外部变量还保存对该函数的引用,作用域链能够访问到当时构造的活动对象,这个活动对象就是闭包
-
-
匿名函数的全局性:对于匿名函数而言,因为它没有挂载到任何对象上,所以它最终调用它的是Windows,所以直接指向Windows
-
箭头函数有不会生成执行上下文,而且没有this,没有arguments,没有prototype
因此箭头函数内如果使用this,他会在它所在执行上下文的上一级去查找,也就是定义它的函数所在的执行上下文的上一级,然后继承其中的this
常见疑问
1.对象的属性有作用域吗?比如person.name之类的?
答案是不能这么说!
对象的属性是对象变量这个整体的组成部分,衡量作用域范围始终是在变量这一层次的,就好像作为公民的我们享有选举权,但是我们的鼻子或者耳朵不能单独跑出去进行选举,这个行为本身要求我们达到人这个整体的层次
变量的作用域也是如此,它针对的就是变量这个层次,内部的属性从属于对象这个变量从而不能用作用域来衡量
2.变量作用域有哪些?
全局作用域(Global Scope)
局部作用域(Local Scope)
(lock)
3.全局作用域有哪些?
@1.全局声明的变量(函数外)
实际上就是在window对象上自定义属性
@2.未定义直接赋值的变量(自动声明全局)
就是没写let和var,即使写在函数内照样全局可访问
@3.window对象
因为window对象全局作用可见,所以它的属性/方法也就可以全局访问
@4.全局声明的函数
也就是最外层声明的函数,相当于给window对象声明新方法
4.函数的作用域链 scope chain?

5.作用域的作用是什么?
@1.隔绝变量,防止替换和干扰.
对于变量来说,内层函数可以通过作用域链访问外层变量,但是外层函数却不能访问内层作用域中的变量
如果一定要访问,则只能用return
===如果return返回是简单处理过的数据,外部变量接收后,该函数执行完毕,函数的活动对象和对应的作用域链在堆中直接被销毁.之后如果不再次调用该函数,是无法访问除return 数据以外的 其他任何内部数据的
===如果在欲访问的函数内部再设置一个函数,因为新函数可以通过作用域链访问该函数的所有数据方法,因此只要在新函数中通过传参或者调用该函数数据.
就像制作了一个包裹函数内部数据的小盒子或者小包裹,通过return 把这个函数派发出去,外部变量接收后,即使这个函数执行完毕,作用域链本该销毁,但是由于外部变量中接收到这个新函数的结构,内部有对该函数数据的引用,JS的内存处理机制因此会忽略对其的销毁,保留原有的作用域链,这个派发的函数就是闭包
===注意:必须是 return functionName/函数结构 如果return function() 那么外部变量接收的还是处理后的结果,就不是闭包了
这个作用机制类似出租车窗户贴的窗纸,外面看不见里面有什么,里面却可以对外面的景色一览无余
@2.
6.为什么局部作用域又叫函数作用域?
因为js本质上可以说没有块作用域,{}大括号内能分割变量作用范围的的有且只有函数起效果
其他if(){},for(){}之类的语句中定义的变量全是全局可见的,实际上局部作用域就是函数作用域了
对于这个问题,es6新增的let命名能将声明的变量固定在对应{}块内,js才算拥有了块作用域域
7.[[scope]]是什么
首先我们要明确几点公认的结论
-
js中一切一切都是 对象object ,函数自然也不例外
-
函数作为对象,本质上(甚至可以认为是一种另类的变量),它封装了一些外部无法访问的内部属性,和普通的外部属性(比如原型链)
-
[[scope]]就是一个内置的不可访问属性
-
[[scope]]的功能就是存储作用域链的查找顺序,或者说按查找顺序存储作用域链
-
作用域被抽象成一个个对象,它作为一个数组通过按顺序存储这些对象的引用从而存储作用域链
8.作用域链的实际机制
@1.函数变量的查找是顺着作用链中存储的(作用域对象-内部的属性)查找的
作用域对象按顺序存储在scope中,每一个对象都存储 -- 当前作用域内所有可接触的变量/方法/this指针
最先创建的是 global object,它存储全局作用域内所有变量,方法,和this,以及window本身(全局作用域内能访问到的所有东西)
之后在调用这个函数时,创建它对应的活动对象 active object,它存储该函数作用域内所有能访问到的东西,以及this
-
包括内部属性,内部对象 arguments
-
命名参数
-
this
-
局部变量
9.执行期上下文

浙公网安备 33010602011771号