基础内容回顾
1.高阶函数指把函数作为参数的函数,map和reduce就是两个高阶函数
map接受一个方法作为参数,可以对一个数列中的每一个元素拿此方法做处理,像这样
function pow(x){return x+1} [1,2,3,4,5].map(pow) //[2, 3, 4, 5, 6]
reduce接受一个方法作为参数,这个方法必须有两个参数,可以对一个数列中的元素做累计处理,第一个参数为数组处理的累积返回值,第二个参数为新加入处理的数组元素
function pow(x,y){return x+y} [1,2,3,4,5].reduce(pow) 15
但是需要注意的是,map和reduce只需要处理数组的方法,即只需要传reduce(pow),不需要reduce(pow());另外,map和reduce是两个方法,两个api,直接跟在数组后面,如:[1,2,3,4,5].reduce(pow)
2.闭包
闭包指的就是一个函数里面返回了一个函数,或者这个函数返回的值里有未执行的函数,像这样:
function count() { var arr = []; for (var i=1; i<=3; i++) { arr.push(function () { return i * i; }); } return arr; }
count(),执行后返回了arr数组,arr数组中每一个元素都是一个未执行的函数,返回出来是这样的
count() [funciton() {return i * i;},funciton() {return i * i;},funciton() {return i * i;}]
这就是闭包了,返回了未执行的函数或者返回的值里包含未执行的函数,这里要说的是闭包的第一个特性,闭包可以保存外部函数带来的数据:
比如一个函数内含闭包,在闭包外声明var a=1;然后闭包中也用了a,那么外部这个函数执行完后会返回这个闭包,闭包中这个a=1的值仍然保存,单独放在那里也保存着a=1,因为闭包是一个“携带状态的函数,并且它的状态可以完全对外隐藏起来”
比如下面这个例子:
function create_counter(initial) { var x = initial || 0; return { inc: function () { x += 1; return x; } } } var c1 = create_counter(); c1.inc(); // 1 c1.inc(); // 2 c1.inc(); // 3 var c2 = create_counter(10); c2.inc(); // 11 c2.inc(); // 12 c2.inc(); // 13
如以上代码,x的值在闭包中始终存在。
我之前疑惑的一点是在调用c1.inc()时,c1不是等于create_counter()吗?它每c1.inc()一次,先执行c1时难道不会把x再次初始化吗,那闭包中保存的值不是被初始化了
后来想了想,原来c1=create_counter()意思是c1是create_counter这个函数执行后的返回值,它的返回值是什么,是闭包啊,没有那个初始化语句了,所以上面说“先执行c1”是可笑的,因为它只是一个值而已,它只是一个执行过的函数返回的值而已
闭包的第二个特性就是,闭包保存的值(外部的值沿用到内部因未执行保存起来的),保存的是这个值的最后一个状态
什么意思呢
function count() { var arr = []; for (var i=1; i<=3; i++) { arr.push(function () { return i * i; }); } return arr; }
这个最终返回的是[16,16,16],因为i循环完了的时候,返回的闭包还是[funciton() {return i * i;},funciton() {return i * i;},funciton() {return i * i;}]
并没有执行,但是i已经等于4了,所以等它们重见天日的时候,它们内部保存的状态(值)是i=4
待续