作用域,就是一个代码块所在的区域,它是静态的,在编写代码时就已经确定了
不同于执行上下文,(执行上下文是动态的,执行创建)
举例:
执行上下文时 建房子 时的 打地基
作用域 是 建房子 时的 区域
作用:用来决定代码执行的范围,变量所属的范围
联系:
上下文环境(对象) 是从属于所在的 作用域全局上下文环境 ==> 全局作用域函数上下文 ==> 对应的函数作用域作用域链:
作用域链 ,是一个数组结构该结构保存的是 一个个的变量对象作用域 是人们虚拟出来的,实际上,作用域根本不存在
但是,作用域链是真实存在的
作用:有句话说:找属性去找原型链,找变量去找作用域链
流程:
先在自身的作用域的变量对象找没有,沿着作用域链,去上一个作用域的变量对象找看以下代码,我通过断点的方式,来解释这个概念
/* 断点一 */ var a = 2; function fn1() { /* 断点二 */ var b = 3; function fn2() { /* 断点三 */ var c = 4; console.log(c) // 4 console.log(b) // 3 console.log(a) // 2 console.log(d) // 报错 } fn2() } fn1()首先,通过 debug调试,将代码执行带断点一的地方停下
那么:
首先创建全局作用域 和 全局变量对象globalglobal收集了函数fn1,为他创建局部作用域这时,在函数fn1建立一个作用域链,里面保存一个变量对象global然后,执行到断点二的地方停下:
首先,在fn1的作用域内,创建一个变量对象Local: fn1Local:fn1,收集了函数fn2,为他创建局部作用域这时,在函数fn2建立一个作用域链,将Local:fn1插入到链的头部那么,这时作用域链,就有[ Local:fn1, global ]那么,这个由 [[Scopes]]属性存储的变量对象,就是作用域链
答案:10
解析:
首先,创建全局作用域和变量对象globalglobal收集函数fn、show,创建局部作用域,两个的作用域链都只有一个global对象执行代码,fn, show创建自身的作用域链,[[scopes]] = [global]执行到fn()时,由于要找变量,那么先找自身的作用域的变量对象Local:fnfn自身没有x变量,找作用域链的上一个变量对象globalglobal的x变量为 10输出 10答案:
第一道:undefined、 f() {console.log(fn)}
第二道: 报错:fn2 is not function