闭包内存泄漏/函数柯里化curry

发布于:2023-01-24 ⋅ 阅读:(614) ⋅ 点赞:(0)

闭包

1、定义:

嵌套在函数作用域中的函数,称为闭包函数。该作用域称为闭包环境。通过闭包函数可以访问闭包函数所在函数作用域中的形参与变量

2、表现形式:

使函数外部能够调用函数内部定义的变量

3、工作原理:

利用了js中的垃圾回收机制,当一个函数被调用时,开辟空间,函数调用结束,释放空间,垃圾回收机制释放被调用结束的函数时,发现函数的变量正在被其他的函数调用,这些变量不会被释放,而且被永久驻留在内存,只有退出程序,才会被释放,或者是手工释放(=null)

4、变量的作用域

要理解闭包,首先必须理解Javascript特殊的变量作用域。
变量的作用域分类:全局变量和局部变量。
特点:

1、函数内部可以读取函数外部的全局变量;在函数外部无法读取函数内的局部变量。
2、函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

5、使用闭包的注意点

1)滥用闭包,会造成内存泄漏:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除,==null销毁闭包。
2)会改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public
Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

函数柯里化

实现 sum(1)(2)(3) 返回结果是1,2,3之和

1.函数柯里化(curry)是函数式编程里面的概念。是指每次调用函数时,它先接受一部分参数,并返回一个函数,然后再传递剩下的一部分参数,返回一个函数,直到传递所有参数为止 。
2. carry是用来生成 fn 函数成为柯理化函数的工具函数,add1 是让其成为柯理化函数的目标函数(也就是 fn) 根据传入的参数个数
3.(args.length) 是否大于等于原函数所需参数个(fn.length)如果是,则执行当前函数;否则返回一个函数(carry函数)

 // carry是用来生成 fn 函数成为柯理化函数的函数, 
    function carry(fn, ...args) {
      //传入的参数个数 (args.length) 是否大于等于原函数所需参数个数 (fn.length) ,如果是,则执行当前函数;否则返回一个函数
      if (args.length >= fn.length) {
        return fn(...args);
      } else {
        return function (..._args) {
          return carry(fn, ..._args, ...args)
        };
      }
    }

    function add1(x, y, z) {
      return x + y + z;
    }
    let add = carry(add1);

    console.log(add(1, 2, 3));
    console.log(add(1, 2)(3));
    console.log(add(1)(2, 3));

主要有三个作用: 参数复用、提前返回和 延迟执行

比如,我们有一个柯理化函数 add(最多传入3个参数),那么 add(1, 2)(m) 的结果就是 1+2+m,我们只需要这样做:

令 fn_1_2 = add(1, 2) ,之后 fn_1_2(m) 就只需直接传入一个值 m,不需要传入 1和2,达到复用 1和2 这两个参数了
let fn_1_2 = add(1)(2);
console.log(fn_1_2(3)) // 6
console.log(fn_1_2(4)) // 7
就是参数复用,而 提前返回 和 延迟执行 也很好理解,因为每次调用函数时,它只接受一部分参数,并返回一个函数(提前返回),直到(延迟执行)传递所有参数为止。

本文含有隐藏内容,请 开通VIP 后查看