作用域链

作用域链

当一个块或函数嵌套在另一个块或函数中时,就发生了作用域的嵌套。因此,在当前作用域中无法搜索到某个变量时,引擎就会在外层嵌套的作用域中继续搜索,直到搜索到该变量,或抵达最外层的作用域(也就是全局作用域)为止。这样一条有序的列表,称为作用域链,作用域链的最前端一定是当前作用域,最末端是全局作用域。

var b = 0;
console.log("全局作用域下,b="+b);//"全局作用域下,b=0"
function test(){
  console.log(b);  // b=0
  function innerTest(){
   var b = 2;
   console.log("当前作用域下,b="+b);//"当前作用域下,b=2"
  }
  return innerTest();
}
test();
  • 如上代码所示,第一次打印变量 b 是在全局作用域下,b = 0;
  • 第二次打印时,变量 b处于函数 test()作用域内,由于在test() 作用域内未对变量 b 进行定义,所以返回上一层调用全局作用域内定义的变量 b;
  • 第三次打印时,变量 b 处于 test 下的 innerTest() 内,由于在 innerTest() 内重新定义了 b (局部变量),所以 b = 2。

简单点来说,作用域链就是一条变量对象的链。

{
    Scope: 
    [
        { //当前作用域
            变量,
            函数名
        }, 
        { //上一层作用域
            变量,
            函数名
        }
        ... 
        { //全局作用域
            变量,
            函数名
        }
    ]
}

为了加深理解,我们来看几道题目

var a = 1
function fn1(){
  function fn2(){
    console.log(a)
  }
  function fn3(){
    var a = 4
    fn2()
  }
  var a = 2
  return fn3
}
var fn = fn1()
fn() //输出多少?

解析: 2,fn1() 返回的是 fn3 函数,被赋值给了 fn 。那么当执行 fn() 时 ,也就是执行 fn3()。在 fn3() 内 执行了 fn2() 函数,在 fn2() 中又打印了 a,但此时在 fn2() 未对变量 a 进行定义,所以需要返回到创建 fn2() 函数的作用域内寻找定义好的 a 变量,可以发现在 fn1() 内 var a = 2,所以输出 a = 2。(如若此层作用域未定义变量 a ,那就接着往上一层作用域寻找。)

var a = 1
function fn1(){

  function fn3(){
    function fn2(){
      console.log(a)
    }
    var a
    fn2()
    a = 4
  }
  var a = 2
  return fn3
}
var fn = fn1()
fn() //输出多少

解析: undefined,fn1() 返回的是 fn3 函数,被赋值给了fn。执行 fn() 也就是执行 fn3()。当执行fn3() 时,我们可以发现在 fn3() 循环体内,只是先声明了 a ,只有执行 fn2() 之后才对 a 进行赋值。那么在执行 fn2() 输出 a 时,只能输出 undefined 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值