【前端面试题】闭包——笔记2

69 阅读3分钟

一、作用域

(1)作用域是指程序源代码中定义的范围

(2)作用域规定了如何设置变量,也就是确定当前执行代码对变量的访问权限

(3)JavaScript采用词法作用域(静态作用域):在函数定义的时候就已经确定。

    var a=1;
    function getA(){
        console.log(a);
    }
    function getA2(){
        var a = 2;
        getA();//1
    }
    getA()

二、变量对象

变量对象是当前代码片段中,所有的变量(变量 函数 形参 arguments)组成的一个对象。

变量对象是在执行上下文中被激活的,只有变量对象被激活,在这段代码中才能使用所有的变量。

变量对象分为全局变量对象和局部变量对象。

全局简称为Variable Object VO 函数由于执行才被激活称为Active Object AO

三、作用域链

1、在JavaScript中,函数存在一个隐式属性scopes,scopes用来保存当前函数的执行上下文环境,由于在数据结构上是链式的,因此也被称作是作用域链。可以把它理解为一个数组(一系列AO对象所组成的一个链式结构/变量对象的集合/变量对象组成的链式结构)

    function f() {
    }
    // 打印f对象的内部结构
    console.dir(f)

image.png

 function f() {
        // 打印f对象的内部结构
        console.dir(f)
    }
    f()

image.png

scopes属性在函数声明时产生的,在函数调用时更新(在函数被调用时,将该函数AO对象压入到scopes中) 2、作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的。

 var global
   function a() {
    function b(){
        var bb=456
    }
    b()
   }
   a()

(1)a函数的生成

image.png

(2)a的调用

image.png

(3)b函数生成【a函数调用导致b函数的生成】

image.png

(4)b函数的调用

image.png

函数执行完就进行销毁,就是b函数的调用的毁掉图中的线【作用域链断开的过程】(垃圾回收机制)

四、闭包

(1)闭包:是一个函数访问另一个函数内部变量的函数,使得函数不被垃圾回收机制回收,但是闭包过多会导致内存泄漏。 (2)好处:使一个变量长期驻扎到内存当中;避免全局变量的污染;私有成员的存在;安全性的提升。 (3)father和child指向同一个作用域链,当father运行完被垃圾回收机制回收,当child被赋值给全局变量a使a可以访问到father里的变量。

    function father() {
        var f = "我是father"
        function child() {
            console.log(f)
        }
        return child
    }
    var a = father()
    a()//我是father

(4)实战应用

在函数里return函数多半是闭包

    function f(){
        return ff(){  
        }
    }

第一种:回调函数

第二种:防抖节流

第三种:定时器的传参

第四种:手写js的特性 bind()

第五种:判断数据类型