js中闭包及函数柯里化

1,338 阅读4分钟

闭包

什么是闭包

  • 一句话可以概括:闭包就是能够读取其他函数内部变量的函数,或者子函数在外调用,子函数所在的父函数的作用域不会被释放。
function foo(){
  var a = 10;  // foo的活动对象之中;
  return function(){   //匿名函数的活动对象;返回的是这个函数
    console.log(a)
  }
}
var b = foo() 当调用foo时,返回的参数是一个函数
b() 调用b时才是返回真正的结果

我们看下上面的函数foo,内部定义了一个变量a,直接返回一个匿名函数,当调用foo这个函数时,返回的结果是这个函数体,并不会直接打印出变量的结果.当我们把这个函数赋值给一个变量,通过这个变量调用才会返回最终的结果.

其中a是作为这个函数的局部变量,本应该是在这个函数运行完毕以后销毁这个变量的;但是由于返回结果中还在引用的这个变量,所以这个变量会常驻内存中.

内存生命周期

分配内存空间=>使用内存(读写操作)=>释放销毁

js中分配内存空间是自动的,当我们定义一个变量a,var a = 123,javascript自动为我们分配了需要的内存空间,接下来我们可以对这个变量进行引用或者赋值,这个就是内存使用的阶段;当完成这个阶段以后,垃圾回收机制会检测分配的内存是否还有在使用,没有就将其回收.

这里说下我自己对垃圾回收的认知,当我们定义一个全局变量,这个变量会在全局一直存在,即使没有其他函数或者变量引用,直到页面关闭或者或者浏览器退出才会销毁,那么这么做的缺陷就是变量的污染,当我们协同开发时用的时同一个变量名,这样代码会出现各种问题.为此我们可以在函数内定义局部变量,当这个函数体运行完毕后,其他地方已经没有引用这个函数或者调用它,垃圾回收检测到以后会将这个函数运行时开辟的内存空间关闭,其内部的变量也将销毁.而闭包恰恰就是利用这一特性,在函数内返回这个变量的引用,使其不会存在没有变量引用而被垃圾回收.

使用闭包需要注意

闭包会将定义的变量全部保存在内存中,滥用闭包会造成内存占用过多,影响网页性能. 如上面的代码,我们已经使用完成这个变量了,并且在以后的代码也不会再使用这个变量,我们可以将b赋值为null,此时就不再引用函数,垃圾回收将该函数的内存空间回收.

一段代码

  var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      return function(){
        return this.name;
      };

    }

  };

  alert(object.getNameFunc()());
  
  ---------------------------------
    var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };

    }

  };

  alert(object.getNameFunc()());

这是阮一峰老师博客中关于闭包的一段代码,为什么两个结果输出不一样?难道是修改了this指向的原因?那么闭包也是通过this指向来访问到其函数内部的变量吗?那么闭包与函数柯里化有什么关系呢?

柯里化

什么是柯里化

是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

闭包就是函数柯里化的一种实际应用

function add(a,b){
    return a+b
}
add(1,2) // =>3
function add(a){
    return function(b){
        return a+b
    }
}
add(1)(2)  //=>3

上面两段代码同样是求和,下面就是实现的柯里化,但是同样的功能,为什么要用柯里化呢?它有什么好处呢?

柯里化的好处

  1. 参数复用;2. 提前返回;3. 延迟计算/运行.

看了几篇文章也没理解柯里化的这几个好处,先暂时囫囵吞下.

写在最后

这篇是自己学习记录总结下的内容,如果有不对的地方欢迎指正,互相交流.