Java教程

JavaScript中的闭包问题

本文主要是介绍JavaScript中的闭包问题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

首先,我们需要明白什么是闭包:

闭包:一个可以用自己拥有独立环境与变量的表达式,通常是函数,因为在ES6里已经引入了块级作用域的概念

其次,再来了解一些闭包的优缺点及其特性:

闭包有三个特性:
        函数嵌套函数。
        函数内部可以引用外部的参数和变量。
        参数和变量不会被垃圾回收机制回收。

闭包的好处:
        希望一个变量长期存储在内存中。
        避免全局变量的污染。
        私有成员的存在。

闭包的缺点:
        常驻内存,增加内存使用量。
        使用不当会很容易造成内存泄露。

最后,我们来了解一下闭包的应用场景:

         //作为返回值
        function fn() {
            let num = 10;
            return function() {
                return num;
            }
        }
        let fnc = fn();
        console.log(fnc());

 

//函数赋值
var fn1;

function fn() {
   let num = 20;
   fn1 = function() {
   return num;
    }
 }
fn(); //赋值
console.log(fn1()); //调用

 

         //函数参数
        function fn() {
            let num = 20;
            return function callback() {
                return num;
            }
        }
        //执行函数,将返回值(callback函数)赋值给fn1
        let fn1 = fn();

        function fn2(f) {
            //将函数作为参数传入
            console.log(f()); //执行函数,并输出
        }

        fn2(fn1);

 

         //IIFE(自执行函数)
        (
            function() {
                let num = 30;
                var fn = function() {
                        return num;
                    }
                    //直接在自执行函数里面调用fn2,将fn1作为参数传入
                fn1(fn);
            }
        )()

        function fn1(f) {
            //将函数作为参数传入
            console.log(f()); //执行函数,并输出
        }

 

        //循环赋值
        //每秒执行1次,分别输出1-10
        for (let i = 1; i <= 10; i++) {
            (function(j) {
                //j来接收
                setTimeout(function() {
                    console.log(j);
                }, j * 1000);
            })(i) //i作为实参传入
        }

 

 

        //迭代器(执行一次函数往下取一个值)
        let arr = ['aa', 'bb', 'cc'];

        function incre(arr) {
            let i = 0;
            return function() {
                //这个函数每次被执行都返回数组arr中 i下标对应的元素
                return arr[i++] || '数组值已经遍历完';
            }
        }
        let next = incre(arr);
        console.log(next()); //aa
        console.log(next()); //bb
        console.log(next()); //cc
        console.log(next()); //数组值已经遍历完

 

 

        //缓存
        //比如求和操作,如果没有缓存,每次调用都要重复计算,采用缓存已经执行过的去查找,查找到了就直接返回,不需要重新计算

        var fn = (function() {
            var cache = {}; //缓存对象
            var calc = function(arr) { //计算函数
                var sum = 0;
                //求和
                for (var i = 0; i < arr.length; i++) {
                    sum += arr[i];
                }
                return sum;
            }

            return function() {
                var args = Array.prototype.slice.call(arguments, 0); //arguments转换成数组
                var key = args.join(","); //将args用逗号连接成字符串
                var result, tSum = cache[key];
                if (tSum) { //如果缓存有   
                    console.log('从缓存中取:', cache) //打印方便查看
                    result = tSum;
                } else {
                    //重新计算,并存入缓存同时赋值给result
                    result = cache[key] = calc(args);
                    console.log('存入缓存:', cache) //打印方便查看
                }
                return result;
            }
        })();
        fn(1, 2, 3, 4, 5);
        fn(1, 2, 3, 4, 5);
        fn(1, 2, 3, 4, 5, 6);
        fn(1, 2, 3, 4, 5, 8);
        fn(1, 2, 3, 4, 5, 6);

 

//防抖
function debounce(callback, time) {
            var timer;
            return function() {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    callback()
                }, time)
            }
        }

 

这篇关于JavaScript中的闭包问题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!