javascript 闭包学习笔记
一些情况下,函数返回 计算结果就行了 比如:
function addAll(arr){
return arr.reduce(function(x,y){
return x+y;
});
}
var arr = [1,3,4,5,6,7,8];
console.log(addAll(arr));
函数作为返回值
function lazy_sum(arr){
return function(){ // 参数和局部变量都保存在 返回的函数内部
return arr.reduce(function(x,y){return x+y;});
}
}
var f = lazy_sum(arr); //这个函数得到的不是计算结果,而是算法/函数
console.log(f); // [Function]
console.log(f()); 34
这在 某些时候特别有用
返回函数不要引用任何循环变量
function count(){
var arr = [];
for(var i=1;i<=3;i++){
arr.push(function(){
return i*i; //等到返回的时候i已经变成了4
});
}
return arr;
}
var results = count();
results.forEach(function(f){
console.log(f()); ///16 16 16
});
var 改 let
function count(){
var arr = [];
for(let i=1;i<=3;i++){ // 如果var 改为let, i变成了块变量,i的作用域仅在for块了
arr.push(function(){
return i*i; // 每一次循环里的i都是独立的
});
}
return arr;
}
var results = count();
results.forEach(function(f){
console.log(f()); ///1 4 9
});
创建一个匿名函数并立刻执行
function count(){
var arr= [];
for(var i=1;i<=3;i++){
arr.push((function(n){
return function(){
return n*n;
};
})(i));
}
return arr;
}
拆开写看清楚些
function count(){
var arr = [];
function f(n){
return function(){return n*n;}; // f(n)一执行则 n固定下来
}
for(var i=1;i<=3;i++){
arr.push(f(i)); //不再是push进函数的定义,而是f(i)的执行结果
}
return arr;
}
var res = count();
res.forEach(function(f){
console.log(f()); //1 4 9
});
js中 创建一个匿名函数并立刻执行的写法
理论上应该是
f(n){
return n*n
}(3);
但是由于JavaScript语法解析的问题,会报SyntaxError错误,因此需要用括号把整个函数定义括起来:
(f(n){
return n*n
})(3);
借助闭包,封装一个私有变量
function create_counter(initNum){
var x = initNum||0;
return {
//该闭包携带了局部变量x,并且,从外部代码根本无法访问到变量x
inc:function(){
x+=1;
return x;
}
}
}
var c = create_counter();
console.log(c.inc());
console.log(c.inc());
console.log(c.inc());
console.log(c.inc());
闭包携带了局部变量x,并且,从外部代码根本无法访问到变量x。换句话说,闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。
小栗子
function addNum(n){
return function(x){
return x+n;
};
}
var add2 = addNum(2);
var add10 = addNum(10);
console.log(add2(1));
console.log(add10(1));