bunny笔记|javascript闭包的三种方式,以及闭包的优

2022-05-10  本文已影响0人  一只小小小bunny

基本函数的表达方式

        function  fun(){
            let a=10;
            return a;
        }
        let res=fun()
        console.log(res);//10

只能得到一个返回值的结果并不能去对函数里的变量a进行任何操作(访问变量)

image.png

闭包

(1)闭包的第一种方式,return返回一个匿名函数,并return返回值

按理说呢,a是函数内部的变量,我们是不能在外部访问的,但是这里匿名函数相当于延续的变量a的生命周期,并且当我们多次运行res变量的时候,我们得到函数执行累加的返回结果

image.png image.png

闭包 : 闭包就是通过某种方式获取(函数)内部的变量,然后暴露到函数的外部,并且在将来的某个节点还可以继续操作这个变量。
优点:可以防止污染我们的全局作用域
缺点:会导致一个内存库泄露的问题

(2)闭包的第二种方式值 希望用到函数内部的变量,但是又不想return,应该怎么办?

加入函数外部有一个变量对象 就需要给这个变量临时添加方法,一个get()方法 并且对应一个set()方法,在get()方法里获取变量(直接return返回结果),在到set()的方法里用传参再接收参数就可以了。
外部调用就不需要返回值了,直接调用函数就可以访问到函数内部的变量了,如:

        let obj = {}
        function fun() {
            var a = 10;
            obj.get = function () {
                return a;
            }
            obj.set = function (v) {
                a = v;
            }
        }
        fun();//调用
        console.log(obj.get());//10
image.png

当我们调用obj.get()时并不知道get里面的有a的变量,再看obj={}的代码其实是也只是个空的对象,但确实obj.get()能拿到值为10,也就是说函数内部处理好了get()和set()的方法,所以说,闭包会产生一种鬼魅的幽灵变量,你感觉不到它的存在,但是它确实存在着

(3)闭包的第三种存在方式,(举例是vue框架中的用法)
        var data = {
            name: '',
            iphone: ''
        }
        //属性劫持
        for (let key in data) {
          console.log(key);
        }

key的返回结果


image.png

溢出问题

        var data = {
            name: '',
            iphone: ''
        }
        //属性劫持
        for (let key in data) {
            // console.log(key);//name iphone
            //解决死循环的问题,临时添加一个变量接收data[key],这个变量在函数里只会执行一次,所以不会死循环
            let value = data[key];
            Object.defineProperty(data, key, {
                get() {
                    // return data[key];
                },
                set(v) {
                     console.log('对应的DOM更新', "----");//死循环,内存溢出
                     data[key] = v;
                    console.log('对应的DOM更新');
                }
            })
        }
image.png
        var data = {
            name: '',
            iphone: ''
        }

        //属性劫持
        for (let key in data) {
            // console.log(key);//name iphone
            //解决死循环的问题,临时添加一个变量接收data[key],这个变量在函数里只会执行一次,所以不会死循环
            let value = data[key];
            Object.defineProperty(data, key, {
                get() {
                    // return data[key];
                    return value;
                },
                set(v) {
                    //   (1) 
                    // console.log('对应的DOM更新', "----");//死循环,内存溢出
                    // data[key] = v;

                    value = v;

                    console.log('对应的DOM更新');
                }
            })
        }

image.png
上一篇下一篇

猜你喜欢

热点阅读