作用域与作用域链

原理

  1. 函数在执行的过程中,先从自己内部找变量
  2. 如果找不到,再从创建当前函数所在的作用域去找, 以此往上
  3. 注意找的是变量的当前的状态

举例

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() //输出多少
  • 首先进入fn1作用域,发现返回值为fn3,在当前作用域即fn1下查找fn3
  • 进入fn3,发现调用了fn2,在当前作用域即fn3下查找fn2,未找到,返回上一级找到fn2
  • 进入fn2,执行console.log(a),未找到a,返回上一级找到定义了变量a为2,输出2
var a = 1
function fn1(){
  function fn3(){
    var a = 4
    fn2()
  }
  var a = 2
  return fn3
}
function fn2(){
  console.log(a)
}
var fn = fn1()
fn() //输出多少
  • 首先进入fn1作用域,发现返回值为fn3,在当前作用域即fn1下查找fn3
  • 进入fn3,发现调用了fn2,在当前作用域即fn3下查找fn2,未找到,返回上一级找到fn2
  • 进入fn2,执行console.log(a),未找到a,返回上一级找到定义了变量a为1,输出1
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() //输出多少
  • 首先进入fn1作用域,发现返回值为fn3,在当前作用域即fn1下查找fn3
  • 进入fn3,发现调用了fn2,在当前作用域即fn3下查找fn2
  • 进入fn2,执行console.log(a),未找到a,返回上一级而此时就涉及到预执行的操作,JS会默认运行操作是从上而下,首先找到的是var a,而此时的a的值只被声明,未被赋值,为undefined,所以最终输出为undefined。

你可能感兴趣的:(作用域与作用域链)