Skip to content

Latest commit

 

History

History
55 lines (53 loc) · 3.13 KB

闭包与高阶函数.md

File metadata and controls

55 lines (53 loc) · 3.13 KB

闭包

闭包到底是什么呢?我觉得闭包是js独有的特性,需要延长一个变量的生命周期(延长作用域链的方式),使其在在外部也能访问内部的变量或函数,使得内部的变量或函数不会因离开了局部作用域而被销毁。
红宝书: 闭包,是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。

function outFunc(){
  console.log("i am outside");
  return function(){
    return "i am inside";
  }
}

要明白里面的细节,需要了解一下函数是怎么被调用的。

函数是什么被调用的

当某个函数被调用时,会创建一个执行环境及相应的作用域链。然后,使用arguments和其他命名参数的值来初始化函数的活动对象。但在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位,······直至作为作用域链终点的全局执行环境。
在函数的执行过程中,为读取和写入变量的值,就需要在作用域链中查找变量。

// arguments
function compare(value1,value2){
    if(value1 < value2)
        return -1;
}
var result = compare(1,2); // 这里在全局作用域中调用了他,调用compare就会创建一个arguments,value1,value2的活动对象。

全局执行环境的变量对象包含(result和compare)在compare()执行环境的作用域链中则处于第二位。(自己才是第一位,外面的开始是第二位...)
作用域链显然本质上是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。
当函数执行完毕就会销毁自身活动对象,内存中仅保存全局作用域的变量对象。

闭包又是什么情况?

在另一个函数内部定义的函数会将包含函数(即外部函数)的活动对象添加到它的作用域链中。(这里的重点是活动对象,包含外部函数的活动对象)。
举个🌰 在QuicFunc()函数内部定义的匿名函数的作用域链中,实际上将会包含外部函数QuicFunc()的 活动对象 。包含函数与内部匿名函数的作用域链。

var compare = QuicFunc("name");
var result = compare({name:"trans"},{name:"hi"});
function QuicFunc(name){
   return function(Object1,Object2){
     var value = Object1[name];
     ...
   }
}

匿名函数被返回后,它的作用域链被初始化为包含QuicFunc()函数的活动对象和全局变量对象。这样匿名函数就可以访问QuicFunc()中定义的所有变量,QuicFunc()函数在执行完之后,其活动对象也不会被销毁,因为匿名函数的作用域链仍然引用这个活动对象。
匿名函数被销毁,QuicFunc()才会被销毁。

var compareNames = QuicFunc("name"); // 创建
var result = compareNames({},{}); // 调用
compareNames = null;// 销毁

高阶函数

函数可以作为参数被传递
函数可以作为返回值输出

函数作为参数传递

回调函数,不知道请求返回的确切时间 callback