基础巩固-作用域与作用域链

123 阅读2分钟

作用域与作用域链

作用域

  1. 理解

    • 即一块”地盘“,一个代码段所在的区域
    • 它时静态的(相对于上下文对象),在编写代码时确定
  2. 分类

    • 全局作用域

    • 函数作用域(局部作用域)

    • 没有块作用域(ES6)

      if(true){
      var c = 1
      }
      console.log(c)// 1  大括号并不影响c,在外部能看见变量
      
  3. 作用

    • 隔离变量,不同作用域下同名变量不会冲突
  4. 总结

    • n+1原则,n为定义函数个数,1为全局作用域,得出总作用域个数

作用域与执行上下文

  1. 区别1
    • 全局作用域之外,每个函数都会创建自己的作用域(n+1),作用域在函数定义时就已经确定了。而不是在函数调用时
    • 全局执行上下文环境是在全局作用域确定之后,JS代码马上执行之前创建
    • 函数执行上下文是在调用函数时,函数代码准备执行之前创建
  2. 区别2
    • 作用域是静态的,只要函数定义好了就一直存在,且不再变化
    • 执行上下文环境是动态的,调用函数时创建,函数调用结束时执行上下文环境会被自动释放
  3. 联系
    • 执行上下文环境(对象)是从属于所在的作用域
    • 全局执行上下文环境==>全局作用域
    • 函数执行上下文环境==>对应的函数使用域

作用域链

类似于原型链,嵌套作用域,由内向外逐层查询变量,直到全局作用域,若还是未找到则报错 ,即外部不能看到内部,但内部可以往外部找

【注】a.b,先在作用域链上找a,找不到报错,.b在原型链上查找,找不到返回undefined。window.a,找不到a返undefined,而单独a找不到报错!

面试题

var x = 10
function fn() {
    console.log(x)
}
function show(f) {
    var x = 20
    f()
}
show(fn) //10  函数作用域在定义时就确定了,跟调用没有关系,不会改变

var fn = function () {
    console.log(fn)
}
fn()//输出这个函数

var obj = {
    fn2:function () {
        console.log(fn2) //这里的fn2是个变量,只是和obj的属性fn2一样具有迷惑性但并不是同一个
        //console.log(this.fn2)   就能输出函数
    }
}
obj.fn2()//报错fn2未找到 现在函数作用域找fn2未找到,再到全局找也没找到