JavaScript中闭包的4个有用技巧分享

 更新时间:2023年10月25日 09:28:43   作者:黑土豆  
当谈到JavaScript编程中的高级概念和技巧时,闭包(Closures)是一个重要而有趣的主题,闭包是一种函数与其创建时的词法环境的组合,它允许我们捕获和保留局部变量,并在函数之外使用它们,在这篇文章中,我们将深入探讨JavaScript中闭包的4种有用技巧

前言

当谈到JavaScript编程中的高级概念和技巧时,闭包(Closures)是一个重要而有趣的主题。闭包是一种函数与其创建时的词法环境的组合,它允许我们捕获和保留局部变量,并在函数之外使用它们。在这篇文章中,我们将深入探讨JavaScript中闭包的4种有用技巧,以及如何应用它们来解决各种问题和提高代码质量。

1. 解决循环中的问题

JavaScript中,循环中的变量作用域问题经常会导致预期之外的结果。通常,使用var声明变量会导致循环中的变量共享相同的作用域,因此在异步操作中,这些变量可能会具有意外的值。

问题场景:

for (var i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i); // 输出什么?
    }, 1000 * i);
}

上述代码将在1秒、2秒和3秒后分别打印出3,三次都是相同的值。这是因为setTimeout是异步的,它在循环结束后才执行,此时i的值已经是3

解决方法:

使用闭包来保存每次迭代中的i的值:

for (var i = 0; i < 3; i++) {
    ((n) => {
        setTimeout(() => {
            console.log(n); // 输出0、1、2
        }, 1000 * n);
    })(i);
}

或者,更简单的方式是使用let来声明循环变量,它将在每次迭代中创建一个新的作用域:

for (let i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i); // 输出0、1、2
    }, 1000 * i);
}

2种方法都可以解决循环中的作用域问题。

2. 保存函数状态

闭包还可以用于实现记忆功能,通过缓存计算结果来提高性能。这在需要重复计算的函数中特别有用。

问题场景:

实现一个累加器:

let sum = 1;

function add(num) {
    sum += num;
    return sum;
}

console.log(add(1));
console.log(add(5));

每次调用add时,它都会将上次的值保存下来。但是这段代码有潜在的问题,那就是sum可能会被其他部分代码无意中修改。那如何解决?

解决方法:

使用闭包就可以规避上面存在的问题且可以缓存已经计算的值:

function calculator(val) {
    let sum = val;
    return function(num) {
        sum += num;
        return sum;
    }
}
const add = calculator(1);
console.log(add(1)); //2
console.log(add(5)); //7

每次调用返回的函数时,它都会将传递给它的数字加到总和中,并返回新的总和。

3. 封装私有变量和属性

在过去,为了保护对象的私有变量,常常使用闭包。通过闭包,可以将变量封装在函数内部,只能通过函数暴露的接口来访问和修改。

问题场景:

function add() {
    let count = 0;
    count++;
    console.log(count);
}
add(); //输出1
add(); //输出1
add(); //输出1

调用函数,输出的结果都是1,但是显然我们想要的效果是让count每次加1的。那如何解决呢?

解决方法:

使用闭包来封装私有变量:

function add(){
    let count = 0;
    function a() {
        count++;
        console.log(count);
    }
    return a;
}
var res = add();
res() //1
res() //2
res() //3

add函数返回了一个闭包a,其中包含了count变量。由于count只在add函数内部定义,因此外部无法直接访问它。但是,由于a函数引用了count变量,因此count变量的值可以在闭包内部被修改和访问,这样就可以防止它被恶意修改了。

4. 函数柯里化

函数柯里化是一种将接受多个参数的函数转化为一系列接受一个参数的函数的过程。这也可以通过闭包来实现。

问题场景:

const add = (a, b, c) => {
    return a + b + c;
}

console.log(add(2, 3, 4)); // 输出9

解决方法:

使用闭包来实现函数柯里化:

function curry(callback) {
    const args = [];

    return function curried(...newArgs) {
        args.push(...newArgs);

        if (args.length >= callback.length) {
            return callback(...args);
        } else {
            return curried;
        }
    };
}

function add(a, b, c) {
    return a + b + c;
}

const curriedAdd = curry(add);

console.log(curriedAdd(2)(3)(4)); // 输出 9

函数柯里化使函数更加灵活,能够逐步接受参数,提高代码的可重用性和可读性。

总结

在本文中,我们深入探讨了JavaScript中闭包的4种有用技巧,以及如何应用它们来解决各种问题和提高代码质量。这些技巧包括解决循环中的变量作用域问题,实现记忆功能以提高性能,封装私有变量和属性,以及使用函数柯里化来提高函数的灵活性。

闭包是JavaScript中一个强大的概念,它允许我们在函数之外访问和操作局部变量,从而解决了许多常见的编程问题。虽然闭包在JavaScript中有着广泛的应用,但也需要小心使用,以避免潜在的内存泄漏问题。确保在不再需要闭包时,及时释放对其的引用,以帮助垃圾回收器正常运作。希望本文对你理解JavaScript中的闭包和如何应用它们有所帮助。

以上就是JavaScript中闭包的4个有用技巧分享的详细内容,更多关于JavaScript闭包的有用技巧的资料请关注脚本之家其它相关文章!

相关文章

  • 基于javascript制作微信聊天面板

    基于javascript制作微信聊天面板

    这篇文章主要为大家详细介绍了基于javascript制作微信聊天面板的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • 实现JavaScript中数据响应的方法总结

    实现JavaScript中数据响应的方法总结

    JavaScript 数据响应是一种重要的前端开发概念,是指在应用程序中的数据发生变化时,能够自动更新与这些数据相关的用户界面(UI)部分的能力,本文我们来总结一下目前可以简单实现 JavaScript 中的数据响应的方法,需要的朋友可以参考下
    2023-09-09
  • javascript实现简单下拉菜单效果

    javascript实现简单下拉菜单效果

    这篇文章主要为大家详细介绍了javascript实现简单下拉菜单效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一
    2022-08-08
  • JS根据变量保存方法名并执行方法示例

    JS根据变量保存方法名并执行方法示例

    用eval方法,把传进来的这个方法名所代表的方法当作一个对象来赋值给method1的func属性,需要的朋友可以参考下
    2014-04-04
  • JS中的算法与数据结构之常见排序(Sort)算法详解

    JS中的算法与数据结构之常见排序(Sort)算法详解

    这篇文章主要介绍了JS中的算法与数据结构之常见排序(Sort)算法,结合实例形式详细分析了js常见排序算法中的冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序等算法相关实现技巧与操作注意事项,需要的朋友可以参考下
    2019-08-08
  • js实现手机拍照上传功能

    js实现手机拍照上传功能

    这篇文章主要为大家详细介绍了js实现手机拍照上传功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • js实现产品缩略图效果

    js实现产品缩略图效果

    本文主要介绍了js实现产品缩略图效果的实例。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • 详解使用mocha对webpack打包的项目进行

    详解使用mocha对webpack打包的项目进行"冒烟测试"的大致流程

    这篇文章主要介绍了详解使用mocha对webpack打包的项目进行"冒烟测试"的大致流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • 网易首页的新闻代码

    网易首页的新闻代码

    网易首页的新闻代码...
    2007-01-01
  • js中遍历Map对象的方法

    js中遍历Map对象的方法

    下面小编就为大家带来一篇js中遍历Map对象的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07

最新评论