🍉JavaScript进阶——闭包与递归的那些事儿

简介: 🍉JavaScript进阶——闭包与递归的那些事儿

1.闭包


1.1 变量作用域


  1. 函数内部可以使用全局变量。
  2. 函数外部不可以使用局部变量。
  3. 当函数执行完毕,本作用域内的局部变量会销毁


1.2 什么是闭包


闭包指有权访问另一个函数作用域中变量的函数。-----红宝书

简单理解就是,一个作用域可以访问另外一个函数内部的局部变量。 闭包就是一个典型的闭包函数。


<script>
        function fn() {
            var num = 10;
            function fun() {
                console.log(num);
            }
            fun();
        }
        fn();
    </script>
复制代码


这就是一个闭包,我们可以利用Chorme调试工具来查看是否产生闭包。


b01338b62bbe4d2eac711bbc263b9f04_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

ab19723bc6a649ceb54372e9e404ae31_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

a29d0f6b6bd0484995e6a8ad18bc0457_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

6babe12729f94613abaeece7ec3196a3_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


看,出现了closure,由此可见fn()就是一个闭包


1.3  闭包的主要作用


延伸了变量的作用范围


1.4 闭包的案例


循环注册点击事件


用立即执行函数解决,立即执行函数也称为小闭包


<body>
    <ul>
        <li>苹果</li>
        <li>梨子</li>
        <li>草莓</li>
        <li>西瓜</li>
        <li>樱桃</li>
    </ul>
    <script>
        var lis = document.querySelectorAll("li")
        for (var i = 0; i < lis.length; i++) {
            (function (i) {
                lis[i].onclick = function () {
                    console.log(i);
                }
            })(i)
        }
    </script>
</body>
复制代码


循环中的setTimeout()


<body>
    <ul>
        <li>苹果</li>
        <li>梨子</li>
        <li>草莓</li>
        <li>西瓜</li>
        <li>樱桃</li>
    </ul>
    <script>
        // 闭包应用——3秒钟之后,打印所有li元素的内容
        var lis = document.querySelectorAll("li")
        for (var i = 0; i < lis.length; i++) {
            (function (i) {
                setTimeout(() => {
                    console.log(lis[i].innerHTML);
                }, 3000);
            })(i)
        }
    </script>
</body>
复制代码


计算打车价格


要求:


  • 起步价13(3公里内),之后每多一公里增加5块钱,用户输入公里就可以计算打车价格
  • 如果有拥堵情况,总价格多收取10块钱拥堵费


<script>
        var car = (function () {
            var start = 13;
            var total = 0;
            return {
                price: function (n) {
                    if (n <= 3) {
                        total = start;
                    } else {
                        total = (n - 3) * 5 + start;
                    }
                    return total;
                },
                yongdu: function (flag) {
                    return flag ? total + 10 : total;
                }
            }
        })();
        console.log(car.price(5));
        console.log(car.yongdu(true));
    </script>
复制代码


我们发现上面三个案例中都使用了闭包


2.递归


2.1 什么是递归?


如果一个函数在内部调用其本身,那么这个函数就是递归函数。


简单理解:函数内部自己调用自己,这个函数就是递归函数。


递归函数的作用和循环作用效果一样

由于递归很容易发生栈溢出错误,所以必须加退出条件return


<script>
        var num = 1;
        function fn() {
            console.log('我要打印6句话');
            if (num == 6) {
                return;
            }
            num++;
            fn();
        }
        fn();
    </script>
复制代码


2.2 用递归求数学题


1.求5的阶乘


<script>
        function fn(n) {
            if (n == 1) {
                return 1
            }
            return n * fn(n - 1)
        };
        console.log(fn(5));
    </script>
复制代码


2.求斐波那契数列1、1、2、3、5、8、13、21


用户输入一个数字n就可以求出 这个数字对应的兔子序列值


<script>
        function fib(n) {
            if (n == 1 || n == 2) {
                return 1;
            }
            return fib(n - 1) + fib(n - 2)
        };
        console.log(fib(4));
    </script>
复制代码


2.3 浅拷贝与深拷贝


  • 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用。


  • 深拷贝拷贝多层,每一级别的数据都会拷贝。浅拷贝:


// 浅拷贝的第一种写法
    <script>
        var obj = {
            id: 1,
            name: 'andy'
        };
        var o = {};
        for (var k in obj) {
            // k是属性名 obj[k]是属性值
            o[k] = obj[k]
        }
        console.log(o);
    </script>
    // 浅拷贝的第二种写法
    <script>
            var obj = {
            id: 1,
            name: 'andy'
        };
        var o = {};
        Object.assign(o,obj);
        console.log(o);
    </script>
复制代码


深拷贝:


手写深拷贝函数


<script>
        var obj = {
            id: 1,
            name: 'andy',
            msg: {
                age: 18
            },
            color: ['pink', 'red']
        };
        var o = {};
        // 封装函数
        function deepCopy(newobj, oldobj) {
            for (var k in oldobj) {
                // 判断我们的属性值属于哪种数据类型
                // 1.获取属性值 oldobj[k]
                var item = oldobj[k];
                // 2.判断这个值是否是数组
                if (item instanceof Array) {
                    newobj[k] = [];
                    deepCopy(newobj[k], item)
                } else if (item instanceof Object) {
                    // 3.判断这个值是否是对象
                    newobj[k] = {};
                    deepCopy(newobj[k], item)
                } else {
                    // 4.属于简单数据类型
                    newobj[k] = oldobj[k];
                }
            }
        }
        deepCopy(o, obj)
    </script>
    // 数组放在第一位的原因是数组也属于对象。


相关文章
|
2月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
28天前
|
JavaScript 前端开发
js 闭包的优点和缺点
【10月更文挑战第27天】JavaScript闭包是一把双刃剑,在合理使用的情况下,它可以带来很多好处,如实现数据封装、记忆功能和模块化等;但如果不注意其缺点,如内存泄漏、变量共享和性能开销等问题,可能会导致代码出现难以调试的错误和性能问题。因此,在使用闭包时,需要谨慎权衡其优缺点,根据具体的应用场景合理地运用闭包。
106 58
|
28天前
|
缓存 JavaScript 前端开发
js 闭包
【10月更文挑战第27天】JavaScript闭包是一种强大的特性,它可以用于实现数据隐藏、记忆和缓存等功能,但在使用时也需要注意内存泄漏和变量共享等问题,以确保代码的质量和性能。
36 7
|
1月前
|
自然语言处理 JavaScript 前端开发
JavaScript闭包:解锁编程潜能,释放你的创造力
【10月更文挑战第25天】本文深入探讨了JavaScript中的闭包,包括其基本概念、创建方法和实践应用。闭包允许函数访问其定义时的作用域链,常用于数据封装、函数柯里化和模块化编程。文章还提供了闭包的最佳实践,帮助读者更好地理解和使用这一强大特性。
17 2
|
2月前
|
设计模式 JavaScript 前端开发
探索JavaScript中的闭包:从基础概念到实际应用
在本文中,我们将深入探讨JavaScript中的一个重要概念——闭包。闭包是一种强大的编程工具,它允许函数记住并访问其所在作用域的变量,即使该函数在其作用域之外被调用。通过详细解析闭包的定义、创建方法以及实际应用场景,本文旨在帮助读者不仅理解闭包的理论概念,还能在实际开发中灵活运用这一技巧。
|
2月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理、应用与代码演示
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理、应用与代码演示
|
2月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript闭包:原理与应用
【10月更文挑战第11天】深入理解JavaScript闭包:原理与应用
20 0
|
7月前
|
设计模式 JavaScript 前端开发
js开发:请解释闭包(closure)是什么,以及它的用途。
闭包是JavaScript中的关键特性,允许函数访问并操作外部作用域的变量,常用于实现私有变量、模块化和高阶函数。私有变量示例展示了如何创建无法外部访问的计数器;模块化示例演示了封装私有变量和函数,防止全局污染;高阶函数示例则说明了如何使用闭包创建能接收或返回函数的函数。
60 2
|
7月前
|
自然语言处理 JavaScript 前端开发
JavaScript基础知识:什么是闭包(Closure)?
JavaScript基础知识:什么是闭包(Closure)?
57 0
|
7月前
|
JavaScript 前端开发 Java
学习Javascript闭包(Closure)
学习Javascript闭包(Closure)
47 0